summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/evp/digest.c22
-rw-r--r--crypto/evp/m_sigver.c61
-rw-r--r--include/crypto/evp.h1
-rw-r--r--include/openssl/evp.h3
4 files changed, 77 insertions, 10 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:
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 68ae957058..e7888d2acd 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -64,6 +64,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
if (ctx->pctx == NULL)
return 0;
+ EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_FINALISED);
+
locpctx = ctx->pctx;
ERR_set_mark();
@@ -401,6 +403,11 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
{
EVP_PKEY_CTX *pctx = ctx->pctx;
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
+ return 0;
+ }
+
if (pctx == NULL
|| pctx->operation != EVP_PKEY_OP_SIGNCTX
|| pctx->op.sig.algctx == NULL
@@ -431,6 +438,11 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
{
EVP_PKEY_CTX *pctx = ctx->pctx;
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
+ return 0;
+ }
+
if (pctx == NULL
|| pctx->operation != EVP_PKEY_OP_VERIFYCTX
|| pctx->op.sig.algctx == NULL
@@ -464,6 +476,11 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
int sctx = 0, r = 0;
EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+ return 0;
+ }
+
if (pctx == NULL
|| pctx->operation != EVP_PKEY_OP_SIGNCTX
|| pctx->op.sig.algctx == NULL
@@ -479,7 +496,10 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
sigret, siglen,
sigret == NULL ? 0 : *siglen);
- EVP_PKEY_CTX_free(dctx);
+ if (dctx == NULL && sigret != NULL)
+ ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
+ else
+ EVP_PKEY_CTX_free(dctx);
return r;
legacy:
@@ -497,9 +517,10 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
if (sigret == NULL)
return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
- if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) {
r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
- else {
+ ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
+ } else {
dctx = EVP_PKEY_CTX_dup(pctx);
if (dctx == NULL)
return 0;
@@ -560,15 +581,23 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
{
EVP_PKEY_CTX *pctx = ctx->pctx;
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+ return 0;
+ }
+
if (pctx != NULL
&& pctx->operation == EVP_PKEY_OP_SIGNCTX
&& pctx->op.sig.algctx != NULL
&& pctx->op.sig.signature != NULL) {
- if (pctx->op.sig.signature->digest_sign != NULL)
+ if (pctx->op.sig.signature->digest_sign != NULL) {
+ if (sigret != NULL)
+ ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx,
sigret, siglen,
sigret == NULL ? 0 : *siglen,
tbs, tbslen);
+ }
} else {
/* legacy */
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
@@ -589,6 +618,11 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
int vctx = 0;
EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+ return 0;
+ }
+
if (pctx == NULL
|| pctx->operation != EVP_PKEY_OP_VERIFYCTX
|| pctx->op.sig.algctx == NULL
@@ -603,7 +637,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
}
r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
sig, siglen);
- EVP_PKEY_CTX_free(dctx);
+ if (dctx == NULL)
+ ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
+ else
+ EVP_PKEY_CTX_free(dctx);
return r;
legacy:
@@ -623,9 +660,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
else
vctx = 0;
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
- if (vctx)
+ if (vctx) {
r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx);
- else
+ ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
+ } else
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
} else {
EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
@@ -652,14 +690,21 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
{
EVP_PKEY_CTX *pctx = ctx->pctx;
+ if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+ return 0;
+ }
+
if (pctx != NULL
&& pctx->operation == EVP_PKEY_OP_VERIFYCTX
&& pctx->op.sig.algctx != NULL
&& pctx->op.sig.signature != NULL) {
- if (pctx->op.sig.signature->digest_verify != NULL)
+ if (pctx->op.sig.signature->digest_verify != NULL) {
+ ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx,
sigret, siglen,
tbs, tbslen);
+ }
} else {
/* legacy */
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index dbbdcccbda..55b44cd835 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -21,6 +21,7 @@
* values in evp.h
*/
#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400
+#define EVP_MD_CTX_FLAG_FINALISED 0x0800
#define evp_pkey_ctx_is_legacy(ctx) \
((ctx)->keymgmt == NULL)
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index b8bafe4e12..e10c0617a4 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -226,7 +226,8 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
* if the following flag is set.
*/
# define EVP_MD_CTX_FLAG_FINALISE 0x0200
-/* NOTE: 0x0400 is reserved for internal usage */
+/* NOTE: 0x0400 and 0x0800 are reserved for internal usage */
+
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);