summaryrefslogtreecommitdiffstats
path: root/crypto/evp/digest.c
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2023-03-09 11:45:02 -0500
committerPauli <pauli@openssl.org>2023-03-15 08:42:59 +1100
commit3fc2b7d6b8f961144905330dfd4689f5bd515199 (patch)
tree6636f65738ba67a2c55d1941a0c7f3a4432e590d /crypto/evp/digest.c
parentf3c0dd4f0cd3bc282575a98181f8190d81189a78 (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.c22
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: