diff options
author | Matt Caswell <matt@openssl.org> | 2020-12-22 11:36:30 +0000 |
---|---|---|
committer | Dmitry Belyavskiy <beldmit@gmail.com> | 2020-12-23 21:12:18 +0100 |
commit | 38f7931429859a3bd07725dbc451c0b4cac26a10 (patch) | |
tree | 91e461bb329371007d84763525632235a7bd4d06 /crypto | |
parent | ae69da05a7749e21c7526831173405e3570917b2 (diff) |
Cache Digest constants
EVP_CIPHER already caches certain constants so that we don't have to
query the provider every time. We do the same thing with EVP_MD constants.
Without this we can get performance issues, e.g. running "speed" with
small blocks of data to digest can spend a long time in EVP_MD_size(),
which should be quick.
Partialy fixes #13578
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/13730)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/evp/digest.c | 29 | ||||
-rw-r--r-- | crypto/evp/evp_lib.c | 33 |
2 files changed, 32 insertions, 30 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 1d16c52060..46f4d201d9 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -827,6 +827,29 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid) } #endif +static int evp_md_cache_constants(EVP_MD *md) +{ + int ok; + size_t blksz = 0; + size_t mdsize = 0; + unsigned long flags = 0; + OSSL_PARAM params[4]; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &blksz); + params[1] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &mdsize); + params[2] = OSSL_PARAM_construct_ulong(OSSL_DIGEST_PARAM_FLAGS, &flags); + params[3] = OSSL_PARAM_construct_end(); + ok = evp_do_md_getparams(md, params); + if (mdsize > INT_MAX || blksz > INT_MAX) + ok = 0; + if (ok) { + md->block_size = (int)blksz; + md->md_size = (int)mdsize; + md->flags = flags; + } + return ok; +} + static void *evp_md_from_dispatch(int name_id, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov) @@ -938,6 +961,12 @@ static void *evp_md_from_dispatch(int name_id, if (prov != NULL) ossl_provider_up_ref(prov); + if (!evp_md_cache_constants(md)) { + EVP_MD_free(md); + ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED); + md = NULL; + } + return md; } diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 48fa330ac3..954acaae0d 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -688,19 +688,7 @@ const OSSL_PROVIDER *EVP_MD_provider(const EVP_MD *md) int EVP_MD_block_size(const EVP_MD *md) { - int ok; - size_t v; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - if (md == NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL); - return -1; - } - v = md->block_size; - params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &v); - ok = evp_do_md_getparams(md, params); - - return ok != 0 ? (int)v : -1; + return md->block_size; } int EVP_MD_type(const EVP_MD *md) @@ -715,31 +703,16 @@ int EVP_MD_pkey_type(const EVP_MD *md) int EVP_MD_size(const EVP_MD *md) { - int ok; - size_t v; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - if (md == NULL) { ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL); return -1; } - v = md->md_size; - params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &v); - ok = evp_do_md_getparams(md, params); - - return ok != 0 ? (int)v : -1; + return md->md_size; } unsigned long EVP_MD_flags(const EVP_MD *md) { - int ok; - unsigned long v = md->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_md_getparams(md, params); - - return ok != 0 ? v : 0; + return md->flags; } EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type) |