Index: asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/random.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/random.c	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/random.c	(revision 372)
@@ -26,4 +26,5 @@
 
 #include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
 
 /* on HPUX 11 you may need to install /dev/random see
@@ -32,9 +33,25 @@
 */
 
+#if defined(HAVE_FIPS) && \
+	defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
+
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+
+    #ifdef USE_WINDOWS_API
+        #pragma code_seg(".fipsA$c")
+        #pragma const_seg(".fipsB$c")
+    #endif
+#endif
+
+
 #include <wolfssl/wolfcrypt/random.h>
 #include <wolfssl/wolfcrypt/cpuid.h>
 
 
-#ifdef HAVE_FIPS
+/* If building for old FIPS. */
+#if defined(HAVE_FIPS) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
+
 int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
 {
@@ -73,19 +90,17 @@
     }
 
-    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 RNG_HealthTest_fips(reseed, entropyA, entropyASz,
-                              entropyB, entropyBSz, output, outputSz);
+        return RNG_HealthTest_fips(reseed, seedA, seedASz,
+                              seedB, seedBSz, output, outputSz);
     }
 #endif /* HAVE_HASHDRBG */
 
-#else /* else build without fips */
+#else /* else build without fips, or for new fips */
 
 #ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */
 
-#include <wolfssl/wolfcrypt/error-crypt.h>
 #include <wolfssl/wolfcrypt/sha256.h>
 
@@ -127,4 +142,6 @@
 #elif defined(WOLFSSL_EMBOS)
 #elif defined(MICRIUM)
+#elif defined(WOLFSSL_NUCLEUS)
+#elif defined(WOLFSSL_PB)
 #else
     /* include headers that may be needed to get good seed */
@@ -148,4 +165,8 @@
     static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz);
     #endif
+
+#ifdef USE_WINDOWS_API
+    #include <immintrin.h>
+#endif /* USE_WINDOWS_API */
 #endif
 
@@ -156,15 +177,72 @@
 #define MAX_REQUEST_LEN   (0x10000)
 #define RESEED_INTERVAL   WC_RESEED_INTERVAL
-#define SECURITY_STRENGTH (256)
-#define ENTROPY_SZ        (SECURITY_STRENGTH/8)
-#define NONCE_SZ          (ENTROPY_SZ/2)
-#define ENTROPY_NONCE_SZ  (ENTROPY_SZ+NONCE_SZ)
+
+
+/* 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 4. */
+        #define SEED_BLOCK_SZ 4
+    #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
-#define DRBG_ERROR        1
-#define DRBG_FAILURE      2
-#define DRBG_NEED_RESEED  3
-#define DRBG_CONT_FAILURE 4
+#define DRBG_FAILURE      1
+#define DRBG_NEED_RESEED  2
+#define DRBG_CONT_FAILURE 3
 
 /* RNG health states */
@@ -200,4 +278,7 @@
 #endif
     byte   matchCount;
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+    wc_Sha256 sha256;
+#endif
 } DRBG;
 
@@ -216,9 +297,17 @@
     int len;
     word32 bits = (outSz * 8); /* reverse byte order */
-    wc_Sha256 sha;
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+    wc_Sha256* sha = &drbg->sha256;
+#else
+    wc_Sha256 sha[1];
+#endif
+#ifdef WC_ASYNC_ENABLE_SHA256
     DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
+#else
+    byte digest[WC_SHA256_DIGEST_SIZE];
+#endif
 
     (void)drbg;
-#ifdef WOLFSSL_ASYNC_CRYPT
+#ifdef WC_ASYNC_ENABLE_SHA256
     if (digest == NULL)
         return DRBG_FAILURE;
