On 01/16/2014 01:57 PM, Dr. Stephen Henson wrote:
On Thu, Jan 16, 2014, Florian Weimer wrote:
The additional resolution of a tick counter might make reseeding
after fork unnecessary, but it's difficult to be sure. Something
not based on timing information looks desirable to me.
I should point out that the aim of the current code is not to completely
reseed after fork() but to make the PRNG state diverge so that the two
processes do not share the same internal PRNG state.
I get that. I've reconsidered things. Time seems the only thing that
deals with the related VM snapshot issue.
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). OPENSSL_rdtsc() appears to return 0 if the cycle counter is not
available, so md_rand-rtdsc.patch calls it unconditionally if RDRAND is
not available.
--
Florian Weimer / Red Hat Product Security Team
commit 594dcc12d4ede5cd6f4e11cdc23fff3eea20cdcf
Author: Florian Weimer <fwei...@redhat.com>
Date: Thu Jan 16 15:16:38 2014 +0100
ssleay_rand_seed: optimize fork protection: do not call time()
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 6cab308..f2165cd 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -368,7 +368,6 @@ 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_stir_pool = 0;
/* time value for various platforms */
#ifdef OPENSSL_SYS_WIN32
@@ -508,6 +507,15 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
crypto_lock_rand = 0;
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ /* 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;
+#endif
+ if (!MD_Update(&m,(unsigned char*)&tv, sizeof tv))
+ goto err;
+ rand_hw_seed(&m);
+
while (num > 0)
{
/* num_ceil -= MD_DIGEST_LENGTH/2 */
@@ -515,26 +523,6 @@ 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 (!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);
- }
if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
goto err;
if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
commit 8cfc51d808a3d3b3118f3d3168fcba6c0ce79b9c
Author: Florian Weimer <fwei...@redhat.com>
Date: Thu Jan 16 15:35:40 2014 +0100
ssleay_rand_bytes: use cycle counter if RDRAND is not available
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index f2165cd..51acf44 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -382,9 +382,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);
@@ -674,7 +671,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;
@@ -721,7 +724,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)