summaryrefslogtreecommitdiffstats
path: root/crypto/evp/digest.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-09-03 11:50:30 +0100
committerTomas Mraz <tmraz@fedoraproject.org>2020-09-10 11:35:42 +0200
commit3101ab603cd82cdbc81de0902b2b4718e8f1279b (patch)
tree02647b1a149bc52bd9973534eac593dc0744fe74 /crypto/evp/digest.c
parentb830e0042972a237c6677c071f1fcde5c1afbea7 (diff)
Fix an EVP_MD_CTX leak
If we initialise an EVP_MD_CTX with a legacy MD, and then reuse the same EVP_MD_CTX with a provided MD then we end up leaking the md_data. We need to ensure we free the md_data if we change to a provided MD. Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/12779)
Diffstat (limited to 'crypto/evp/digest.c')
-rw-r--r--crypto/evp/digest.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 19fddb74ab..07bf12e5ae 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -22,24 +22,9 @@
#include "internal/provider.h"
#include "evp_local.h"
-/* This call frees resources associated with the context */
-int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
-{
- if (ctx == NULL)
- return 1;
-
-#ifndef FIPS_MODULE
- /* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */
- /*
- * pctx should be freed by the user of EVP_MD_CTX
- * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
- */
- if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) {
- EVP_PKEY_CTX_free(ctx->pctx);
- ctx->pctx = NULL;
- }
-#endif
+void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
+{
EVP_MD_free(ctx->fetched_digest);
ctx->fetched_digest = NULL;
ctx->reqdigest = NULL;
@@ -61,16 +46,36 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
ctx->digest->cleanup(ctx);
if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
- && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
+ && (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE) || force))
OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
- }
+ if (force)
+ ctx->digest = NULL;
#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
ENGINE_finish(ctx->engine);
+ ctx->engine = NULL;
#endif
+}
- /* TODO(3.0): End of legacy code */
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
+{
+ if (ctx == NULL)
+ return 1;
+
+#ifndef FIPS_MODULE
+ /* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */
+ /*
+ * pctx should be freed by the user of EVP_MD_CTX
+ * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
+ */
+ if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) {
+ EVP_PKEY_CTX_free(ctx->pctx);
+ ctx->pctx = NULL;
+ }
+#endif
+ evp_md_ctx_clear_digest(ctx, 0);
OPENSSL_cleanse(ctx, sizeof(*ctx));
return 1;