@@ -232,8 +321,9 @@
 
     for (i = 0, ctr = 1; i < len; i++, ctr++) {
+#ifndef WOLFSSL_SMALL_STACK_CACHE
     #ifdef WOLFSSL_ASYNC_CRYPT
-        ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
+        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
     #else
-        ret = wc_InitSha256(&sha);
+        ret = wc_InitSha256(sha);
     #endif
         if (ret != 0)
@@ -241,23 +331,26 @@
 
         if (ret == 0)
-            ret = wc_Sha256Update(&sha, &ctr, sizeof(ctr));
+#endif
+            ret = wc_Sha256Update(sha, &ctr, sizeof(ctr));
         if (ret == 0)
-            ret = wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits));
+            ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits));
 
         if (ret == 0) {
             /* churning V is the only string that doesn't have the type added */
             if (type != drbgInitV)
-                ret = wc_Sha256Update(&sha, &type, sizeof(type));
+                ret = wc_Sha256Update(sha, &type, sizeof(type));
         }
         if (ret == 0)
-            ret = wc_Sha256Update(&sha, inA, inASz);
+            ret = wc_Sha256Update(sha, inA, inASz);
         if (ret == 0) {
             if (inB != NULL && inBSz > 0)
-                ret = wc_Sha256Update(&sha, inB, inBSz);
+                ret = wc_Sha256Update(sha, inB, inBSz);
         }
         if (ret == 0)
-            ret = wc_Sha256Final(&sha, digest);
-
-        wc_Sha256Free(&sha);
+            ret = wc_Sha256Final(sha, digest);
+
+#ifndef WOLFSSL_SMALL_STACK_CACHE
+        wc_Sha256Free(sha);
+#endif
         if (ret == 0) {
             if (outSz > OUTPUT_BLOCK_LEN) {
@@ -274,5 +367,7 @@
     ForceZero(digest, WC_SHA256_DIGEST_SIZE);
 
+#ifdef WC_ASYNC_ENABLE_SHA256
     FREE_VAR(digest, drbg->heap);
+#endif
 
     return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
@@ -280,15 +375,17 @@
 
 /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
-static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
-{
-    byte seed[DRBG_SEED_LEN];
-
-    if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
-                                          entropy, entropySz) != DRBG_SUCCESS) {
+static int Hash_DRBG_Reseed(DRBG* drbg, const byte* seed, word32 seedSz)
+{
+    byte newV[DRBG_SEED_LEN];
+
+    XMEMSET(newV, 0, DRBG_SEED_LEN);
+
+    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,
@@ -303,5 +400,15 @@
 }
 
-static INLINE void array_add_one(byte* data, word32 dataSz)
+/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
+int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz)
+{
+    if (rng == NULL || seed == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return Hash_DRBG_Reseed(rng->drbg, seed, seedSz);
+}
+
+static WC_INLINE void array_add_one(byte* data, word32 dataSz)
 {
     int i;
@@ -322,6 +429,14 @@
     int len;
     word32 checkBlock;
-    wc_Sha256 sha;
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+    wc_Sha256* sha = &drbg->sha256;
+#else
+    wc_Sha256 sha[1];
+#endif
+#ifdef WC_ASYNC_ENABLE_SHA256
     DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
+#else
+    byte digest[WC_SHA256_DIGEST_SIZE];
+#endif
 
     /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
@@ -334,14 +449,18 @@
     XMEMCPY(data, V, sizeof(data));
     for (i = 0; i < len; i++) {
+#ifndef WOLFSSL_SMALL_STACK_CACHE
     #ifdef WOLFSSL_ASYNC_CRYPT
-        ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
+        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
     #else
-        ret = wc_InitSha256(&sha);
+        ret = wc_InitSha256(sha);
     #endif
         if (ret == 0)
-            ret = wc_Sha256Update(&sha, data, sizeof(data));
+#endif
+            ret = wc_Sha256Update(sha, data, sizeof(data));
         if (ret == 0)
-            ret = wc_Sha256Final(&sha, digest);
-        wc_Sha256Free(&sha);
+            ret = wc_Sha256Final(sha, digest);
+#ifndef WOLFSSL_SMALL_STACK_CACHE
+        wc_Sha256Free(sha);
+#endif
 
         if (ret == 0) {
@@ -379,10 +498,12 @@
     ForceZero(data, sizeof(data));
 
+#ifdef WC_ASYNC_ENABLE_SHA256
     FREE_VAR(digest, drbg->heap);
+#endif
 
     return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
 }
 
-static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
+static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
 {
     word16 carry = 0;
@@ -410,5 +531,9 @@
 {
     int ret;
-    wc_Sha256 sha;
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+    wc_Sha256* sha = &drbg->sha256;
+#else
+    wc_Sha256 sha[1];
+#endif
     byte type;
     word32 reseedCtr;
@@ -417,5 +542,9 @@
         return DRBG_NEED_RESEED;
     } else {
+    #ifdef WC_ASYNC_ENABLE_SHA256
         DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
+    #else
+        byte digest[WC_SHA256_DIGEST_SIZE];
+    #endif
         type = drbgGenerateH;
         reseedCtr = drbg->reseedCtr;
@@ -423,17 +552,21 @@
         ret = Hash_gen(drbg, out, outSz, drbg->V);
         if (ret == DRBG_SUCCESS) {
+#ifndef WOLFSSL_SMALL_STACK_CACHE
         #ifdef WOLFSSL_ASYNC_CRYPT
-            ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
+            ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
         #else
-            ret = wc_InitSha256(&sha);
+            ret = wc_InitSha256(sha);
         #endif
             if (ret == 0)
-                ret = wc_Sha256Update(&sha, &type, sizeof(type));
+#endif
+                ret = wc_Sha256Update(sha, &type, sizeof(type));
             if (ret == 0)
-                ret = wc_Sha256Update(&sha, drbg->V, sizeof(drbg->V));
+                ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V));
             if (ret == 0)
-                ret = wc_Sha256Final(&sha, digest);
-
-            wc_Sha256Free(&sha);
+                ret = wc_Sha256Final(sha, digest);
+
+#ifndef WOLFSSL_SMALL_STACK_CACHE
+            wc_Sha256Free(sha);
+#endif
 
             if (ret == 0) {
@@ -450,5 +583,7 @@
         }
         ForceZero(digest, WC_SHA256_DIGEST_SIZE);
+    #ifdef WC_ASYNC_ENABLE_SHA256
         FREE_VAR(digest, drbg->heap);
+    #endif
     }
 
@@ -472,4 +607,14 @@
 #endif
 
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId);
+    #else
+        ret = wc_InitSha256(&drbg->sha256);
+    #endif
+    if (ret != 0)
+        return ret;
+#endif
+
     if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
                                               nonce, nonceSz) == DRBG_SUCCESS &&
@@ -493,4 +638,8 @@
     byte*  compareDrbg = (byte*)drbg;
 
+#ifdef WOLFSSL_SMALL_STACK_CACHE
+    wc_Sha256Free(&drbg->sha256);
+#endif
+
     ForceZero(drbg, sizeof(DRBG));
 
@@ -500,13 +649,45 @@
     return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
 }
+
+
+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;
+}
 #endif /* HAVE_HASHDRBG */
 /* End NIST DRBG Code */
 
 
