summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/evp/m_sigver.c38
-rw-r--r--providers/implementations/signature/mac_legacy_sig.c13
-rw-r--r--test/evp_extra_test.c7
3 files changed, 43 insertions, 15 deletions
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 80570973dd..9188edbc21 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -49,7 +49,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const char *supported_sig = NULL;
char locmdname[80] = ""; /* 80 chars should be enough */
void *provkey = NULL;
- int ret, iter;
+ int ret, iter, reinit = 1;
if (ctx->algctx != NULL) {
if (!ossl_assert(ctx->digest != NULL)) {
@@ -62,6 +62,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
if (ctx->pctx == NULL) {
+ reinit = 0;
if (e == NULL)
ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props);
else
@@ -71,22 +72,37 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
return 0;
locpctx = ctx->pctx;
- evp_pkey_ctx_free_old_ops(locpctx);
-
- if (props == NULL)
- props = locpctx->propquery;
-
ERR_set_mark();
if (evp_pkey_ctx_is_legacy(locpctx))
goto legacy;
+ /* do not reinitialize if pkey is set or operation is different */
+ if (reinit
+ && (pkey != NULL
+ || locpctx->operation != (ver ? EVP_PKEY_OP_VERIFYCTX
+ : EVP_PKEY_OP_SIGNCTX)
+ || (signature = locpctx->op.sig.signature) == NULL
+ || locpctx->op.sig.algctx == NULL))
+ reinit = 0;
+
+ if (props == NULL)
+ props = locpctx->propquery;
+
if (locpctx->pkey == NULL) {
ERR_clear_last_mark();
ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
goto err;
}
+ if (!reinit) {
+ evp_pkey_ctx_free_old_ops(locpctx);
+ } else {
+ if (mdname == NULL && type == NULL)
+ mdname = canon_mdname(EVP_MD_get0_name(ctx->reqdigest));
+ goto reinitialize;
+ }
+
/*
* Try to derive the supported signature from |locpctx->keymgmt|.
*/
@@ -183,9 +199,6 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
/* No more legacy from here down to legacy: */
- if (pctx != NULL)
- *pctx = locpctx;
-
locpctx->op.sig.signature = signature;
locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX
: EVP_PKEY_OP_SIGNCTX;
@@ -195,12 +208,17 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
}
+
+ reinitialize:
+ if (pctx != NULL)
+ *pctx = locpctx;
+
if (type != NULL) {
ctx->reqdigest = type;
if (mdname == NULL)
mdname = canon_mdname(EVP_MD_get0_name(type));
} else {
- if (mdname == NULL) {
+ if (mdname == NULL && !reinit) {
if (evp_keymgmt_util_get_deflt_digest_name(tmp_keymgmt, provkey,
locmdname,
sizeof(locmdname)) > 0) {
diff --git a/providers/implementations/signature/mac_legacy_sig.c b/providers/implementations/signature/mac_legacy_sig.c
index 06f79505ff..0866e68d9b 100644
--- a/providers/implementations/signature/mac_legacy_sig.c
+++ b/providers/implementations/signature/mac_legacy_sig.c
@@ -101,13 +101,16 @@ static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey,
const char *ciphername = NULL, *engine = NULL;
if (!ossl_prov_is_running()
- || pmacctx == NULL
- || vkey == NULL
- || !ossl_mac_key_up_ref(vkey))
+ || pmacctx == NULL
+ || (pmacctx->key == NULL && vkey == NULL))
return 0;
- ossl_mac_key_free(pmacctx->key);
- pmacctx->key = vkey;
+ if (vkey != NULL) {
+ if (!ossl_mac_key_up_ref(vkey))
+ return 0;
+ ossl_mac_key_free(pmacctx->key);
+ pmacctx->key = vkey;
+ }
if (pmacctx->key->cipher.cipher != NULL)
ciphername = (char *)EVP_CIPHER_get0_name(pmacctx->key->cipher.cipher);
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 22cc3b3d03..9433bb9098 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -1316,6 +1316,13 @@ static int test_EVP_DigestVerifyInit(void)
|| !TEST_true(EVP_DigestVerifyFinal(md_ctx, kSignature,
sizeof(kSignature))))
goto out;
+
+ /* test with reinitialization */
+ if (!TEST_true(EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, NULL))
+ || !TEST_true(EVP_DigestVerifyUpdate(md_ctx, kMsg, sizeof(kMsg)))
+ || !TEST_true(EVP_DigestVerifyFinal(md_ctx, kSignature,
+ sizeof(kSignature))))
+ goto out;
ret = 1;
out: