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/evp/digest.c | |
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/evp/digest.c')
-rw-r--r-- | crypto/evp/digest.c | 29 |
1 files changed, 29 insertions, 0 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; } |