-int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
+static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
+                    void* heap, int devId)
 {
     int ret = RNG_FAILURE_E;
+#ifdef HAVE_HASHDRBG
+    word32 seedSz = SEED_SZ + SEED_BLOCK_SZ;
+#endif
+
+    (void)nonce;
+    (void)nonceSz;
 
     if (rng == NULL)
+        return BAD_FUNC_ARG;
+    if (nonce == NULL && nonceSz != 0)
         return BAD_FUNC_ARG;
 
@@ -552,6 +733,13 @@
 #else
 #ifdef HAVE_HASHDRBG
+    if (nonceSz == 0)
+        seedSz = MAX_SEED_SZ;
+
     if (wc_RNG_HealthTestLocal(0) == 0) {
-        DECLARE_VAR(entropy, byte, ENTROPY_NONCE_SZ, rng->heap);
+    #ifdef WC_ASYNC_ENABLE_SHA256
+        DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap);
+    #else
+        byte seed[MAX_SEED_SZ];
+    #endif
 
         rng->drbg =
@@ -561,17 +749,24 @@
             ret = MEMORY_E;
         }
-        /* This doesn't use a separate nonce. The entropy input will be
-         * the default size plus the size of the nonce making the seed
-         * size. */
-        else if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
-                 Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ,
-                                   NULL, 0, rng->heap, devId) == DRBG_SUCCESS) {
+        else {
+            ret = wc_GenerateSeed(&rng->seed, seed, seedSz);
+            if (ret != 0)
+                ret = DRBG_FAILURE;
+            else
+                ret = wc_RNG_TestSeed(seed, seedSz);
+
+            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);
         }
