Commit 8c63835c8c for openssl.org
commit 8c63835c8c24783215bb47a842165f7ae45cd501
Author: Simo Sorce <simo@redhat.com>
Date: Tue Dec 2 15:19:52 2025 -0500
Initialize DRBG for single FIPS KATs
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)
diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c
index d3d1e02831..f4cda15d8d 100644
--- a/providers/fips/self_test_kats.c
+++ b/providers/fips/self_test_kats.c
@@ -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;
}