Commit c43dc3dd authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Avoid multiple locks in FIPS mode.

PR: 3176.

In FIPS mode ssleay_rand_bytes is only used for PRNG seeding and is
performed in either a single threaded context (when the PRNG is first
initialised) or under a lock (reseeding). To avoid multiple locks disable
use of CRYPTO_LOCK_RAND in FIPS mode in ssleay_rand_bytes.
parent e5eab8a1
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -380,7 +380,10 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
	 * are fed into the hash function and the results are kept in the
	 * global 'md'.
	 */

#ifdef OPENSSL_FIPS
	/* NB: in FIPS mode we are already under a lock */
	if (FIPS_mode())
#endif
		CRYPTO_w_lock(CRYPTO_LOCK_RAND);

	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
@@ -460,6 +463,9 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)

	/* before unlocking, we must clear 'crypto_lock_rand' */
	crypto_lock_rand = 0;
#ifdef OPENSSL_FIPS
	if (FIPS_mode())
#endif
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	while (num > 0)
@@ -512,9 +518,15 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
	MD_Init(&m);
	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
#ifdef OPENSSL_FIPS
	if (FIPS_mode())
#endif
		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
	MD_Update(&m,md,MD_DIGEST_LENGTH);
	MD_Final(&m,md);
#ifdef OPENSSL_FIPS
	if (FIPS_mode())
#endif
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	EVP_MD_CTX_cleanup(&m);