]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
test: add test case to reliably reproduce RAND leak during POST
authorPauli <pauli@openssl.org>
Fri, 14 May 2021 05:41:14 +0000 (15:41 +1000)
committerPauli <pauli@openssl.org>
Sun, 23 May 2021 23:39:15 +0000 (09:39 +1000)
The FIPS provider leaks a RAND if the POST is run at initialisation time.
This test case reliably reproduces this event.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15278)

test/build.info
test/recipes/90-test_threads.t
test/threadstest.c
test/threadstest.h [new file with mode: 0644]
test/threadstest_fips.c [new file with mode: 0644]

index 58d75be5d4224f86033c32852acfbf7b7c5407e0..183c97260266eee0e6654ad7ced83b4903957ba7 100644 (file)
@@ -47,7 +47,7 @@ IF[{- !$disabled{tests} -}]
           bio_callback_test bio_memleak_test bio_core_test param_build_test \
           bioprinttest sslapitest dtlstest sslcorrupttest \
           bio_enc_test pkey_meth_test pkey_meth_kdf_test evp_kdf_test uitest \
-          cipherbytes_test \
+          cipherbytes_test threadstest_fips \
           asn1_encode_test asn1_decode_test asn1_string_table_test \
           x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \
           recordlentest drbgtest rand_status_test sslbuffertest \
@@ -271,6 +271,10 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[threadstest]=../include ../apps/include
   DEPEND[threadstest]=../libcrypto libtestutil.a
 
+  SOURCE[threadstest_fips]=threadstest_fips.c
+  INCLUDE[threadstest_fips]=../include ../apps/include
+  DEPEND[threadstest_fips]=../libcrypto libtestutil.a
+
   SOURCE[afalgtest]=afalgtest.c
   INCLUDE[afalgtest]=../include ../apps/include
   DEPEND[afalgtest]=../libcrypto libtestutil.a
index a841a4b2f5930f8d0e598e1fb2c4c38cf5b1fa3d..651fa805d5c637f075797413023cc220114f37b8 100644 (file)
@@ -23,7 +23,7 @@ my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
 my $config_path = abs_path(srctop_file("test", $no_fips ? "default.cnf"
                                                         : "default-and-fips.cnf"));
 
