mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
test: add test case to reliably reproduce RAND leak during POST
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)
This commit is contained in:
parent
b6f0f050fd
commit
235776b2c7
@ -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
|
||||
|
@ -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");
|
||||
|
@ -20,77 +20,12 @@
|
||||
#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();
|
||||
|
82
test/threadstest.h
Normal file
82
test/threadstest.h
Normal file
@ -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
|
||||
|
49
test/threadstest_fips.c
Normal file
49
test/threadstest_fips.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user