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

Avoid multiple lock using FIPS DRBG.



Don't use multiple locks when SP800-90 DRBG is used outside FIPS mode.

PR#3176
Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent 789b1259
Loading
Loading
Loading
Loading
+9 −13
Original line number Diff line number Diff line
@@ -335,6 +335,11 @@ static void ssleay_rand_seed(const void *buf, int num)
	}

static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
	{
	return md_rand_bytes_lock(buf, num, pseudo, 1);
	}

int md_rand_bytes_lock(unsigned char *buf, int num, int pseudo, int lock)
	{
	static volatile int stirred_pool = 0;
	int i,j,k,st_num,st_idx;
@@ -383,10 +388,7 @@ 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
	if (lock)
		CRYPTO_w_lock(CRYPTO_LOCK_RAND);

	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
@@ -466,9 +468,7 @@ 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
	if (lock)
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	while (num > 0)
@@ -521,15 +521,11 @@ 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
	if (lock)
		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
	MD_Update(&m,md,MD_DIGEST_LENGTH);
	MD_Final(&m,md);
#ifdef OPENSSL_FIPS
	if (!FIPS_mode())
#endif
	if (lock)
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	EVP_MD_CTX_cleanup(&m);
+1 −0
Original line number Diff line number Diff line
@@ -154,5 +154,6 @@
#define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
#endif

int md_rand_bytes_lock(unsigned char *buf, int num, int pseudo, int lock);

#endif
+2 −1
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#include <openssl/fips_rand.h>
#include "rand_lcl.h"
#endif

#ifndef OPENSSL_NO_ENGINE
@@ -199,7 +200,7 @@ static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
	*pout = OPENSSL_malloc(min_len);
	if (!*pout)
		return 0;
	if (RAND_SSLeay()->bytes(*pout, min_len) <= 0)
	if (md_rand_bytes_lock(*pout, min_len, 0, 0) <= 0)
		{
		OPENSSL_free(*pout);
		*pout = NULL;