-        else
-            ret = DRBG_FAILURE;
-
-        ForceZero(entropy, ENTROPY_NONCE_SZ);
-        FREE_VAR(entropy, rng->heap);
+
+        ForceZero(seed, seedSz);
+    #ifdef WC_ASYNC_ENABLE_SHA256
+        FREE_VAR(seed, rng->heap);
+    #endif
     }
     else
@@ -599,7 +794,27 @@
 }
 
+
 int wc_InitRng(WC_RNG* rng)
 {
-    return wc_InitRng_ex(rng, NULL, INVALID_DEVID);
+    return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID);
+}
+
+
+int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
+{
+    return _InitRng(rng, NULL, 0, heap, devId);
+}
+
+
+int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz)
+{
+    return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID);
+}
+
+
+int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,
+                       void* heap, int devId)
+{
+    return _InitRng(rng, nonce, nonceSz, heap, devId);
 }
 
@@ -623,5 +838,5 @@
     #ifdef HAVE_CAVIUM
         return NitroxRngGenerateBlock(rng, output, sz);
-    #elif defined(HAVE_INTEL_QA)
+    #elif defined(HAVE_INTEL_QA) && defined(QAT_ENABLE_RNG)
         return IntelQaDrbg(&rng->asyncDev, output, sz);
     #else
@@ -646,18 +861,22 @@
     if (ret == DRBG_NEED_RESEED) {
         if (wc_RNG_HealthTestLocal(1) == 0) {
-            byte entropy[ENTROPY_SZ];
-
-            if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
-                Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
-                                                              == DRBG_SUCCESS) {
-
+            byte newSeed[SEED_SZ + SEED_BLOCK_SZ];
+
+            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);
+
+            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);
-            }
-            else
-                ret = DRBG_FAILURE;
-
-            ForceZero(entropy, ENTROPY_SZ);
+
+            ForceZero(newSeed, sizeof(newSeed));
         }
         else
@@ -721,7 +940,20 @@
 
 #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,
+                                seedA, seedASz, seedB, seedBSz,
+                                output, outputSz,
+                                NULL, INVALID_DEVID);
+}
+
+
+int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
+                                  const byte* seedA, word32 seedASz,
+                                  const byte* seedB, word32 seedBSz,
+                                  byte* output, word32 outputSz,
+                                  void* heap, int devId)
 {
     int ret = -1;
@@ -731,9 +963,9 @@
 #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;
     }
@@ -744,5 +976,5 @@
 
 #ifdef WOLFSSL_SMALL_STACK
-    drbg = (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
+    drbg = (DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
     if (drbg == NULL) {
         return MEMORY_E;
@@ -752,11 +984,11 @@
 #endif
 
-    if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, NULL, 0, NULL,
-                                                    INVALID_DEVID) != 0) {
+    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;
         }
@@ -789,5 +1021,5 @@
 
 
-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,
@@ -796,5 +1028,5 @@
 };
 
-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,
@@ -816,9 +1048,10 @@
 };
 
-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, 0x85, 0x81, 0xf9, 0x31,
-    0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
+    0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */
+    0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d,
+    0xdb, 0xcb, 0xcc, 0x2e
 };
 
@@ -856,6 +1089,6 @@
 
     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) {
@@ -866,5 +1099,5 @@
     }
     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);
@@ -873,4 +1106,21 @@
                                 RNG_HEALTH_TEST_CHECK_SIZE) != 0)
                 ret = -1;
+        }
+
+        /* The previous test cases use a large seed instead of a seed and nonce.
+         * 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,
+                                    seedB + 32, sizeof(seedB) - 32,
+                                    seedB, 32,
+                                    NULL, 0,
+                                    check, RNG_HEALTH_TEST_CHECK_SIZE,
+                                    NULL, INVALID_DEVID);
+            if (ret == 0) {
+                if (ConstantCompare(check, outputB, sizeof(outputB)) != 0)
+                    ret = -1;
+            }
         }
     }
@@ -995,6 +1245,8 @@
 #ifdef HAVE_INTEL_RDSEED
 
+#ifndef USE_WINDOWS_API
+
 /* return 0 on success */
