[openssl] openssl-3.0 update

Matt Caswell matt at openssl.org
Mon Jan 10 16:55:04 UTC 2022


The branch openssl-3.0 has been updated
       via  afaa7755aa3e577348e1267d5ad34da695292917 (commit)
       via  fa2029250e38947ebd68a9b5861bedaa2384d85d (commit)
       via  43927f81a5d1ea1d32508430eee2df85736ba105 (commit)
      from  617203e64f17371b95fc8d64fc7fde9f8bc6e9db (commit)


- Log -----------------------------------------------------------------
commit afaa7755aa3e577348e1267d5ad34da695292917
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Dec 29 16:39:11 2021 +0000

    Add a test for a custom digest created via EVP_MD_meth_new()
    
    We check that the init and cleanup functions for the custom method are
    called as expected.
    
    Based on an original reproducer by Dmitry Belyavsky from issue #17149.
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/17255)
    
    (cherry picked from commit fbbe7202eba9fba243c18513f4f0316dafb3496d)

commit fa2029250e38947ebd68a9b5861bedaa2384d85d
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Dec 10 17:17:27 2021 +0000

    Fix a leak in EVP_DigestInit_ex()
    
    If an EVP_MD_CTX is reused then memory allocated and stored in md_data
    can be leaked unless the EVP_MD's cleanup function is called.
    
    Fixes #17149
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/17255)
    
    (cherry picked from commit 357bccc8ba64ec8a5f587b04b5d6b6ca9e8dcbdc)

commit 43927f81a5d1ea1d32508430eee2df85736ba105
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Dec 10 16:53:02 2021 +0000

    Ensure that MDs created via EVP_MD_meth_new() go down the legacy route
    
    MDs created via EVP_MD_meth_new() are inherently legacy and therefore
    need to go down the legacy route when they are used.
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/17255)
    
    (cherry picked from commit d9ad5b16b32172df6f7d02cfb1c339cc85d0db01)

-----------------------------------------------------------------------

Summary of changes:
 crypto/evp/digest.c   | 34 ++++++++++++---------
 test/evp_extra_test.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+), 15 deletions(-)

diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index d92059cbcc..eb6ccfaca2 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -25,6 +25,19 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force)
+{
+    if (ctx->digest != NULL) {
+        if (ctx->digest->cleanup != NULL
+                && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+            ctx->digest->cleanup(ctx);
+        if (ctx->md_data != NULL && ctx->digest->ctx_size > 0
+                && (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)
+                    || force))
+            OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+        ctx->md_data = NULL;
+    }
+}
 
 void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
 {
@@ -41,12 +54,7 @@ void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
      * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
      * sometimes only copies of the context are ever finalised.
      */
-    if (ctx->digest && ctx->digest->cleanup
-        && !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) || force))
-        OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+    cleanup_old_md_data(ctx, force);
     if (force)
         ctx->digest = NULL;
 
@@ -207,7 +215,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
             || tmpimpl != NULL
 #endif
-            || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) {
+            || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0
+            || type->origin == EVP_ORIG_METH) {
         if (ctx->digest == ctx->fetched_digest)
             ctx->digest = NULL;
         EVP_MD_free(ctx->fetched_digest);
@@ -215,10 +224,7 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
         goto legacy;
     }
 
-    if (ctx->digest != NULL && ctx->digest->ctx_size > 0) {
-        OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-        ctx->md_data = NULL;
-    }
+    cleanup_old_md_data(ctx, 1);
 
     /* Start of non-legacy code below */
 
@@ -307,10 +313,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
     }
 #endif
     if (ctx->digest != type) {
-        if (ctx->digest && ctx->digest->ctx_size) {
-            OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-            ctx->md_data = NULL;
-        }
+        cleanup_old_md_data(ctx, 1);
+
         ctx->digest = type;
         if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
             ctx->update = type->update;
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 47ef35ca67..21bc2eb4df 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -4179,6 +4179,90 @@ static int test_evp_md_cipher_meth(void)
     return testresult;
 }
 
+typedef struct {
+        int data;
+} custom_dgst_ctx;
+
+static int custom_md_init_called = 0;
+static int custom_md_cleanup_called = 0;
+
+static int custom_md_init(EVP_MD_CTX *ctx)
+{
+    custom_dgst_ctx *p = EVP_MD_CTX_md_data(ctx);
+
+    if (p == NULL)
+        return 0;
+
+    custom_md_init_called++;
+    return 1;
+}
+
+static int custom_md_cleanup(EVP_MD_CTX *ctx)
+{
+    custom_dgst_ctx *p = EVP_MD_CTX_md_data(ctx);
+
+    if (p == NULL)
+        /* Nothing to do */
+        return 1;
+
+    custom_md_cleanup_called++;
+    return 1;
+}
+
+static int test_custom_md_meth(void)
+{
+    EVP_MD_CTX *mdctx = NULL;
+    EVP_MD *tmp = NULL;
+    char mess[] = "Test Message\n";
+    unsigned char md_value[EVP_MAX_MD_SIZE];
+    unsigned int md_len;
+    int testresult = 0;
+    int nid;
+
+    /*
+     * We are testing deprecated functions. We don't support a non-default
+     * library context in this test.
+     */
+    if (testctx != NULL)
+        return 1;
+
+    custom_md_init_called = custom_md_cleanup_called = 0;
+
+    nid = OBJ_create("1.3.6.1.4.1.16604.998866.1", "custom-md", "custom-md");
+    if (!TEST_int_ne(nid, NID_undef))
+        goto err;
+    tmp = EVP_MD_meth_new(nid, NID_undef);
+    if (!TEST_ptr(tmp))
+        goto err;
+
+    if (!TEST_true(EVP_MD_meth_set_init(tmp, custom_md_init))
+            || !TEST_true(EVP_MD_meth_set_cleanup(tmp, custom_md_cleanup))
+            || !TEST_true(EVP_MD_meth_set_app_datasize(tmp,
+                                                       sizeof(custom_dgst_ctx))))
+        goto err;
+
+    mdctx = EVP_MD_CTX_new();
+    if (!TEST_ptr(mdctx)
+               /*
+                * Initing our custom md and then initing another md should
+                * result in the init and cleanup functions of the custom md
+                * from being called.
+                */
+            || !TEST_true(EVP_DigestInit_ex(mdctx, tmp, NULL))
+            || !TEST_true(EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL))
+            || !TEST_true(EVP_DigestUpdate(mdctx, mess, strlen(mess)))
+            || !TEST_true(EVP_DigestFinal_ex(mdctx, md_value, &md_len))
+            || !TEST_int_eq(custom_md_init_called, 1)
+            || !TEST_int_eq(custom_md_cleanup_called, 1))
+        goto err;
+
+    testresult = 1;
+ err:
+    EVP_MD_CTX_free(mdctx);
+    EVP_MD_meth_free(tmp);
+    return testresult;
+}
+
 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
 /* Test we can create a signature keys with an associated ENGINE */
 static int test_signatures_with_engine(int tst)
@@ -4473,6 +4557,7 @@ int setup_tests(void)
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     ADD_ALL_TESTS(test_custom_pmeth, 12);
     ADD_TEST(test_evp_md_cipher_meth);
+    ADD_TEST(test_custom_md_meth);
 
 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
     /* Tests only support the default libctx */


More information about the openssl-commits mailing list