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