Skip to content

Commit 9ee66b7

Browse files
committed
wolfcrypt/src/wolfentropy.c: add volatile attribute to entropy_memuse_initialized declaration; in wc_Entropy_Get(), if HAVE_FIPS, call Entropy_Init() if necessary, to accommodate FIPS KATs; in Entropy_Init(), add thread safety.
1 parent 6f95a9c commit 9ee66b7

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

wolfcrypt/src/wolfentropy.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ data, use this implementation to seed and re-seed the DRBG.
5858
#define MAX_NOISE_CNT (MAX_ENTROPY_BITS * 8 + ENTROPY_EXTRA)
5959

6060
/* MemUse entropy global state initialized. */
61-
static int entropy_memuse_initialized = 0;
61+
static volatile int entropy_memuse_initialized = 0;
6262
/* Global SHA-3 object used for conditioning entropy and creating noise. */
6363
static wc_Sha3 entropyHash;
6464
/* Reset the health tests. */
@@ -740,6 +740,21 @@ int wc_Entropy_Get(int bits, unsigned char* entropy, word32 len)
740740
int noise_len = (bits + ENTROPY_EXTRA) / ENTROPY_MIN;
741741
static byte noise[MAX_NOISE_CNT];
742742

743+
#ifdef HAVE_FIPS
744+
/* FIPS KATs, e.g. EccPrimitiveZ_KnownAnswerTest(), call wc_Entropy_Get()
745+
* incidental to wc_InitRng(), without first calling Entropy_Init(), neither
746+
* directly, nor indirectly via wolfCrypt_Init(). This matters, because
747+
* KATs must be usable before wolfCrypt_Init() (indeed, in the library
748+
* embodiment, the HMAC KAT always runs before wolfCrypt_Init(), incidental
749+
* to fipsEntry()). Without the InitSha3() under Entropy_Init(), the
750+
* SHA3_BLOCK function pointer is null when Sha3Update() is called by
751+
* Entropy_MemUse(), which ends badly.
752+
*/
753+
if (!entropy_memuse_initialized) {
754+
ret = Entropy_Init();
755+
}
756+
#endif
757+
743758
/* Lock the mutex as collection uses globals. */
744759
if ((ret == 0) && (wc_LockMutex(&entropy_mutex) != 0)) {
745760
ret = BAD_MUTEX_E;
@@ -851,6 +866,17 @@ int Entropy_Init(void)
851866
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
852867
ret = wc_InitMutex(&entropy_mutex);
853868
#endif
869+
ret = wc_LockMutex(&entropy_mutex);
870+
871+
if (entropy_memuse_initialized) {
872+
/* Short circuit return -- a competing thread initialized the state
873+
* while we were waiting. Note, this is only threadsafe when
874+
* WOLFSSL_MUTEX_INITIALIZER is defined.
875+
*/
876+
wc_UnLockMutex(&entropy_mutex);
877+
return 0;
878+
}
879+
854880
if (ret == 0) {
855881
/* Initialize a SHA3-256 object for use in entropy operations. */
856882
ret = wc_InitSha3_256(&entropyHash, NULL, INVALID_DEVID);
@@ -872,6 +898,10 @@ int Entropy_Init(void)
872898
Entropy_StopThread();
873899
#endif
874900
}
901+
902+
if (ret != WC_NO_ERR_TRACE(BAD_MUTEX_E)) {
903+
wc_UnLockMutex(&entropy_mutex);
904+
}
875905
}
876906

877907
return ret;

0 commit comments

Comments
 (0)