Skip to content

Commit 6571f42

Browse files
authored
Merge pull request wolfSSL#8867 from JacobBarthelmeh/rng
Improvements to RNG and compatibility layer
2 parents 675ff71 + 8ee1f8f commit 6571f42

7 files changed

Lines changed: 211 additions & 89 deletions

File tree

.github/workflows/os-check.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ jobs:
4848
'--enable-sniffer --enable-curve25519 --enable-curve448 --enable-enckeys CFLAGS=-DWOLFSSL_DH_EXTRA',
4949
'--enable-dtls --enable-dtls13 --enable-dtls-frag-ch
5050
--enable-dtls-mtu CPPFLAGS=-DWOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS',
51+
'--enable-opensslall --enable-opensslextra CPPFLAGS=-DWC_RNG_SEED_CB',
52+
'--enable-opensslall --enable-opensslextra
53+
CPPFLAGS='-DWC_RNG_SEED_CB -DWOLFSSL_NO_GETPID'',
5154
]
5255
name: make check
5356
if: github.repository_owner == 'wolfssl'

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ check_function_exists("memset" HAVE_MEMSET)
124124
check_function_exists("socket" HAVE_SOCKET)
125125
check_function_exists("strftime" HAVE_STRFTIME)
126126
check_function_exists("__atomic_fetch_add" HAVE_C___ATOMIC)
127+
check_function_exists("getpid" HAVE_GETPID)
127128

128129
include(CheckSymbolExists)
129130
check_symbol_exists(isascii "ctype.h" HAVE_ISASCII)

