]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Initialize DRBG for single FIPS KATs
authorSimo Sorce <simo@redhat.com>
Tue, 2 Dec 2025 20:19:52 +0000 (15:19 -0500)
committerDmitry Belyavskiy <beldmit@gmail.com>
Fri, 13 Feb 2026 09:53:40 +0000 (10:53 +0100)
The SELF_TEST_kats_single() function runs an individual FIPS Known Answer Test
(KAT) on demand. These tests require a deterministic random bit generator
(DRBG) to be properly initialized to function correctly.

This change ensures a dedicated DRBG is set up for the single test run. The
existing private RNG is saved before the test and restored afterward,
isolating the test's random context from the rest of the library.

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/29222)

providers/fips/self_test_kats.c

index d3d1e028314868c10dc27c32ed0c485ffc72e053..f4cda15d8dfb8fc3e67f2cab3ace1db5a2a29200 100644 (file)
@@ -1196,6 +1196,8 @@ int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx, int do_deferred)
         /* Decrement saved_rand reference counter */
         EVP_RAND_CTX_free(saved_rand);
         EVP_RAND_CTX_free(main_rand);
+        /* Ensure this global variable does not reference freed memory */
+        main_rand = NULL;
         return 0;
     }
 
@@ -1219,6 +1221,8 @@ int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx, int do_deferred)
         ret = 0;
 
     RAND_set0_private(libctx, saved_rand);
+    /* The above call will cause main_rand to be freed */
+    main_rand = NULL;
     return ret;
 }
 
@@ -1236,12 +1240,23 @@ int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx, int do_deferred)
 int SELF_TEST_kats_single(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx,
     int type, const char *alg_name)
 {
+    EVP_RAND_CTX *saved_rand = ossl_rand_get0_private_noncreating(libctx);
     int ret = 1;
     int i, found = 0;
 
     if (alg_name == NULL)
         return 0;
 
+    if (saved_rand != NULL && !EVP_RAND_CTX_up_ref(saved_rand))
+        return 0;
+    if (!setup_main_random(libctx)
+        || !RAND_set0_private(libctx, main_rand)) {
+        /* Decrement saved_rand reference counter */
+        EVP_RAND_CTX_free(saved_rand);
+        EVP_RAND_CTX_free(main_rand);
+        return 0;
+    }
+
     switch (type) {
     case FIPS_DEFERRED_KAT_DIGEST:
         for (i = 0; i < st_kat_digest_tests_size; ++i) {
@@ -1364,6 +1379,7 @@ int SELF_TEST_kats_single(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx,
     }
 
 done:
+    RAND_set0_private(libctx, saved_rand);
     /* If no test was found for alg_name, it is considered a failure */
     return ret && found;
 }