summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2021-06-03 19:09:38 +1000
committerPauli <pauli@openssl.org>2021-06-08 15:16:06 +1000
commitf41fd10d90fb5202f4c05f8842b4a4f25afd51d0 (patch)
tree09106bd79af443731ff67bee224ec5609d632c7a
parent5135a9bd9280301a24640a6bf5125c144e28cfdd (diff)
Add a gettable for provider ciphers to return the EVP_CIPH_RAND_KEY flag
Fixes #15531 DES and TDES set this flag which could possibly be used by applications. The gettable cipher param OSSL_CIPHER_PARAM_HAS_RAND_KEY has been added. Note that EVP_CIPHER_CTX_rand_key() uses this flag. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15606)
-rw-r--r--crypto/evp/evp_lib.c10
-rw-r--r--doc/man3/EVP_EncryptInit.pod12
-rw-r--r--include/openssl/core_names.h1
-rw-r--r--providers/implementations/ciphers/cipher_des.c2
-rw-r--r--providers/implementations/ciphers/cipher_tdes.h2
-rw-r--r--providers/implementations/ciphers/cipher_tdes_wrap.c2
-rw-r--r--providers/implementations/ciphers/ciphercommon.c7
-rw-r--r--providers/implementations/include/prov/ciphercommon.h5
-rw-r--r--test/evp_libctx_test.c30
9 files changed, 61 insertions, 10 deletions
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index bb91b22678..0b08c9adfd 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -340,12 +340,12 @@ int EVP_CIPHER_get_type(const EVP_CIPHER *cipher)
int evp_cipher_cache_constants(EVP_CIPHER *cipher)
{
- int ok, aead = 0, custom_iv = 0, cts = 0, multiblock = 0;
+ int ok, aead = 0, custom_iv = 0, cts = 0, multiblock = 0, randkey = 0;
size_t ivlen = 0;
size_t blksz = 0;
size_t keylen = 0;
unsigned int mode = 0;
- OSSL_PARAM params[9];
+ OSSL_PARAM params[10];
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &blksz);
params[1] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &ivlen);
@@ -357,7 +357,9 @@ int evp_cipher_cache_constants(EVP_CIPHER *cipher)
params[6] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_CTS, &cts);
params[7] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK,
&multiblock);
- params[8] = OSSL_PARAM_construct_end();
+ params[8] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY,
+ &randkey);
+ params[9] = OSSL_PARAM_construct_end();
ok = evp_do_ciph_getparams(cipher, params) > 0;
if (ok) {
cipher->block_size = blksz;
@@ -374,6 +376,8 @@ int evp_cipher_cache_constants(EVP_CIPHER *cipher)
cipher->flags |= EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK;
if (cipher->ccipher != NULL)
cipher->flags |= EVP_CIPH_FLAG_CUSTOM_CIPHER;
+ if (randkey)
+ cipher->flags |= EVP_CIPH_RAND_KEY;
if (OSSL_PARAM_locate_const(EVP_CIPHER_gettable_ctx_params(cipher),
OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS))
cipher->flags |= EVP_CIPH_FLAG_CUSTOM_ASN1;
diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod
index 965e0d9248..4b90cdd780 100644
--- a/doc/man3/EVP_EncryptInit.pod
+++ b/doc/man3/EVP_EncryptInit.pod
@@ -679,6 +679,12 @@ TLS ciphers.
Use (EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) to retrieve the
cached value.
+=item "has-randkey" (B<OSSL_CIPHER_PARAM_HAS_RANDKEY>) <integer>
+
+Gets 1 if the cipher algorithm I<cipher> supports the gettable EVP_CIPHER_CTX
+parameter B<OSSL_CIPHER_PARAM_RANDOM_KEY>. Only DES and 3DES set this to 1,
+all other OpenSSL ciphers return 0.
+
=back
=head2 Gettable and Settable EVP_CIPHER_CTX parameters
@@ -1115,6 +1121,10 @@ See L</Gettable EVP_CIPHER parameters> "cts".
See L</Gettable EVP_CIPHER parameters> "tls-multi".
+=item EVP_CIPH_RAND_KEY
+
+See L</Gettable EVP_CIPHER parameters> "has-randkey".
+
=back
EVP_CIPHER_flags() uses the following flags for legacy purposes only:
@@ -1131,8 +1141,6 @@ EVP_CIPHER_flags() uses the following flags for legacy purposes only:
=item EVP_CIPH_CUSTOM_KEY_LENGTH
-=item EVP_CIPH_RAND_KEY
-
=item EVP_CIPH_CUSTOM_COPY
=item EVP_CIPH_FLAG_DEFAULT_ASN1
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 097dbc1c04..f99497e229 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -75,6 +75,7 @@ extern "C" {
#define OSSL_CIPHER_PARAM_CUSTOM_IV "custom-iv" /* int, 0 or 1 */
#define OSSL_CIPHER_PARAM_CTS "cts" /* int, 0 or 1 */
#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK "tls-multi" /* int, 0 or 1 */
+#define OSSL_CIPHER_PARAM_HAS_RAND_KEY "has-randkey" /* int, 0 or 1 */
#define OSSL_CIPHER_PARAM_KEYLEN "keylen" /* size_t */
#define OSSL_CIPHER_PARAM_IVLEN "ivlen" /* size_t */
#define OSSL_CIPHER_PARAM_IV "iv" /* octet_string OR octet_ptr */
diff --git a/providers/implementations/ciphers/cipher_des.c b/providers/implementations/ciphers/cipher_des.c
index d03d65b668..c6d13466f7 100644
--- a/providers/implementations/ciphers/cipher_des.c
+++ b/providers/implementations/ciphers/cipher_des.c
@@ -20,7 +20,7 @@
#include "prov/implementations.h"
#include "prov/providercommon.h"
-#define DES_FLAGS 0
+#define DES_FLAGS PROV_CIPHER_FLAG_RAND_KEY
static OSSL_FUNC_cipher_freectx_fn des_freectx;
static OSSL_FUNC_cipher_encrypt_init_fn des_einit;
diff --git a/providers/implementations/ciphers/cipher_tdes.h b/providers/implementations/ciphers/cipher_tdes.h
index d3d885bd18..93f9d1744d 100644
--- a/providers/implementations/ciphers/cipher_tdes.h
+++ b/providers/implementations/ciphers/cipher_tdes.h
@@ -13,7 +13,7 @@
#define DES_BLOCK_SIZE 8
#define TDES_IVLEN 8
-#define TDES_FLAGS 0
+#define TDES_FLAGS PROV_CIPHER_FLAG_RAND_KEY
typedef struct prov_tdes_ctx_st {
PROV_CIPHER_CTX base; /* Must be first */
diff --git a/providers/implementations/ciphers/cipher_tdes_wrap.c b/providers/implementations/ciphers/cipher_tdes_wrap.c
index f6a859539e..1b4539a64c 100644
--- a/providers/implementations/ciphers/cipher_tdes_wrap.c
+++ b/providers/implementations/ciphers/cipher_tdes_wrap.c
@@ -22,7 +22,7 @@
#include "prov/implementations.h"
#include "prov/providercommon.h"
-#define TDES_WRAP_FLAGS PROV_CIPHER_FLAG_CUSTOM_IV
+#define TDES_WRAP_FLAGS PROV_CIPHER_FLAG_CUSTOM_IV | PROV_CIPHER_FLAG_RAND_KEY
static OSSL_FUNC_cipher_update_fn tdes_wrap_update;
static OSSL_FUNC_cipher_cipher_fn tdes_wrap_cipher;
diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c
index b5a0d43b78..fa383165d8 100644
--- a/providers/implementations/ciphers/ciphercommon.c
+++ b/providers/implementations/ciphers/ciphercommon.c
@@ -30,6 +30,7 @@ static const OSSL_PARAM cipher_known_gettable_params[] = {
OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL),
OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL),
OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL),
+ OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL),
OSSL_PARAM_END
};
const OSSL_PARAM *ossl_cipher_generic_gettable_params(ossl_unused void *provctx)
@@ -72,6 +73,12 @@ int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
+ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY);
+ if (p != NULL
+ && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+ return 0;
+ }
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
diff --git a/providers/implementations/include/prov/ciphercommon.h b/providers/implementations/include/prov/ciphercommon.h
index 7ccc9c7047..91c4c914be 100644
--- a/providers/implementations/include/prov/ciphercommon.h
+++ b/providers/implementations/include/prov/ciphercommon.h
@@ -36,9 +36,10 @@ typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out,
#define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002
#define PROV_CIPHER_FLAG_CTS 0x0004
#define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008
+#define PROV_CIPHER_FLAG_RAND_KEY 0x0010
/* Internal flags that are only used within the provider */
-#define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0010
-#define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0020
+#define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100
+#define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200
struct prov_cipher_ctx_st {
block128_f block;
diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c
index b9794b6b7d..bfbbafdbab 100644
--- a/test/evp_libctx_test.c
+++ b/test/evp_libctx_test.c
@@ -557,6 +557,33 @@ static int kem_rsa_gen_recover(void)
return ret;
}
+#ifndef OPENSSL_NO_DES
+/*
+ * This test makes sure that EVP_CIPHER_CTX_rand_key() works correctly
+ * For fips mode this code would produce an error if the flag is not set.
+ */
+static int test_cipher_tdes_randkey(void)
+{
+ int ret;
+ EVP_CIPHER_CTX *ctx = NULL;
+ EVP_CIPHER *tdes_cipher = NULL, *aes_cipher = NULL;
+ unsigned char key[24] = { 0 };
+
+ ret = TEST_ptr(aes_cipher = EVP_CIPHER_fetch(libctx, "AES-256-CBC", NULL))
+ && TEST_int_eq(EVP_CIPHER_get_flags(aes_cipher) & EVP_CIPH_RAND_KEY, 0)
+ && TEST_ptr(tdes_cipher = EVP_CIPHER_fetch(libctx, "DES-EDE3-CBC", NULL))
+ && TEST_int_ne(EVP_CIPHER_get_flags(tdes_cipher) & EVP_CIPH_RAND_KEY, 0)
+ && TEST_ptr(ctx = EVP_CIPHER_CTX_new())
+ && TEST_true(EVP_CipherInit_ex(ctx, tdes_cipher, NULL, NULL, NULL, 1))
+ && TEST_true(EVP_CIPHER_CTX_rand_key(ctx, key));
+
+ EVP_CIPHER_CTX_free(ctx);
+ EVP_CIPHER_free(tdes_cipher);
+ EVP_CIPHER_free(aes_cipher);
+ return ret;
+}
+#endif /* OPENSSL_NO_DES */
+
static int kem_rsa_params(void)
{
int ret = 0;
@@ -717,6 +744,9 @@ int setup_tests(void)
#ifndef OPENSSL_NO_DH
ADD_TEST(kem_invalid_keytype);
#endif
+#ifndef OPENSSL_NO_DES
+ ADD_TEST(test_cipher_tdes_randkey);
+#endif
return 1;
}