configure.ac

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ AC_CHECK_HEADER(assert.h, [AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSL_HAVE_ASSERT_H"],[
129129
# check if functions of interest are linkable, but also check if
130130
# they're declared by the expected headers, and if not, supersede the
131131
# unusable positive from AC_CHECK_FUNCS().
132-
AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r gmtime_s inet_ntoa memset socket strftime atexit isascii])
133-
AC_CHECK_DECLS([gethostbyname, getaddrinfo, gettimeofday, gmtime_r, gmtime_s, inet_ntoa, memset, socket, strftime, atexit, isascii], [], [
132+
AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r gmtime_s inet_ntoa memset socket strftime atexit isascii getpid])
133+
AC_CHECK_DECLS([gethostbyname, getaddrinfo, gettimeofday, gmtime_r, gmtime_s, inet_ntoa, memset, socket, strftime, atexit, isascii, getpid], [], [
134134
if test "$(eval echo \$"$(eval 'echo ac_cv_func_${as_decl_name}')")" = "yes"
135135
then
136136
AC_MSG_NOTICE([ note: earlier check for $(eval 'echo ${as_decl_name}') superseded.])

src/ssl.c

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25500,6 +25500,13 @@ static int wolfSSL_RAND_InitMutex(void)
2550025500

2550125501
#ifdef OPENSSL_EXTRA
2550225502

25503+
#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
25504+
defined(HAVE_FIPS) && FIPS_VERSION3_LT(6,0,0)
25505+
/* In older FIPS bundles add check for reseed here since it does not exist in
25506+
* the older random.c certified files. */
25507+
static pid_t currentRandPid = 0;
25508+
#endif
25509+
2550325510
/* Checks if the global RNG has been created. If not then one is created.
2550425511
*
2550525512
* Returns WOLFSSL_SUCCESS when no error is encountered.
@@ -25512,6 +25519,10 @@ int wolfSSL_RAND_Init(void)
2551225519
if (initGlobalRNG == 0) {
2551325520
ret = wc_InitRng(&globalRNG);
2551425521
if (ret == 0) {
25522+
#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
25523+
defined(HAVE_FIPS) && FIPS_VERSION3_LT(6,0,0)
25524+
currentRandPid = getpid();
25525+
#endif
2551525526
initGlobalRNG = 1;
2551625527
ret = WOLFSSL_SUCCESS;
2551725528
}
@@ -25946,8 +25957,8 @@ int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
2594625957
return ret;
2594725958
}
2594825959

25949-
/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise
25950-
* WOLFSSL_FAILURE */
25960+
/* returns WOLFSSL_SUCCESS (1) if the bytes generated are valid otherwise 0
25961+
* on failure */
2595125962
int wolfSSL_RAND_bytes(unsigned char* buf, int num)
2595225963
{
2595325964
int ret = 0;
@@ -25989,6 +26000,26 @@ int wolfSSL_RAND_bytes(unsigned char* buf, int num)
2598926000
* have the lock.
2599026001
*/
2599126002
if (initGlobalRNG) {
26003+
#if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
26004+
defined(HAVE_FIPS) && FIPS_VERSION3_LT(6,0,0)
26005+
pid_t p;
26006+
26007+
p = getpid();
26008+
if (p != currentRandPid) {
26009+
wc_UnLockMutex(&globalRNGMutex);
26010+
if (wolfSSL_RAND_poll() != WOLFSSL_SUCCESS) {
26011+
WOLFSSL_MSG("Issue with check pid and reseed");
26012+
ret = WOLFSSL_FAILURE;
26013+
}
26014+
26015+
/* reclaim lock after wolfSSL_RAND_poll */
26016+
if (wc_LockMutex(&globalRNGMutex) != 0) {
26017+
WOLFSSL_MSG("Bad Lock Mutex rng");
26018+
return ret;
26019+
}
26020+
currentRandPid = p;
26021+
}
26022+
#endif
2599226023
rng = &globalRNG;
2599326024
used_global = 1;
2599426025
}
@@ -26065,6 +26096,11 @@ int wolfSSL_RAND_poll(void)
2606526096
}
2606626097
else {
2606726098
#ifdef HAVE_HASHDRBG
26099+
if (wc_LockMutex(&globalRNGMutex) != 0) {
26100+
WOLFSSL_MSG("Bad Lock Mutex rng");
26101+
return ret;
26102+
}
26103+
2606826104
ret = wc_RNG_DRBG_Reseed(&globalRNG, entropy, entropy_sz);
2606926105
if (ret != 0) {
2607026106
WOLFSSL_MSG("Error reseeding DRBG");
@@ -26073,6 +26109,7 @@ int wolfSSL_RAND_poll(void)
2607326109
else {
2607426110
ret = WOLFSSL_SUCCESS;
2607526111
}
26112+
wc_UnLockMutex(&globalRNGMutex);
2607626113
#else
2607726114
WOLFSSL_MSG("RAND_poll called with HAVE_HASHDRBG not set");
2607826115
ret = WOLFSSL_FAILURE;

tests/api.c

Lines changed: 89 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33158,6 +33158,12 @@ static int test_wolfSSL_RAND_bytes(void)
3315833158
const int size4 = RNG_MAX_BLOCK_LEN * 4; /* in bytes */
3315933159
int max_bufsize;
3316033160
byte *my_buf = NULL;
33161+
#if defined(HAVE_GETPID)
33162+
byte seed[16] = {0};
33163+
byte randbuf[8] = {0};
33164+
int pipefds[2] = {0};
33165+
pid_t pid = 0;
33166+
#endif
3316133167

3316233168
/* sanity check */
3316333169
ExpectIntEQ(RAND_bytes(NULL, 16), 0);
@@ -33177,6 +33183,46 @@ static int test_wolfSSL_RAND_bytes(void)
3317733183
ExpectIntEQ(RAND_bytes(my_buf, size3), 1);
3317833184
ExpectIntEQ(RAND_bytes(my_buf, size4), 1);
3317933185

33186+
#if defined(OPENSSL_EXTRA) && defined(HAVE_GETPID)
33187+
XMEMSET(seed, 0, sizeof(seed));
33188+
RAND_cleanup();
33189+
33190+
/* No global methods set. */
33191+
ExpectIntEQ(RAND_seed(seed, sizeof(seed)), 1);
33192+
33193+
ExpectIntEQ(pipe(pipefds), 0);
33194+
pid = fork();
33195+
ExpectIntGE(pid, 0);
33196+
if (pid == 0) {
33197+
ssize_t n_written = 0;
33198+
33199+
/* Child process. */
33200+
close(pipefds[0]);
33201+
RAND_bytes(randbuf, sizeof(randbuf));
33202+
n_written = write(pipefds[1], randbuf, sizeof(randbuf));
33203+
close(pipefds[1]);
33204+
exit(n_written == sizeof(randbuf) ? 0 : 1);
33205+
}
33206+
else {
33207+
/* Parent process. */
33208+
word64 childrand64 = 0;
33209+
int waitstatus = 0;
33210+
33211+
close(pipefds[1]);
33212+
ExpectIntEQ(RAND_bytes(randbuf, sizeof(randbuf)), 1);
33213+
ExpectIntEQ(read(pipefds[0], &childrand64, sizeof(childrand64)),
33214+
sizeof(childrand64));
33215+
#ifdef WOLFSSL_NO_GETPID
33216+
ExpectBufEQ(randbuf, &childrand64, sizeof(randbuf));
33217+
#else
33218+
ExpectBufNE(randbuf, &childrand64, sizeof(randbuf));
33219+
#endif
33220+
close(pipefds[0]);
33221+
waitpid(pid, &waitstatus, 0);
33222+
}
33223+
RAND_cleanup();
33224+
#endif
33225+
3318033226
XFREE(my_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3318133227
#endif
3318233228
return EXPECT_RESULT();
@@ -33209,50 +33255,60 @@ static int test_wolfSSL_RAND(void)
3320933255
}
3321033256

3321133257

33258+
#if defined(WC_RNG_SEED_CB) && defined(OPENSSL_EXTRA)
33259+
static int wc_DummyGenerateSeed(OS_Seed* os, byte* output, word32 sz)
33260+
{
33261+
word32 i;
33262+
for (i = 0; i < sz; i++ )
33263+
output[i] = (byte)i;
33264+
33265+
(void)os;
33266+
33267+
return 0;
33268+
}
33269+
#endif /* WC_RNG_SEED_CB */
33270+
33271+
3321233272
static int test_wolfSSL_RAND_poll(void)
3321333273
{
3321433274
EXPECT_DECLS;
3321533275

33216-
#if defined(OPENSSL_EXTRA) && defined(__linux__)
33217-
byte seed[16] = {0};
33218-
byte randbuf[8] = {0};
33219-
int pipefds[2] = {0};
33220-
pid_t pid = 0;
33276+
#if defined(OPENSSL_EXTRA)
33277+
byte seed[16];
33278+
byte rand1[16];
33279+
#ifdef WC_RNG_SEED_CB
33280+
byte rand2[16];
33281+
#endif
3322133282

3322233283
XMEMSET(seed, 0, sizeof(seed));
33284+
ExpectIntEQ(RAND_seed(seed, sizeof(seed)), 1);
33285+
ExpectIntEQ(RAND_poll(), 1);
33286+
ExpectIntEQ(RAND_bytes(rand1, 16), 1);
33287+
RAND_cleanup();
33288+
33289+
#ifdef WC_RNG_SEED_CB
33290+
/* Test with custom seed and poll */
33291+
wc_SetSeed_Cb(wc_DummyGenerateSeed);
3322333292

33224-
/* No global methods set. */
3322533293
ExpectIntEQ(RAND_seed(seed, sizeof(seed)), 1);
33294+
ExpectIntEQ(RAND_bytes(rand1, 16), 1);
33295+
RAND_cleanup();
3322633296

33227-
ExpectIntEQ(pipe(pipefds), 0);
33228-
pid = fork();
33229-
ExpectIntGE(pid, 0);
33230-
if (pid == 0)
33231-
{
33232-
ssize_t n_written = 0;
33297+
/* test that the same value is generated twice with dummy seed function */
33298+
ExpectIntEQ(RAND_seed(seed, sizeof(seed)), 1);
33299+
ExpectIntEQ(RAND_bytes(rand2, 16), 1);
33300+
ExpectIntEQ(XMEMCMP(rand1, rand2, 16), 0);
33301+
RAND_cleanup();
3323333302

33234-
/* Child process. */
33235-
close(pipefds[0]);
33236-
RAND_poll();
33237-
RAND_bytes(randbuf, sizeof(randbuf));
33238-
n_written = write(pipefds[1], randbuf, sizeof(randbuf));
33239-
close(pipefds[1]);
33240-
exit(n_written == sizeof(randbuf) ? 0 : 1);
33241-
}
33242-
else
33243-
{
33244-
/* Parent process. */
33245-
word64 childrand64 = 0;
33246-
int waitstatus = 0;
33303+
/* test that doing a poll is reseeding RNG */
33304+
ExpectIntEQ(RAND_seed(seed, sizeof(seed)), 1);
33305+
ExpectIntEQ(RAND_poll(), 1);
33306+
ExpectIntEQ(RAND_bytes(rand2, 16), 1);
33307+
ExpectIntNE(XMEMCMP(rand1, rand2, 16), 0);
3324733308

33248-
close(pipefds[1]);
33249-
ExpectIntEQ(RAND_poll(), 1);
33250-
ExpectIntEQ(RAND_bytes(randbuf, sizeof(randbuf)), 1);
33251-
ExpectIntEQ(read(pipefds[0], &childrand64, sizeof(childrand64)), sizeof(childrand64));
33252-
ExpectBufNE(randbuf, &childrand64, sizeof(randbuf));
33253-
close(pipefds[0]);
33254-
waitpid(pid, &waitstatus, 0);
33255-
}
33309+
/* reset the seed function used */
33310+
wc_SetSeed_Cb(wc_GenerateSeed);
33311+
#endif
3325633312
RAND_cleanup();
3325733313

3325833314
ExpectIntEQ(RAND_egd(NULL), -1);

0 commit comments

Comments
 (0)