diff options
-rw-r--r-- | crypto/evp/m_sigver.c | 38 | ||||
-rw-r--r-- | providers/implementations/signature/mac_legacy_sig.c | 13 | ||||
-rw-r--r-- | test/evp_extra_test.c | 7 |
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: |