-static INLINE int IntelRDseed64(word64* seed)
+    static WC_INLINE int IntelRDseed64(word64* seed)
 {
     unsigned char ok;
@@ -1004,6 +1256,21 @@
 }
 
+#else /* USE_WINDOWS_API */
+    /* The compiler Visual Studio uses does not allow inline assembly.
+     * It does allow for Intel intrinsic functions. */
+
 /* return 0 on success */
-static INLINE int IntelRDseed64_r(word64* rnd)
+    static WC_INLINE int IntelRDseed64(word64* seed)
+    {
+        int ok;
+
+        ok = _rdseed64_step(seed);
+        return (ok) ? 0 : -1;
+    }
+
+#endif /* USE_WINDOWS_API */
+
+/* return 0 on success */
+static WC_INLINE int IntelRDseed64_r(word64* rnd)
 {
     int i;
@@ -1041,4 +1308,5 @@
 
     XMEMCPY(output, &rndTmp, sz);
+    ForceZero(&rndTmp, sizeof(rndTmp));
 
     return 0;
@@ -1049,6 +1317,8 @@
 #ifdef HAVE_INTEL_RDRAND
 
+#ifndef USE_WINDOWS_API
+
 /* return 0 on success */
-static INLINE int IntelRDrand64(word64 *rnd)
+static WC_INLINE int IntelRDrand64(word64 *rnd)
 {
     unsigned char ok;
@@ -1059,6 +1329,22 @@
 }
 
+#else /* USE_WINDOWS_API */
+    /* The compiler Visual Studio uses does not allow inline assembly.
+     * It does allow for Intel intrinsic functions. */
+
 /* return 0 on success */
-static INLINE int IntelRDrand64_r(word64 *rnd)
+static WC_INLINE int IntelRDrand64(word64 *rnd)
+{
+    int ok;
+
+    ok = _rdrand64_step(rnd);
+
+    return (ok) ? 0 : -1;
+}
+
+#endif /* USE_WINDOWS_API */
+
+/* return 0 on success */
+static WC_INLINE int IntelRDrand64_r(word64 *rnd)
 {
     int i;
@@ -1182,4 +1468,17 @@
 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))
@@ -1302,5 +1601,5 @@
         int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
         {
-            int i;
+            word32 i;
 
             /* turn on RNGA module */
@@ -1418,6 +1717,5 @@
 
 #elif defined(STM32_RNG)
-    /*
-     * wc_Generate a RNG seed using the hardware random number generator
+     /* Generate a RNG seed using the hardware random number generator
      * on the STM32F2/F4/F7. */
 
@@ -1443,5 +1741,43 @@
         return 0;
     }
+    #elif defined(WOLFSSL_STM32F427_RNG)
+
+    /* Generate a RNG seed using the hardware RNG on the STM32F427
+     * directly, following steps outlined in STM32F4 Reference
+     * Manual (Chapter 24) for STM32F4xx family. */
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        int i;
+        (void)os;
+
+        /* enable RNG peripheral clock */
+        RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
+
+        /* enable RNG interrupt, set IE bit in RNG->CR register */
+        RNG->CR |= RNG_CR_IE;
+
+        /* enable RNG, set RNGEN bit in RNG->CR. Activates RNG,
+         * RNG_LFSR, and error detector */
+        RNG->CR |= RNG_CR_RNGEN;
+
+        /* verify no errors, make sure SEIS and CEIS bits are 0
+         * in RNG->SR register */
+        if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS))
+            return RNG_FAILURE_E;
+
+        for (i = 0; i < (int)sz; i++) {
+            /* wait until RNG number is ready */
+            while ((RNG->SR & RNG_SR_DRDY) == 0) { }
+
+            /* get value */
+            output[i] = RNG->DR;
+        }
+
+        return 0;
+    }
+
     #else
+
+    /* Generate a RNG seed using the STM32 Standard Peripheral Library */
     int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
     {
@@ -1493,4 +1829,36 @@
     }
 
