summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-12-22 11:36:30 +0000
committerDmitry Belyavskiy <beldmit@gmail.com>2020-12-23 21:12:18 +0100
commit38f7931429859a3bd07725dbc451c0b4cac26a10 (patch)
tree91e461bb329371007d84763525632235a7bd4d06 /crypto
parentae69da05a7749e21c7526831173405e3570917b2 (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.c29
-rw-r--r--crypto/evp/evp_lib.c33
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)