From b9a850575f5db11fb811355713444959e0481d84 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 17 Sep 2018 15:33:08 -0700 Subject: [PATCH 1/5] FIPSv2: RNG Update 1. For non-FIPS builds, lower the entropy request size to the old value. 2. Added a consistency check to the result of the entropy source. The test involves requesting an additional 64-bits, then doing a running comparison of each block of 64-bits. The first block of bits is ignored. 3. Refactored the RNG seeding a bit. Renamed all variables with "entropy" in the name as "seed". Renamed the constants for entropy sizes as seed sizes. Changed the security strength to its actual value and introduced an entropy scaling factor for the number of bits of entropy per bit and a size for the NDRBG block size. 4. Changed it so the user can change the parameters for the RNG at the build configuration. If using FIPSv2, triggers an error if the paramters are changed. --- wolfcrypt/src/random.c | 215 ++++++++++++++++++++++++++----------- wolfcrypt/test/test.c | 28 +++++ wolfssl/wolfcrypt/random.h | 1 + 3 files changed, 183 insertions(+), 61 deletions(-) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index cf2f598be..0dc71be55 100755 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -89,13 +89,12 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) return FreeRng_fips(rng); } - int wc_RNG_HealthTest(int reseed, - const byte* entropyA, word32 entropyASz, - const byte* entropyB, word32 entropyBSz, - byte* output, word32 outputSz) + int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz, + const byte* seedB, word32 seedBSz, + byte* output, word32 outputSz) { - return RNG_HealthTest_fips(reseed, entropyA, entropyASz, - entropyB, entropyBSz, output, outputSz); + return RNG_HealthTest_fips(reseed, seedA, seedASz, + seedB, seedBSz, output, outputSz); } #endif /* HAVE_HASHDRBG */ @@ -177,9 +176,69 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) #define OUTPUT_BLOCK_LEN (WC_SHA256_DIGEST_SIZE) #define MAX_REQUEST_LEN (0x10000) #define RESEED_INTERVAL WC_RESEED_INTERVAL -#define SECURITY_STRENGTH (2048) -#define ENTROPY_SZ (SECURITY_STRENGTH/8) -#define MAX_ENTROPY_SZ (ENTROPY_SZ + ENTROPY_SZ/2) + + +/* For FIPS builds, the user should not be adjusting the values. */ +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + #if defined(RNG_SECURITY_STRENGTH) \ + || defined(ENTROPY_SCALE_FACTOR) \ + || defined(SEED_BLOCK_SZ) + + #error "Do not change the RNG parameters for FIPS builds." + #endif +#endif + + +/* The security strength for the RNG is the target number of bits of + * entropy you are looking for in a seed. */ +#ifndef RNG_SECURITY_STRENGTH + #if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) + /* SHA-256 requires a minimum of 256-bits of entropy. The goal + * of 1024 will provide 4 times that. */ + #define RNG_SECURITY_STRENGTH (1024) + #else + /* If not using FIPS or using old FIPS, set the number down a bit. + * More is better, but more is also slower. */ + #define RNG_SECURITY_STRENGTH (256) + #endif +#endif + +#ifndef ENTROPY_SCALE_FACTOR + /* The entropy scale factor should be the whole number inverse of the + * minimum bits of entropy per bit of NDRNG output. */ + #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) + /* The value of 2 applies to Intel's RDSEED which provides about + * 0.5 bits minimum of entropy per bit. */ + #define ENTROPY_SCALE_FACTOR 2 + #else + /* Setting the default to 1. */ + #define ENTROPY_SCALE_FACTOR 1 + #endif +#endif + +#ifndef SEED_BLOCK_SZ + /* The seed block size, is the size of the output of the underlying NDRNG. + * This value is used for testing the output of the NDRNG. */ + #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) + /* RDSEED outputs in blocks of 64-bits. */ + #define SEED_BLOCK_SZ sizeof(word64) + #else + /* Setting the default to 2. It is not unreasonable for /dev/random + * or /dev/urandom to return two bytes that are the same. */ + #define SEED_BLOCK_SZ 2 + #endif +#endif + +#define SEED_SZ (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8) + +/* The maximum seed size will be the seed size plus a seed block for the + * test, and an additional half of the seed size. This additional half + * is in case the user does not supply a nonce. A nonce will be obtained + * from the NDRNG. */ +#define MAX_SEED_SZ (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ) + /* Internal return codes */ #define DRBG_SUCCESS 0 @@ -310,19 +369,19 @@ static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type, } /* Returns: DRBG_SUCCESS or DRBG_FAILURE */ -static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz) +static int Hash_DRBG_Reseed(DRBG* drbg, const byte* seed, word32 seedSz) { - byte seed[DRBG_SEED_LEN]; + byte newV[DRBG_SEED_LEN]; - XMEMSET(seed, 0, DRBG_SEED_LEN); + XMEMSET(newV, 0, DRBG_SEED_LEN); - if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V), - entropy, entropySz) != DRBG_SUCCESS) { + if (Hash_df(drbg, newV, sizeof(newV), drbgReseed, + drbg->V, sizeof(drbg->V), seed, seedSz) != DRBG_SUCCESS) { return DRBG_FAILURE; } - XMEMCPY(drbg->V, seed, sizeof(drbg->V)); - ForceZero(seed, sizeof(seed)); + XMEMCPY(drbg->V, newV, sizeof(drbg->V)); + ForceZero(newV, sizeof(newV)); if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V, sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) { @@ -336,13 +395,13 @@ static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz) } /* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */ -int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, word32 entropySz) +int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz) { - if (rng == NULL || entropy == NULL) { + if (rng == NULL || seed == NULL) { return BAD_FUNC_ARG; } - return Hash_DRBG_Reseed(rng->drbg, entropy, entropySz); + return Hash_DRBG_Reseed(rng->drbg, seed, seedSz); } static WC_INLINE void array_add_one(byte* data, word32 dataSz) @@ -576,12 +635,35 @@ static int Hash_DRBG_Uninstantiate(DRBG* drbg) /* End NIST DRBG Code */ +int wc_RNG_TestSeed(const byte* seed, word32 seedSz) +{ + int ret = DRBG_SUCCESS; + + /* Check the seed for duplicate words. */ + word32 seedIdx = 0; + word32 scratchSz = min(SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ); + + while (seedIdx < seedSz - SEED_BLOCK_SZ) { + if (ConstantCompare(seed + seedIdx, + seed + seedIdx + scratchSz, + scratchSz) == 0) { + + ret = DRBG_CONT_FAILURE; + } + seedIdx += SEED_BLOCK_SZ; + scratchSz = min(SEED_BLOCK_SZ, (seedSz - seedIdx)); + } + + return ret; +} + + static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, void* heap, int devId) { int ret = RNG_FAILURE_E; #ifdef HAVE_HASHDRBG - word32 entropySz = ENTROPY_SZ; + word32 seedSz = SEED_SZ + SEED_BLOCK_SZ; #endif (void)nonce; @@ -634,10 +716,10 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, #else #ifdef HAVE_HASHDRBG if (nonceSz == 0) - entropySz = MAX_ENTROPY_SZ; + seedSz = MAX_SEED_SZ; if (wc_RNG_HealthTestLocal(0) == 0) { - DECLARE_VAR(entropy, byte, MAX_ENTROPY_SZ, rng->heap); + DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap); rng->drbg = (struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap, @@ -645,16 +727,24 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, if (rng->drbg == NULL) { ret = MEMORY_E; } - else if (wc_GenerateSeed(&rng->seed, entropy, entropySz) == 0 && - Hash_DRBG_Instantiate(rng->drbg, entropy, entropySz, - nonce, nonceSz, rng->heap, devId) == DRBG_SUCCESS) { - ret = Hash_DRBG_Generate(rng->drbg, NULL, 0); - } - else - ret = DRBG_FAILURE; + else { + ret = wc_GenerateSeed(&rng->seed, seed, seedSz); + if (ret != 0) + ret = DRBG_FAILURE; + else + ret = wc_RNG_TestSeed(seed, seedSz); - ForceZero(entropy, entropySz); - FREE_VAR(entropy, rng->heap); + if (ret == DRBG_SUCCESS) + ret = Hash_DRBG_Instantiate(rng->drbg, + seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ, + nonce, nonceSz, rng->heap, devId); + + if (ret == DRBG_SUCCESS) + ret = Hash_DRBG_Generate(rng->drbg, NULL, 0); + } + + ForceZero(seed, seedSz); + FREE_VAR(seed, rng->heap); } else ret = DRBG_CONT_FAILURE; @@ -747,20 +837,24 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) ret = Hash_DRBG_Generate(rng->drbg, output, sz); if (ret == DRBG_NEED_RESEED) { if (wc_RNG_HealthTestLocal(1) == 0) { - byte entropy[ENTROPY_SZ]; + byte newSeed[SEED_SZ + SEED_BLOCK_SZ]; - if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 && - Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ) - == DRBG_SUCCESS) { - - ret = Hash_DRBG_Generate(rng->drbg, NULL, 0); - if (ret == DRBG_SUCCESS) - ret = Hash_DRBG_Generate(rng->drbg, output, sz); - } - else + ret = wc_GenerateSeed(&rng->seed, newSeed, + SEED_SZ + SEED_BLOCK_SZ); + if (ret != 0) ret = DRBG_FAILURE; + else + ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ); - ForceZero(entropy, ENTROPY_SZ); + if (ret == DRBG_SUCCESS) + ret = Hash_DRBG_Reseed(rng->drbg, newSeed + SEED_BLOCK_SZ, + SEED_SZ); + if (ret == DRBG_SUCCESS) + ret = Hash_DRBG_Generate(rng->drbg, NULL, 0); + if (ret == DRBG_SUCCESS) + ret = Hash_DRBG_Generate(rng->drbg, output, sz); + + ForceZero(newSeed, sizeof(newSeed)); } else ret = DRBG_CONT_FAILURE; @@ -822,21 +916,20 @@ int wc_FreeRng(WC_RNG* rng) } #ifdef HAVE_HASHDRBG -int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz, - const byte* entropyB, word32 entropyBSz, +int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz, + const byte* seedB, word32 seedBSz, byte* output, word32 outputSz) { return wc_RNG_HealthTest_ex(reseed, NULL, 0, - entropyA, entropyASz, - entropyB, entropyBSz, + seedA, seedASz, seedB, seedBSz, output, outputSz, NULL, INVALID_DEVID); } int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz, - const byte* entropyA, word32 entropyASz, - const byte* entropyB, word32 entropyBSz, + const byte* seedA, word32 seedASz, + const byte* seedB, word32 seedBSz, byte* output, word32 outputSz, void* heap, int devId) { @@ -846,11 +939,11 @@ int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz, DRBG drbg_var; #endif - if (entropyA == NULL || output == NULL) { + if (seedA == NULL || output == NULL) { return BAD_FUNC_ARG; } - if (reseed != 0 && entropyB == NULL) { + if (reseed != 0 && seedB == NULL) { return BAD_FUNC_ARG; } @@ -867,13 +960,13 @@ int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz, drbg = &drbg_var; #endif - if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, nonce, nonceSz, + if (Hash_DRBG_Instantiate(drbg, seedA, seedASz, nonce, nonceSz, heap, devId) != 0) { goto exit_rng_ht; } if (reseed) { - if (Hash_DRBG_Reseed(drbg, entropyB, entropyBSz) != 0) { + if (Hash_DRBG_Reseed(drbg, seedB, seedBSz) != 0) { goto exit_rng_ht; } } @@ -904,14 +997,14 @@ exit_rng_ht: } -const byte entropyA[] = { +const byte seedA[] = { 0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4, 0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00, 0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f, 0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68 }; -const byte reseedEntropyA[] = { +const byte reseedSeedA[] = { 0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3, 0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22, 0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3 @@ -931,7 +1024,7 @@ const byte outputA[] = { 0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17 }; -const byte entropyB[] = { +const byte seedB[] = { 0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3, 0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19, 0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */ @@ -972,8 +1065,8 @@ static int wc_RNG_HealthTestLocal(int reseed) #endif if (reseed) { - ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA), - reseedEntropyA, sizeof(reseedEntropyA), + ret = wc_RNG_HealthTest(1, seedA, sizeof(seedA), + reseedSeedA, sizeof(reseedSeedA), check, RNG_HEALTH_TEST_CHECK_SIZE); if (ret == 0) { if (ConstantCompare(check, outputA, @@ -982,7 +1075,7 @@ static int wc_RNG_HealthTestLocal(int reseed) } } else { - ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB), + ret = wc_RNG_HealthTest(0, seedB, sizeof(seedB), NULL, 0, check, RNG_HEALTH_TEST_CHECK_SIZE); if (ret == 0) { @@ -992,13 +1085,13 @@ static int wc_RNG_HealthTestLocal(int reseed) } /* The previous test cases use a large seed instead of a seed and nonce. - * entropyB is actually from a test case with a seed and nonce, and + * seedB is actually from a test case with a seed and nonce, and * just concatenates them. The pivot point between seed and nonce is * byte 32, feed them into the health test separately. */ if (ret == 0) { ret = wc_RNG_HealthTest_ex(0, - entropyB + 32, sizeof(entropyB) - 32, - entropyB, 32, + seedB + 32, sizeof(seedB) - 32, + seedB, 32, NULL, 0, check, RNG_HEALTH_TEST_CHECK_SIZE, NULL, INVALID_DEVID); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 51fa46e50..940f232ee 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8276,6 +8276,34 @@ int random_test(void) if ((ret = random_rng_test()) != 0) return ret; + /* Test the seed check function. */ + { + word32 i, outputSz; + + /* Repeat the same byte over and over. Should fail. */ + outputSz = sizeof(output); + XMEMSET(output, 1, outputSz); + ret = wc_RNG_TestSeed(output, outputSz); + if (ret == 0) + return -6404; + + /* Every byte of the entropy scratch is different, + * entropy is a single byte that shouldn't match. */ + outputSz = (sizeof(word32) * 2) + 1; + for (i = 0; i < outputSz; i++) + output[i] = (byte)i; + ret = wc_RNG_TestSeed(output, outputSz); + if (ret != 0) + return -6405; + + outputSz = sizeof(output); + for (i = 0; i < outputSz; i++) + output[i] = (byte)i; + ret = wc_RNG_TestSeed(output, outputSz); + if (ret != 0) + return -6406; + } + return 0; } diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index b95d410d6..03c638e4c 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -205,6 +205,7 @@ WOLFSSL_API int wc_FreeRng(WC_RNG*); #ifdef HAVE_HASHDRBG WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, word32 entropySz); + WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz); WOLFSSL_API int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz, const byte* entropyB, word32 entropyBSz, From 4aa85f956f01bab171ba3522b40f1a2d4a6b7fa0 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 17 Sep 2018 15:55:03 -0700 Subject: [PATCH 2/5] FIPSv2: RNG Update 1. The wolfcrypt test shouldn't check TestSeed() for old FIPS builds. --- wolfcrypt/test/test.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 940f232ee..d9af1b827 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8277,6 +8277,8 @@ int random_test(void) return ret; /* Test the seed check function. */ +#if !defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) { word32 i, outputSz; @@ -8303,7 +8305,7 @@ int random_test(void) if (ret != 0) return -6406; } - +#endif return 0; } From 582cf3182e7dbaea178eabc8357f5c7ac8f2c2c3 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 17 Sep 2018 16:16:57 -0700 Subject: [PATCH 3/5] FIPSv2: RNG Update 1. Update the SEED_BLOCK_SZ to 4 for non-FIPS builds. 2. Change fips-check.sh to skip copying over the random.{c,h} files for now. Need the tagged versions of the other files and the new random for now. --- fips-check.sh | 2 ++ wolfcrypt/src/random.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fips-check.sh b/fips-check.sh index a88f583d2..901053ea5 100755 --- a/fips-check.sh +++ b/fips-check.sh @@ -161,6 +161,8 @@ linuxv2) CRYPT_VERSION=$LINUXV2_CRYPT_VERSION CRYPT_INC_PATH=wolfssl/wolfcrypt CRYPT_SRC_PATH=wolfcrypt/src +# Replace the WC_MODS list for now. Do not want to copy over random.c yet. + WC_MODS=( aes des3 sha sha256 sha512 rsa hmac ) WC_MODS+=( cmac dh ecc ) FIPS_SRCS+=( wolfcrypt_first.c wolfcrypt_last.c ) FIPS_INCS=( fips.h ) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 0dc71be55..597fbb24f 100755 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -225,9 +225,8 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) /* RDSEED outputs in blocks of 64-bits. */ #define SEED_BLOCK_SZ sizeof(word64) #else - /* Setting the default to 2. It is not unreasonable for /dev/random - * or /dev/urandom to return two bytes that are the same. */ - #define SEED_BLOCK_SZ 2 + /* Setting the default to 4. */ + #define SEED_BLOCK_SZ 4 #endif #endif From 8972867ada465a6700ff8ea4105f6afe3d4db43e Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 18 Sep 2018 16:08:35 -0700 Subject: [PATCH 4/5] FIPSv2: RNG Update 1. Updated the IDE/WIN10 user settings to enable RDSEED by default. 2. Updated the Windows GenerateSeed() function to take into account the RDSEED enabled setting. 3. Exclude the TestSeed() function check for the "selftest" build as well as old FIPS. --- IDE/WIN10/user_settings.h | 3 +++ wolfcrypt/src/random.c | 13 +++++++++++++ wolfcrypt/test/test.c | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/IDE/WIN10/user_settings.h b/IDE/WIN10/user_settings.h index 15476f9e2..4b106cf1c 100644 --- a/IDE/WIN10/user_settings.h +++ b/IDE/WIN10/user_settings.h @@ -42,6 +42,9 @@ #define WOLFSSL_VALIDATE_ECC_IMPORT #define WOLFSSL_VALIDATE_FFC_IMPORT #define HAVE_FFDHE_Q + #define WOLFSSL_AESNI + #define HAVE_INTEL_RDSEED + #define FORCE_FAILURE_RDSEED #endif /* FIPS v2 */ #else /* Enables blinding mode, to prevent timing attacks */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 597fbb24f..12ca83a79 100755 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -1442,6 +1442,19 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { + #ifdef HAVE_INTEL_RDSEED + if (IS_INTEL_RDSEED(intel_flags)) { + if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) { + /* success, we're done */ + return 0; + } + #ifdef FORCE_FAILURE_RDSEED + /* don't fall back to CryptoAPI */ + return READ_RAN_E; + #endif + } + #endif /* HAVE_INTEL_RDSEED */ + if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return WINCRYPT_E; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d9af1b827..0995b7663 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8277,7 +8277,7 @@ int random_test(void) return ret; /* Test the seed check function. */ -#if !defined(HAVE_FIPS) || \ +#if !(defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) { word32 i, outputSz; From 951bd5a01a0761af7ba2773a261a677651c41d5c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 19 Sep 2018 07:22:04 -0700 Subject: [PATCH 5/5] FIPSv2: RNG Update 1. Put the SeedTest function in the HASH_DRBG scope. --- wolfcrypt/src/random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 12ca83a79..db1a6edac 100755 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -630,8 +630,6 @@ static int Hash_DRBG_Uninstantiate(DRBG* drbg) return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE; } -#endif /* HAVE_HASHDRBG */ -/* End NIST DRBG Code */ int wc_RNG_TestSeed(const byte* seed, word32 seedSz) @@ -655,6 +653,8 @@ int wc_RNG_TestSeed(const byte* seed, word32 seedSz) return ret; } +#endif /* HAVE_HASHDRBG */ +/* End NIST DRBG Code */ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,