From 0fc00fc0e3867fc5f95fab1046ad7d2a85db06f8 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 23 Feb 2023 19:51:27 -0500 Subject: Do not fail if ctx dup does not succeed If the ctx was *really* needed we'll probably fail later with an error anyway, so no point in failing immediately. Document that this behavior is dependent on the provider used to implement the signature/verification. Signed-off-by: Simo Sorce Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/20375) --- crypto/evp/m_sigver.c | 37 +++++++++++++++++-------------------- crypto/evp/p_sign.c | 2 ++ crypto/evp/p_verify.c | 2 ++ 3 files changed, 21 insertions(+), 20 deletions(-) (limited to 'crypto/evp') diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 630d339c35..68ae957058 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -462,7 +462,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) { int sctx = 0, r = 0; - EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; + EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx; if (pctx == NULL || pctx->operation != EVP_PKEY_OP_SIGNCTX @@ -470,17 +470,15 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, || pctx->op.sig.signature == NULL) goto legacy; - if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) - return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx, - sigret, siglen, - sigret == NULL ? 0 : *siglen); - dctx = EVP_PKEY_CTX_dup(pctx); - if (dctx == NULL) - return 0; - - r = dctx->op.sig.signature->digest_sign_final(dctx->op.sig.algctx, + if (sigret != NULL && (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) { + /* try dup */ + dctx = EVP_PKEY_CTX_dup(pctx); + if (dctx != NULL) + pctx = dctx; + } + r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen, - *siglen); + sigret == NULL ? 0 : *siglen); EVP_PKEY_CTX_free(dctx); return r; @@ -589,7 +587,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, int r = 0; unsigned int mdlen = 0; int vctx = 0; - EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; + EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx; if (pctx == NULL || pctx->operation != EVP_PKEY_OP_VERIFYCTX @@ -597,14 +595,13 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, || pctx->op.sig.signature == NULL) goto legacy; - if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) - return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx, - sig, siglen); - dctx = EVP_PKEY_CTX_dup(pctx); - if (dctx == NULL) - return 0; - - r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx, + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) { + /* try dup */ + dctx = EVP_PKEY_CTX_dup(pctx); + if (dctx != NULL) + pctx = dctx; + } + r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen); EVP_PKEY_CTX_free(dctx); return r; diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c index 4eb34db267..ae0de57202 100644 --- a/crypto/evp/p_sign.c +++ b/crypto/evp/p_sign.c @@ -39,6 +39,8 @@ int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *sigret, rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); if (rv) rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len); + else + rv = EVP_DigestFinal_ex(ctx, m, &m_len); EVP_MD_CTX_free(tmp_ctx); if (!rv) return 0; diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c index eb5084f839..8478e643dd 100644 --- a/crypto/evp/p_verify.c +++ b/crypto/evp/p_verify.c @@ -37,6 +37,8 @@ int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf, rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); if (rv) rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len); + else + rv = EVP_DigestFinal_ex(ctx, m, &m_len); EVP_MD_CTX_free(tmp_ctx); if (!rv) return 0; -- cgit v1.2.3