On 01/16/2014 03:42 PM, Florian Weimer wrote:
On 01/16/2014 03:39 PM, Florian Weimer wrote:

I still propose to get rid of the time() call (md_rand-time.patch,
AFAICT num == 0 at this point, so I pulled the initialization out of the
loop).

Disregard the patches, this doesn't work.

These patches should be better. Overall, things are still the same: the first patch removes the call to time(), and the second patch uses OPENSSL_rdtsc() as a fallback if RDRAND is not available.

I don't know what kinds of changes are acceptable to the FIPS PRNG.

--
Florian Weimer / Red Hat Product Security Team
>From 562e65769d3a0a228addf0c3ceb11322671fe719 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fwei...@redhat.com>
Date: Thu, 16 Jan 2014 15:50:12 +0100
Subject: [PATCH 1/2] ssleay_rand_seed: optimize fork protection: do not call
 time()

---
 crypto/rand/md_rand.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 6cab308..c7c0f2c 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -368,7 +368,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
 #ifndef GETPID_IS_MEANINGLESS
 	pid_t curr_pid = getpid();
 #endif
-	time_t curr_time = time(NULL);
+	int do_diverge = 1;
 	int do_stir_pool = 0;
 /* time value for various platforms */
 #ifdef OPENSSL_SYS_WIN32
@@ -515,26 +515,23 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
 		num-=j;
 		if (!MD_Init(&m))
 			goto err;
-#ifndef GETPID_IS_MEANINGLESS
-		if (curr_pid) /* just in the first iteration to save time */
+
+		if (do_diverge) /* just in the first iteration to save time */
 			{
+			/* try to diverge the random sequence after
+			   fork and VM resumption */
+#ifndef GETPID_IS_MEANINGLESS
 			if (!MD_Update(&m,(unsigned char*)&curr_pid,
 				       sizeof curr_pid))
 				goto err;
-			curr_pid = 0;
-			}
 #endif
-		if (curr_time) /* just in the first iteration to save time */
-			{
-			if (!MD_Update(&m,(unsigned char*)&curr_time,
-				       sizeof curr_time))
-				goto err;
 			if (!MD_Update(&m,(unsigned char*)&tv,
 				       sizeof tv))
 				goto err;
-			curr_time = 0;
 			rand_hw_seed(&m);
+			do_diverge = 0;
 			}
+
 		if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
 			goto err;
 		if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
-- 
1.8.3.1

>From bd31a066c63d3347e65626f9922fb7ba3aef50f7 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fwei...@redhat.com>
Date: Thu, 16 Jan 2014 15:51:04 +0100
Subject: [PATCH 2/2] ssleay_rand_bytes: use cycle counter if RDRAND is not
 available

---
 crypto/rand/md_rand.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index c7c0f2c..4457cbf 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -383,9 +383,6 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
 #elif defined(OPENSSL_SYS_VXWORKS)
 	struct timespec tv;
 	clock_gettime(CLOCK_REALTIME, &ts);
-#elif defined(OPENSSL_SYSNAME_DSPBIOS)
-	unsigned long long tv, OPENSSL_rdtsc();
-	tv = OPENSSL_rdtsc();
 #else
 	struct timeval tv;
 	gettimeofday(&tv, NULL);
@@ -683,7 +680,13 @@ static void rand_hw_seed(EVP_MD_CTX *ctx)
 	{
 	int i;
 	if (!(OPENSSL_ia32cap_P[1] & (1<<(62-32))))
+		{
+		/* using the cycle counter is better than nothing at all */
+		unsigned long long tv, OPENSSL_rdtsc();
+		tv = OPENSSL_rdtsc();
+		MD_Update(ctx, (unsigned char *)&tv, sizeof(tv));
 		return;
+		}
 	for (i = 0; i < RDRAND_CALLS; i++)
 		{
 		size_t rnd;
@@ -730,7 +733,10 @@ void rand_hw_xor(unsigned char *buf, size_t num)
 
 static void rand_hw_seed(EVP_MD_CTX *ctx)
 	{
-	return;
+	/* using the cycle counter is better than nothing at all */
+	unsigned long long tv, OPENSSL_rdtsc();
+	tv = OPENSSL_rdtsc();
+	MD_Update(ctx, (unsigned char *)&tv, sizeof(tv));
 	}
 
 void rand_hw_xor(unsigned char *buf, size_t num)
-- 
1.8.3.1

Reply via email to