-plan tests => 1;
+plan tests => 2;
 
 if ($no_fips) {
     ok(run(test(["threadstest", "-config", $config_path, data_dir()])),
@@ -32,3 +32,25 @@ if ($no_fips) {
     ok(run(test(["threadstest", "-fips", "-config", $config_path, data_dir()])),
        "running test_threads with FIPS");
 }
+
+# Merge the configuration files into one filtering the contents so the failure
+# condition is reproducable.  A working FIPS configuration without the install
+# status is required.
+
+open CFGBASE, '<', $config_path;
+open CFGINC, '<', bldtop_file('/providers/fipsmodule.cnf');
+open CFGOUT, '>', 'thread.cnf';
+
+while (<CFGBASE>) {
+    print CFGOUT unless m/^[.]include/;
+}
+close CFGBASE;
+print CFGOUT "\n\n";
+while (<CFGINC>) {
+    print CFGOUT unless m/^install-status/;
+}
+close CFGINC;
+close CFGOUT;
+
+$ENV{OPENSSL_CONF} = 'thread.cnf';
+ok(run(test(["threadstest_fips"])), "running test_threads_fips");
index 359b330024a8f8ecbe6e2eee93d95c7e42965cde..4f05cbec544c825f820ef9457086a1e6d87707d1 100644 (file)
 #include <openssl/aes.h>
 #include <openssl/rsa.h>
 #include "testutil.h"
+#include "threadstest.h"
 
 static int do_fips = 0;
 static char *privkey;
 static char *config_file = NULL;
 
-#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
-
-typedef unsigned int thread_t;
-
-static int run_thread(thread_t *t, void (*f)(void))
-{
-    f();
-    return 1;
-}
-
-static int wait_for_thread(thread_t thread)
-{
-    return 1;
-}
-
-#elif defined(OPENSSL_SYS_WINDOWS)
-
-typedef HANDLE thread_t;
-
-static DWORD WINAPI thread_run(LPVOID arg)
-{
-    void (*f)(void);
-
-    *(void **) (&f) = arg;
-
-    f();
-    return 0;
-}
-
-static int run_thread(thread_t *t, void (*f)(void))
-{
-    *t = CreateThread(NULL, 0, thread_run, *(void **) &f, 0, NULL);
-    return *t != NULL;
-}
-
-static int wait_for_thread(thread_t thread)
-{
-    return WaitForSingleObject(thread, INFINITE) == 0;
-}
-
-#else
-
-typedef pthread_t thread_t;
-
-static void *thread_run(void *arg)
-{
-    void (*f)(void);
-
-    *(void **) (&f) = arg;
-
-    f();
-    return NULL;
-}
-
-static int run_thread(thread_t *t, void (*f)(void))
-{
-    return pthread_create(t, NULL, thread_run, *(void **) &f) == 0;
-}
-
-static int wait_for_thread(thread_t thread)
-{
-    return pthread_join(thread, NULL) == 0;
-}
-
-#endif
-
 static int test_lock(void)
 {
     CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
diff --git a/test/threadstest.h b/test/threadstest.h
new file mode 100644 (file)
index 0000000..8bdedd7
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+#include <string.h>
+#include "testutil.h"
+
+#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
+
+typedef unsigned int thread_t;
+
+static int run_thread(thread_t *t, void (*f)(void))
+{
+    f();
+    return 1;
+}
+
+static int wait_for_thread(thread_t thread)
+{
+    return 1;
+}
+
+#elif defined(OPENSSL_SYS_WINDOWS)
+
+typedef HANDLE thread_t;
+
+static DWORD WINAPI thread_run(LPVOID arg)
+{
+    void (*f)(void);
+
+    *(void **) (&f) = arg;
+
+    f();
+    return 0;
+}
+
+static int run_thread(thread_t *t, void (*f)(void))
+{
+    *t = CreateThread(NULL, 0, thread_run, *(void **) &f, 0, NULL);
+    return *t != NULL;
+}
+
+static int wait_for_thread(thread_t thread)
+{
+    return WaitForSingleObject(thread, INFINITE) == 0;
+}
+
+#else
+
+typedef pthread_t thread_t;
+
+static void *thread_run(void *arg)
+{
+    void (*f)(void);
+
+    *(void **) (&f) = arg;
+
+    f();
+    return NULL;
+}
+
+static int run_thread(thread_t *t, void (*f)(void))
+{
+    return pthread_create(t, NULL, thread_run, *(void **) &f) == 0;
+}
+
+static int wait_for_thread(thread_t thread)
+{
+    return pthread_join(thread, NULL) == 0;
+}
+
+#endif
+
diff --git a/test/threadstest_fips.c b/test/threadstest_fips.c
new file mode 100644 (file)
index 0000000..b38221d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+#include "testutil.h"
+#include "threadstest.h"
+
+static int success;
+
+static void thread_fips_rand_fetch(void)
+{
+    EVP_MD *md;
+
+    if (!TEST_true(md = EVP_MD_fetch(NULL, "SHA2-256", NULL)))
+        success = 0;
+    EVP_MD_free(md);
+}
+
+static int test_fips_rand_leak(void)
+{
+    thread_t thread;
+
+    success = 1;
+
+    if (!TEST_true(run_thread(&thread, thread_fips_rand_fetch)))
+        return 0;
+    if (!TEST_true(wait_for_thread(thread)))
+        return 0;
+    return TEST_true(success);
+}
+
+int setup_tests(void)
+{
+    /*
+     * This test MUST be run first.  Once the default library context is set
+     * up, this test will always pass.
+     */
+    ADD_TEST(test_fips_rand_leak);
+    return 1;
+}