diff --git a/CMakeLists.txt b/CMakeLists.txt index 688d9dc4e..a33712f03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,7 @@ check_function_exists("memset" HAVE_MEMSET) check_function_exists("socket" HAVE_SOCKET) check_function_exists("strftime" HAVE_STRFTIME) check_function_exists("__atomic_fetch_add" HAVE_C___ATOMIC) +check_function_exists("getpid" HAVE_GETPID) include(CheckSymbolExists) check_symbol_exists(isascii "ctype.h" HAVE_ISASCII) diff --git a/configure.ac b/configure.ac index e0b6d769c..7da6c7647 100644 --- a/configure.ac +++ b/configure.ac @@ -129,8 +129,8 @@ AC_CHECK_HEADER(assert.h, [AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSL_HAVE_ASSERT_H"],[ # check if functions of interest are linkable, but also check if # they're declared by the expected headers, and if not, supersede the # unusable positive from AC_CHECK_FUNCS(). -AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r gmtime_s inet_ntoa memset socket strftime atexit isascii]) -AC_CHECK_DECLS([gethostbyname, getaddrinfo, gettimeofday, gmtime_r, gmtime_s, inet_ntoa, memset, socket, strftime, atexit, isascii], [], [ +AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r gmtime_s inet_ntoa memset socket strftime atexit isascii getpid]) +AC_CHECK_DECLS([gethostbyname, getaddrinfo, gettimeofday, gmtime_r, gmtime_s, inet_ntoa, memset, socket, strftime, atexit, isascii, getpid], [], [ if test "$(eval echo \$"$(eval 'echo ac_cv_func_${as_decl_name}')")" = "yes" then AC_MSG_NOTICE([ note: earlier check for $(eval 'echo ${as_decl_name}') superseded.]) diff --git a/src/ssl.c b/src/ssl.c index bb1d1176c..e8f298d6f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25512,6 +25512,10 @@ int wolfSSL_RAND_Init(void) if (initGlobalRNG == 0) { ret = wc_InitRng(&globalRNG); if (ret == 0) { + #if defined(HAVE_GETPID) && defined(HAVE_FIPS) && \ + FIPS_VERSION3_LT(6,0,0))) + currentPid = getpid(); + #endif initGlobalRNG = 1; ret = WOLFSSL_SUCCESS; } @@ -25946,8 +25950,30 @@ int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num) return ret; } -/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise - * WOLFSSL_FAILURE */ +#if defined(HAVE_GETPID) && defined(HAVE_FIPS) && FIPS_VERSION3_LT(6,0,0))) +/* In older FIPS bundles add check for reseed here since it does not exist in + * the older random.c certified files. */ +static pid_t currentPid = 0; + +/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */ +static int RandCheckReSeed() +{ + int ret = WOLFSSL_SUCCESS; + pid_t p; + + p = getpid(); + if (p != currentPid) { + currentPid = p; + if (wolfSSL_RAND_poll() != WOLFSSL_SUCCESS) { + ret = WOLFSSL_FAILURE; + } + } + return ret; +} +#endif + +/* returns WOLFSSL_SUCCESS (1) if the bytes generated are valid otherwise 0 + * on failure */ int wolfSSL_RAND_bytes(unsigned char* buf, int num) { int ret = 0; @@ -25990,6 +26016,16 @@ int wolfSSL_RAND_bytes(unsigned char* buf, int num) */ if (initGlobalRNG) { rng = &globalRNG; + + #if defined(HAVE_GETPID) && defined(HAVE_FIPS) && \ + FIPS_VERSION3_LT(6,0,0))) + if (RandCheckReSeed() != WOLFSSL_SUCCESS) { + wc_UnLockMutex(&globalRNGMutex); + WOLFSSL_MSG("Issue with check pid and reseed"); + return ret; + } + #endif + used_global = 1; } else { diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 311d5a71c..7370300ed 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -1640,6 +1640,9 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, #else rng->heap = heap; #endif +#ifdef HAVE_GETPID + rng->pid = getpid(); +#endif #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) rng->devId = devId; #if defined(WOLF_CRYPTO_CB) @@ -1895,6 +1898,63 @@ int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, return _InitRng(rng, nonce, nonceSz, heap, devId); } +#ifdef HAVE_HASHDRBG +static int PollAndReSeed(WC_RNG* rng) +{ + int ret = DRBG_NEED_RESEED; + int devId = INVALID_DEVID; +#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) + devId = rng->devId; +#endif + if (wc_RNG_HealthTestLocal(1, rng->heap, devId) == 0) { + #ifndef WOLFSSL_SMALL_STACK + byte newSeed[SEED_SZ + SEED_BLOCK_SZ]; + ret = DRBG_SUCCESS; + #else + byte* newSeed = (byte*)XMALLOC(SEED_SZ + SEED_BLOCK_SZ, rng->heap, + DYNAMIC_TYPE_SEED); + ret = (newSeed == NULL) ? MEMORY_E : DRBG_SUCCESS; + #endif + if (ret == DRBG_SUCCESS) { + #ifdef WC_RNG_SEED_CB + if (seedCb == NULL) { + ret = DRBG_NO_SEED_CB; + } + else { + ret = seedCb(&rng->seed, newSeed, SEED_SZ + SEED_BLOCK_SZ); + if (ret != 0) { + ret = DRBG_FAILURE; + } + } + #else + ret = wc_GenerateSeed(&rng->seed, newSeed, + SEED_SZ + SEED_BLOCK_SZ); + #endif + if (ret != 0) + ret = DRBG_FAILURE; + } + if (ret == DRBG_SUCCESS) + ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ); + + if (ret == DRBG_SUCCESS) + ret = Hash_DRBG_Reseed((DRBG_internal *)rng->drbg, + newSeed + SEED_BLOCK_SZ, SEED_SZ); + #ifdef WOLFSSL_SMALL_STACK + if (newSeed != NULL) { + ForceZero(newSeed, SEED_SZ + SEED_BLOCK_SZ); + } + XFREE(newSeed, rng->heap, DYNAMIC_TYPE_SEED); + #else + ForceZero(newSeed, sizeof(newSeed)); + #endif + } + else { + ret = DRBG_CONT_FAILURE; + } + + return ret; +} +#endif /* place a generated block in output */ WOLFSSL_ABI @@ -1954,60 +2014,22 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) if (rng->status != DRBG_OK) return RNG_FAILURE_E; +#ifdef HAVE_GETPID + if (rng->pid != getpid()) { + rng->pid = getpid(); + ret = PollAndReSeed(rng); + if (ret != DRBG_SUCCESS) { + rng->status = DRBG_FAILED; + return RNG_FAILURE_E; + } + } +#endif + ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz); if (ret == DRBG_NEED_RESEED) { - int devId = INVALID_DEVID; - #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) - devId = rng->devId; - #endif - if (wc_RNG_HealthTestLocal(1, rng->heap, devId) == 0) { - #ifndef WOLFSSL_SMALL_STACK - byte newSeed[SEED_SZ + SEED_BLOCK_SZ]; - ret = DRBG_SUCCESS; - #else - byte* newSeed = (byte*)XMALLOC(SEED_SZ + SEED_BLOCK_SZ, rng->heap, - DYNAMIC_TYPE_SEED); - ret = (newSeed == NULL) ? MEMORY_E : DRBG_SUCCESS; - #endif - if (ret == DRBG_SUCCESS) { - #ifdef WC_RNG_SEED_CB - if (seedCb == NULL) { - ret = DRBG_NO_SEED_CB; - } - else { - ret = seedCb(&rng->seed, newSeed, SEED_SZ + SEED_BLOCK_SZ); - if (ret != 0) { - ret = DRBG_FAILURE; - } - } - #else - ret = wc_GenerateSeed(&rng->seed, newSeed, - SEED_SZ + SEED_BLOCK_SZ); - #endif - if (ret != 0) - ret = DRBG_FAILURE; - } - if (ret == DRBG_SUCCESS) - ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ); - - if (ret == DRBG_SUCCESS) - ret = Hash_DRBG_Reseed((DRBG_internal *)rng->drbg, - newSeed + SEED_BLOCK_SZ, SEED_SZ); - if (ret == DRBG_SUCCESS) - ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz); - - #ifdef WOLFSSL_SMALL_STACK - if (newSeed != NULL) { - ForceZero(newSeed, SEED_SZ + SEED_BLOCK_SZ); - } - XFREE(newSeed, rng->heap, DYNAMIC_TYPE_SEED); - #else - ForceZero(newSeed, sizeof(newSeed)); - #endif - } - else { - ret = DRBG_CONT_FAILURE; - } + ret = PollAndReSeed(rng); + if (ret == DRBG_SUCCESS) + ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz); } if (ret == DRBG_SUCCESS) { diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 5abd6c011..2b559bf55 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -189,6 +189,9 @@ struct WC_RNG { #endif byte status; #endif +#ifdef HAVE_GETPID + pid_t pid; +#endif #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif