From: Shane Lontis Date: Thu, 3 Jun 2021 09:09:38 +0000 (+1000) Subject: Add a gettable for provider ciphers to return the EVP_CIPH_RAND_KEY flag X-Git-Tag: openssl-3.0.0-beta1~173 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=f41fd10d90fb5202f4c05f8842b4a4f25afd51d0;hp=5135a9bd9280301a24640a6bf5125c144e28cfdd 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 Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/15606) --- 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) + +Gets 1 if the cipher algorithm I supports the gettable EVP_CIPHER_CTX +parameter B. 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 "cts". See L "tls-multi". +=item EVP_CIPH_RAND_KEY + +See L "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; @@ -716,6 +743,9 @@ int setup_tests(void) ADD_TEST(kem_rsa_params); #ifndef OPENSSL_NO_DH ADD_TEST(kem_invalid_keytype); +#endif +#ifndef OPENSSL_NO_DES + ADD_TEST(test_cipher_tdes_randkey); #endif return 1; }