diff options
author | Simo Sorce <simo@redhat.com> | 2023-03-09 11:45:02 -0500 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2023-03-15 08:42:59 +1100 |
commit | 3fc2b7d6b8f961144905330dfd4689f5bd515199 (patch) | |
tree | 6636f65738ba67a2c55d1941a0c7f3a4432e590d /crypto/evp/digest.c | |
parent | f3c0dd4f0cd3bc282575a98181f8190d81189a78 (diff) |
Add a flag so finalised contexts are not reused
The EVP layer should not rely on the underlying low level code to
handle catching incorrect reuse of contexts.
Add a flag to mark a context as finalised as needed and then catch and
immediately error on Update/Final operations if called improperly.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/20375)
Diffstat (limited to 'crypto/evp/digest.c')
-rw-r--r-- | crypto/evp/digest.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 6ce80a1b03..e7590cda55 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -181,7 +181,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, } #endif - EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED + | EVP_MD_CTX_FLAG_FINALISED); if (type != NULL) { ctx->reqdigest = type; @@ -387,6 +388,11 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) if (count == 0) return 1; + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + if (ctx->pctx != NULL && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) && ctx->pctx->op.sig.algctx != NULL) { @@ -453,8 +459,15 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) return 0; } + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + ret = ctx->digest->dfinal(ctx->algctx, md, &size, mdsize); + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + if (isize != NULL) { if (size <= UINT_MAX) { *isize = (unsigned int)size; @@ -499,12 +512,19 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size) return 0; } + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size); params[i++] = OSSL_PARAM_construct_end(); if (EVP_MD_CTX_set_params(ctx, params) > 0) ret = ctx->digest->dfinal(ctx->algctx, md, &size, size); + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + return ret; legacy: |