135 lines
4.6 KiB
Diff
135 lines
4.6 KiB
Diff
|
|
From 708bf3dde8f53446cccded5dadafb853e7e9d38b Mon Sep 17 00:00:00 2001
|
||
|
|
From: Tomas Mraz <tomas@openssl.org>
|
||
|
|
Date: Wed, 13 Apr 2022 16:26:18 +0200
|
||
|
|
Subject: [PATCH] evp_md_init_internal: Avoid reallocating algctx if digest
|
||
|
|
unchanged
|
||
|
|
|
||
|
|
Fixes #16947
|
||
|
|
|
||
|
|
Also refactor out algctx freeing into a separate function.
|
||
|
|
|
||
|
|
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
|
||
|
|
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
|
||
|
|
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||
|
|
(Merged from https://github.com/openssl/openssl/pull/18105)
|
||
|
|
|
||
|
|
(cherry picked from commit fe5c5cb85197aec7d68ab095b866ed22076850d0)
|
||
|
|
---
|
||
|
|
crypto/evp/digest.c | 35 ++++++++++++++++++++---------------
|
||
|
|
crypto/evp/m_sigver.c | 11 ++---------
|
||
|
|
include/crypto/evp.h | 2 ++
|
||
|
|
3 files changed, 24 insertions(+), 24 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
|
||
|
|
index b93e079b15..7a8e15241f 100644
|
||
|
|
--- a/crypto/evp/digest.c
|
||
|
|
+++ b/crypto/evp/digest.c
|
||
|
|
@@ -141,6 +141,20 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
||
|
|
OPENSSL_free(ctx);
|
||
|
|
}
|
||
|
|
|
||
|
|
+int evp_md_ctx_free_algctx(EVP_MD_CTX *ctx)
|
||
|
|
+{
|
||
|
|
+ if (ctx->algctx != NULL) {
|
||
|
|
+ if (!ossl_assert(ctx->digest != NULL)) {
|
||
|
|
+ ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||
|
|
+ return 0;
|
||
|
|
+ }
|
||
|
|
+ if (ctx->digest->freectx != NULL)
|
||
|
|
+ ctx->digest->freectx(ctx->algctx);
|
||
|
|
+ ctx->algctx = NULL;
|
||
|
|
+ }
|
||
|
|
+ return 1;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
|
||
|
|
const OSSL_PARAM params[], ENGINE *impl)
|
||
|
|
{
|
||
|
|
@@ -169,16 +183,6 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
|
||
|
|
|
||
|
|
EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
||
|
|
|
||
|
|
- if (ctx->algctx != NULL) {
|
||
|
|
- if (!ossl_assert(ctx->digest != NULL)) {
|
||
|
|
- ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||
|
|
- return 0;
|
||
|
|
- }
|
||
|
|
- if (ctx->digest->freectx != NULL)
|
||
|
|
- ctx->digest->freectx(ctx->algctx);
|
||
|
|
- ctx->algctx = NULL;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
if (type != NULL) {
|
||
|
|
ctx->reqdigest = type;
|
||
|
|
} else {
|
||
|
|
@@ -229,6 +233,10 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
|
||
|
|
|| (type != NULL && type->origin == EVP_ORIG_METH)
|
||
|
|
|| (type == NULL && ctx->digest != NULL
|
||
|
|
&& ctx->digest->origin == EVP_ORIG_METH)) {
|
||
|
|
+ /* If we were using provided hash before, cleanup algctx */
|
||
|
|
+ if (!evp_md_ctx_free_algctx(ctx))
|
||
|
|
+ return 0;
|
||
|
|
+
|
||
|
|
if (ctx->digest == ctx->fetched_digest)
|
||
|
|
ctx->digest = NULL;
|
||
|
|
EVP_MD_free(ctx->fetched_digest);
|
||
|
|
@@ -239,6 +247,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
|
||
|
|
cleanup_old_md_data(ctx, 1);
|
||
|
|
|
||
|
|
/* Start of non-legacy code below */
|
||
|
|
+ if (ctx->digest != type && !evp_md_ctx_free_algctx(ctx))
|
||
|
|
+ return 0;
|
||
|
|
|
||
|
|
if (type->prov == NULL) {
|
||
|
|
#ifdef FIPS_MODULE
|
||
|
|
@@ -261,11 +271,6 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (ctx->algctx != NULL && ctx->digest != NULL && ctx->digest != type) {
|
||
|
|
- if (ctx->digest->freectx != NULL)
|
||
|
|
- ctx->digest->freectx(ctx->algctx);
|
||
|
|
- ctx->algctx = NULL;
|
||
|
|
- }
|
||
|
|
if (type->prov != NULL && ctx->fetched_digest != type) {
|
||
|
|
if (!EVP_MD_up_ref((EVP_MD *)type)) {
|
||
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||
|
|
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
|
||
|
|
index fc087d2cb6..630d339c35 100644
|
||
|
|
--- a/crypto/evp/m_sigver.c
|
||
|
|
+++ b/crypto/evp/m_sigver.c
|
||
|
|
@@ -51,15 +51,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||
|
|
void *provkey = NULL;
|
||
|
|
int ret, iter, reinit = 1;
|
||
|
|
|
||
|
|
- if (ctx->algctx != NULL) {
|
||
|
|
- if (!ossl_assert(ctx->digest != NULL)) {
|
||
|
|
- ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||
|
|
- return 0;
|
||
|
|
- }
|
||
|
|
- if (ctx->digest->freectx != NULL)
|
||
|
|
- ctx->digest->freectx(ctx->algctx);
|
||
|
|
- ctx->algctx = NULL;
|
||
|
|
- }
|
||
|
|
+ if (!evp_md_ctx_free_algctx(ctx))
|
||
|
|
+ return 0;
|
||
|
|
|
||
|
|
if (ctx->pctx == NULL) {
|
||
|
|
reinit = 0;
|
||
|
|
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
|
||
|
|
index e70d8e9e84..dbbdcccbda 100644
|
||
|
|
--- a/include/crypto/evp.h
|
||
|
|
+++ b/include/crypto/evp.h
|
||
|
|
@@ -909,6 +909,8 @@ int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq,
|
||
|
|
char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig);
|
||
|
|
|
||
|
|
void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force, int keep_digest);
|
||
|
|
+/* just free the algctx if set, returns 0 on inconsistent state of ctx */
|
||
|
|
+int evp_md_ctx_free_algctx(EVP_MD_CTX *ctx);
|
||
|
|
|
||
|
|
/* Three possible states: */
|
||
|
|
# define EVP_PKEY_STATE_UNKNOWN 0
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|