From c43dc3dd77c48898104dfca06793f6836805e7eb Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 4 Dec 2013 13:39:04 +0000 Subject: [PATCH] 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. --- crypto/rand/md_rand.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index 1e3bcb9bc4..2dd22d2beb 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -380,8 +380,11 @@ 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'. */ - - CRYPTO_w_lock(CRYPTO_LOCK_RAND); +#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 */ CRYPTO_w_lock(CRYPTO_LOCK_RAND2); @@ -460,7 +463,10 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo) /* before unlocking, we must clear 'crypto_lock_rand' */ crypto_lock_rand = 0; - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); +#ifdef OPENSSL_FIPS + if (FIPS_mode()) +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); while (num > 0) { @@ -512,10 +518,16 @@ 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); - CRYPTO_w_lock(CRYPTO_LOCK_RAND); +#ifdef OPENSSL_FIPS + if (FIPS_mode()) +#endif + CRYPTO_w_lock(CRYPTO_LOCK_RAND); MD_Update(&m,md,MD_DIGEST_LENGTH); MD_Final(&m,md); - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); +#ifdef OPENSSL_FIPS + if (FIPS_mode()) +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); EVP_MD_CTX_cleanup(&m); if (ok) -- 2.25.1