From 3c957bcd54d097167e53660fa100aa1ba85d63b5 Mon Sep 17 00:00:00 2001 From: Shane Lontis Date: Mon, 18 Nov 2019 10:32:36 +1000 Subject: [PATCH] Cache constants for fetched EVP_cipher Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale Reviewed-by: Patrick Steuer (Merged from https://github.com/openssl/openssl/pull/10461) --- crypto/evp/evp_enc.c | 4 +++ crypto/evp/evp_lib.c | 74 ++++++++++++++++++------------------------ crypto/evp/evp_local.h | 1 + 3 files changed, 37 insertions(+), 42 deletions(-) diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index da6dde0c4d..96eb350623 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -1524,6 +1524,10 @@ EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, evp_cipher_from_dispatch, evp_cipher_up_ref, evp_cipher_free); + if (cipher != NULL && !evp_cipher_cache_constants(cipher)) { + EVP_CIPHER_free(cipher); + cipher = NULL; + } return cipher; } diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index c25c40ddb0..3c2083148e 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -272,16 +272,38 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx) } } -int EVP_CIPHER_block_size(const EVP_CIPHER *cipher) +int evp_cipher_cache_constants(EVP_CIPHER *cipher) { int ok; - size_t v = cipher->block_size; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &v); + size_t ivlen = 0; + size_t blksz = 0; + size_t keylen = 0; + unsigned int mode = 0; + unsigned long flags = 0; + OSSL_PARAM params[6]; + + 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); + params[2] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &keylen); + params[3] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_MODE, &mode); + params[4] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &flags); + params[5] = OSSL_PARAM_construct_end(); ok = evp_do_ciph_getparams(cipher, params); + if (ok) { + /* Provided implementations may have a custom cipher_cipher */ + if (cipher->prov != NULL && cipher->ccipher != NULL) + flags |= EVP_CIPH_FLAG_CUSTOM_CIPHER; + cipher->block_size = blksz; + cipher->iv_len = ivlen; + cipher->key_len = keylen; + cipher->flags = flags | mode; + } + return ok; +} - return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher) +{ + return cipher->block_size; } int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) @@ -340,18 +362,7 @@ int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) { - int ok; - unsigned long v = cipher->flags; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &v); - ok = evp_do_ciph_getparams(cipher, params); - - /* Provided implementations may have a custom cipher_cipher */ - if (cipher->prov != NULL && cipher->ccipher != NULL) - v |= EVP_CIPH_FLAG_CUSTOM_CIPHER; - - return ok != 0 ? v : 0; + return cipher->flags; } void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) @@ -381,14 +392,7 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data) int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { - int ok; - size_t v = cipher->iv_len; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &v); - ok = evp_do_ciph_getparams(cipher, params); - - return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; + return cipher->iv_len; } int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) @@ -501,14 +505,7 @@ int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num) int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { - int ok; - size_t v = cipher->key_len; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &v); - ok = evp_do_ciph_getparams(cipher, params); - - return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED; + return cipher->key_len; } int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) @@ -576,14 +573,7 @@ const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher) int EVP_CIPHER_mode(const EVP_CIPHER *cipher) { - int ok; - unsigned int v = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_MODE, &v); - ok = evp_do_ciph_getparams(cipher, params); - - return ok != 0 ? (int)v : 0; + return EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE; } int EVP_MD_is_a(const EVP_MD *md, const char *name) diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index e229cf2971..71e1258326 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -273,3 +273,4 @@ int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name); void evp_names_do_all(OSSL_PROVIDER *prov, int number, void (*fn)(const char *name, void *data), void *data); +int evp_cipher_cache_constants(EVP_CIPHER *cipher); -- 2.25.1