Here is a better patch. The previous one caused problems for
applications that called RAND_bytes() (usually indirectly) before
any other RAND function -- like, say, the OpenSSH client.
Thor
Index: crypto/rand/md_rand.c
===================================================================
RCS file: /cvsroot/src/crypto/external/bsd/openssl/dist/crypto/rand/md_rand.c,v
retrieving revision 1.1.1.3
retrieving revision 1.3
diff -u -r1.1.1.3 -r1.3
--- crypto/rand/md_rand.c 5 Jun 2011 14:59:27 -0000 1.1.1.3
+++ crypto/rand/md_rand.c 7 Mar 2012 10:17:47 -0000 1.3
@@ -141,7 +141,6 @@
static unsigned char md[MD_DIGEST_LENGTH];
static long md_count[2]={0,0};
static double entropy=0;
-static int initialized=0;
static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
* holds CRYPTO_LOCK_RAND
@@ -187,7 +186,6 @@
md_count[0]=0;
md_count[1]=0;
entropy=0;
- initialized=0;
}
static void ssleay_rand_add(const void *buf, int num, double add)
@@ -389,18 +387,16 @@
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
- if (!initialized)
- {
- RAND_poll();
- initialized = 1;
- }
-
if (!stirred_pool)
do_stir_pool = 1;
ok = (entropy >= ENTROPY_NEEDED);
if (!ok)
{
+
+ RAND_poll();
+ ok = (entropy >= ENTROPY_NEEDED);
+
/* If the PRNG state is not yet unpredictable, then seeing
* the PRNG output may help attackers to determine the new
* state; thus we have to decrease the entropy estimate.
@@ -571,11 +567,10 @@
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1;
}
-
- if (!initialized)
+
+ if (entropy < ENTROPY_NEEDED)
{
RAND_poll();
- initialized = 1;
}
ret = entropy >= ENTROPY_NEEDED;
Index: crypto/rand/rand_unix.c
===================================================================
RCS file:
/cvsroot/src/crypto/external/bsd/openssl/dist/crypto/rand/rand_unix.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- crypto/rand/rand_unix.c 19 Jul 2009 23:30:41 -0000 1.2
+++ crypto/rand/rand_unix.c 5 Mar 2012 20:13:36 -0000 1.3
@@ -182,6 +182,16 @@
u_int32_t rnd = 0, i;
unsigned char buf[ENTROPY_NEEDED];
+ /*
+ * XXX is this really a good idea? It has the seemingly
+ * XXX very undesirable eventual result of keying the CTR_DRBG
+ * XXX generator exclusively with key material produced by
+ * XXX the libc arc4random(). It also guarantees that even
+ * XXX if the generator tries to use RAND_poll() to rekey
+ * XXX itself after a call to fork() etc, it will end up with
+ * XXX the same state, since the libc arc4 state will be the same
+ * XXX unless explicitly updated by the application.
+ */
for (i = 0; i < sizeof(buf); i++) {
if (i % 4 == 0)
rnd = arc4random();