summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2014-07-30 15:13:08 +0100
committerDr. Stephen Henson <steve@openssl.org>2014-07-30 21:09:20 +0100
commit2a9023f7b4e5198e5950269088133526d617544a (patch)
tree5c8840ac350b199e2c9c1f998001eee3a2a31208
parent36e8c3989955aaea06487575a9ed7ce7b8a4bcaa (diff)
downloadopenssl-new-2a9023f7b4e5198e5950269088133526d617544a.tar.gz
Avoid multiple lock using FIPS DRBG.
Don't use multiple locks when SP800-90 DRBG is used outside FIPS mode. PR#3176 Reviewed-by: Rich Salz <rsalz@openssl.org> (cherry picked from commit a3efe1b6e9d2aa2ce5661e4d4b97262eae743fa7)
-rw-r--r--crypto/rand/md_rand.c22
-rw-r--r--crypto/rand/rand_lcl.h1
-rw-r--r--crypto/rand/rand_lib.c3
3 files changed, 12 insertions, 14 deletions
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index aee1c30b0a..5dd0a37d65 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -336,6 +336,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;
int num_ceil;
@@ -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);
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index 618a8ec899..725cdb31c2 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -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
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 5ac0e14caf..54f1d35c6c 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -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;