+#elif defined(WOLFSSL_PB)
+
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        word32 i;
+        for (i = 0; i < sz; i++)
+            output[i] = UTL_Rand();
+
+        (void)os;
+
+        return 0;
+    }
+
+#elif defined(WOLFSSL_NUCLEUS)
+#include "nucleus.h"
+#include "kernel/plus_common.h"
+
+#warning "potential for not enough entropy, currently being used for testing"
+int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+    int i;
+    srand(NU_Get_Time_Stamp());
+
+    for (i = 0; i < sz; i++ ) {
+        output[i] = rand() % 256;
+        if ((i % 8) == 7) {
+            srand(NU_Get_Time_Stamp());
+        }
+    }
+
+    return 0;
+}
 #elif defined(WOLFSSL_VXWORKS)
 
@@ -1630,4 +1998,84 @@
     }
 
+#elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG))
+
+    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
+    #include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
+
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        Buffer buf[1];
+        int ret  = 0;
+        int times = 1000, i;
+
+        (void)os;
+
+        if (output == NULL) {
+            return BUFFER_E;
+        }
+
+        buf[0].BufferType = DataBuffer | LastBuffer;
+        buf[0].TheAddress = (Address)output;
+        buf[0].Length     = sz;
+
+        /* Check Waiting to make sure entropy is ready */
+        for (i = 0; i < times; i++) {
+            ret = wc_caamAddAndWait(buf, NULL, CAAM_ENTROPY);
+            if (ret == Success) {
+                break;
+            }
+
+            /* driver could be waiting for entropy */
+            if (ret != RAN_BLOCK_E) {
+                return ret;
+            }
+            usleep(100);
+        }
+
+        if (i == times && ret != Success) {
+             return RNG_FAILURE_E;
+        }
+        else { /* Success case */
+            ret = 0;
+        }
+
+        return ret;
+    }
+
+#elif defined(WOLFSSL_APACHE_MYNEWT)
+
+    #include <stdlib.h>
+    #include "os/os_time.h"
+    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+    {
+        int i;
+        srand(os_time_get());
+
+        for (i = 0; i < sz; i++ ) {
+            output[i] = rand() % 256;
+            if ((i % 8) == 7) {
+                srand(os_time_get());
+            }
+        }
+
+        return 0;
+    }
+
+#elif defined(WOLFSSL_ESPIDF)
+    #if defined(WOLFSSL_ESPWROOM32)
+        #include <esp_system.h>
+        
+        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+        {
+            int i;
+            
+            for (i = 0; i< sz; i++) {
+               output[i] =  esp_random( );
+            }
+        
+            return 0;
+        }
+    #endif /* end WOLFSSL_ESPWROOM32 */
+ 
 #elif defined(CUSTOM_RAND_GENERATE_BLOCK)
     /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc
@@ -1640,5 +2088,6 @@
       defined(WOLFSSL_LPC43xx)  || defined(WOLFSSL_STM32F2xx) || \
       defined(MBED)             || defined(WOLFSSL_EMBOS) || \
-      defined(WOLFSSL_GENSEED_FORTEST)
+      defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS) || \
+      defined(WOLFSSL_CONTIKI)
 
     /* these platforms do not have a default random seed and
@@ -1677,13 +2126,15 @@
              return ret;
     #else
-             /* fallback to /dev/urandom attempt */
+             /* reset error and fallback to using /dev/urandom */
              ret = 0;
     #endif
         }
-
     #endif /* HAVE_INTEL_RDSEED */
 
+    #ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */
         os->fd = open("/dev/urandom",O_RDONLY);
-        if (os->fd == -1) {
+        if (os->fd == -1)
+    #endif
+        {
             /* may still have /dev/random */
             os->fd = open("/dev/random",O_RDONLY);
@@ -1703,5 +2154,5 @@
 
             if (sz) {
-    #ifdef BLOCKING
+    #if defined(BLOCKING) || defined(WC_RNG_BLOCKING)
                 sleep(0);             /* context switch */
     #else
@@ -1738,5 +2189,4 @@
 
 /* End wc_GenerateSeed */
-
 #endif /* WC_NO_RNG */
 #endif /* HAVE_FIPS */
