Commit 47aae188a6 for openssl.org

commit 47aae188a6bdc65675ea9c2a9e770bef48a5d781
Author: Richard Levitte <levitte@openssl.foundation>
Date:   Thu Aug 27 10:52:07 2026 +0200

    evp_extra: test DSA/DH set_method regression

    In test_low_level_dsa_method() and test_low_level_dh_method(), warm the
    Montgomery cache (by signing / deriving) before the *_set_method() call
    so the default finish slot uses the cache pointer for free.  After the
    fix on the corresponding issue, this should not crash any more.

    The DSA warm uses DSA_do_sign(); the DH warm uses DH_compute_key()
    with the key's own pub_key as peer (self-derive, purpose is to touch
    the Montgomery path, not perform a real derivation).

    Refs: https://github.com/openssl/openssl/issues/32541
    Assisted-by: Pi:moonshotai/kimi-k3
    Signed-off-by: Richard Levitte <levitte@openssl.foundation>
    Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
    Reviewed-by: Matt Caswell <matt@openssl.foundation>
    Merge-date: Sun Aug 30 14:55:00 2026
    Merged-from: https://github.com/openssl/openssl/pull/32543

diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 1eeb0c442b..574d472b49 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -9316,8 +9316,10 @@ static int test_low_level_dsa_method(void)
     DSA *dsa = NULL;
     const DSA_METHOD *def = DSA_get_default_method();
     DSA_METHOD *method = DSA_meth_dup(def);
+    DSA_SIG *dsa_sig = NULL;
     EVP_PKEY *pkey = NULL;
     int testresult = 0;
+    unsigned char dgst[32];

     if (nullprov != NULL) {
         testresult = TEST_skip("Test does not support a non-default library context");
@@ -9337,6 +9339,12 @@ static int test_low_level_dsa_method(void)
     if (!TEST_true(DSA_generate_key(dsa)))
         goto err;

+    /* Warm the Montgomery cache so the finish slot touches it (Issue: 32541) */
+    memset(dgst, 0, sizeof(dgst));
+    if (!TEST_ptr(dsa_sig = DSA_do_sign(dgst, sizeof(dgst), dsa)))
+        goto err;
+    DSA_SIG_free(dsa_sig);
+
     orig_dsa_sign = DSA_meth_get_sign(def);
     if (!TEST_true(DSA_meth_set_sign(method, tst_dsa_sign)))
         goto err;
@@ -9488,12 +9496,7 @@ static int test_low_level_dh_method(void)
     if (!TEST_true(DH_set_ex_data(dh, dh_ex_idx, (void *)"test")))
         goto err;

-    orig_dh_compute_key = DH_meth_get_compute_key(def);
-    if (!TEST_true(DH_meth_set_compute_key(method, tst_dh_compute_key)))
-        goto err;
-    if (!TEST_true(DH_set_method(dh, method)))
-        goto err;
-
+    /* Prepare the API for warming the cache */
     p = BN_dup(DH_get0_p(cdh));
     g = BN_dup(DH_get0_g(cdh));
     if (!TEST_ptr(p) || !TEST_ptr(g))
@@ -9505,6 +9508,21 @@ static int test_low_level_dh_method(void)
     if (!TEST_true(DH_generate_key(dh)))
         goto err;

+    /* Warm the Montgomery cache before the switch (Issue: #32541) */
+    buf = OPENSSL_malloc(DH_size(dh));
+    if (!TEST_ptr(buf))
+        goto err;
+    if (!TEST_int_gt(DH_compute_key(buf, DH_get0_pub_key(dh), dh), 0))
+        goto err;
+    OPENSSL_free(buf);
+    buf = NULL;
+
+    orig_dh_compute_key = DH_meth_get_compute_key(def);
+    if (!TEST_true(DH_meth_set_compute_key(method, tst_dh_compute_key)))
+        goto err;
+    if (!TEST_true(DH_set_method(dh, method)))
+        goto err;
+
     ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
     if (!TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0))
         goto err;