Re: [PATCH] Reseed PRNG on PID change

2014-01-17 Thread Florian Weimer

On 01/16/2014 05:03 PM, David Jacobson wrote:


If you want to make sure they diverge, and make sure that multiple forks
diverge differently, you should push in the process ID. Pushing in time
helps with (but does not perfectly cure) the virtual machine copying
problem. So I suggest pushing in the PID concatenated with some sort of
time.


The PID is already mixed in.  It turned out this was not sufficient 
because PIDs are reused (see e.g. CVE-2013-1900).  My initial idea was 
to reseed the pool if a PID change was detected, but reseeding with a 
high-resolution timer appears preferable.  It also sidesteps the 
LinuxThreads issue.


--
Florian Weimer / Red Hat Product Security Team
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-17 Thread David Jacobson

On 1/16/14 4:57 AM, 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.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org

If you want to make sure they diverge, and make sure that multiple forks 
diverge differently, you should push in the process ID. Pushing in time 
helps with (but does not perfectly cure) the virtual machine copying 
problem. So I suggest pushing in the PID concatenated with some sort of 
time.


The reason I say that it is not perfect is that that might be some 
installation that has taken a snapshot of a VM.  Every time they need a 
new VM, they just start up a new one from that snapshot.  If time is 
only to a second, it is quite possible that 2 VMs start up the same 
second.   Higher resolution time would be better.


Of course, modern Intel chips have a really good RNG.  Use that if you can.

   --David Jacobson
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-16 Thread Stephan Mueller
Am Donnerstag, 16. Januar 2014, 15:55:36 schrieb Florian Weimer:

Hi Florian,

>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.

>From a FIPS 140-2 regulations perspective, there are no special 
considerations needed for this scenario. Thus, mixing the time stamp 
into those DRNGs is no problem either.

Ciao
Stephan
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-16 Thread Florian Weimer

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 
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 
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



Re: [PATCH] Reseed PRNG on PID change

2014-01-16 Thread Stephan Mueller
Am Donnerstag, 16. Januar 2014, 15:39:04 schrieb Florian Weimer:

Hi Florian,

>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.

Isn't the same issue applicable to the FIPS DRNGs? Especially 
considering that RHEL/Fedora ships these and have them enabled with a 
kernel command line flag, I am wondering about those.


Ciao
Stephan
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-16 Thread Florian Weimer

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.

--
Florian Weimer / Red Hat Product Security Team
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-16 Thread Florian Weimer

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 
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 
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)


Re: [PATCH] Reseed PRNG on PID change

2014-01-16 Thread Dr. Stephen Henson
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.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-16 Thread Florian Weimer

On 01/15/2014 05:44 PM, Dr. Stephen Henson wrote:

On Wed, Jan 15, 2014, Florian Weimer wrote:


Commit 3cd8547a2018ada88a4303067a2aa15eadc17f39 mixed the current
time into the randomness pool each time RAND_bytes is called.  As
the resolution of gettimeofday() is limited, I propose to reseed the
PRNG each time a PID change is detected.



I know historically some platforms have different PIDs for different threads.
That would cause problems with this patch.


Ah, good old LinuxThreads.  I admit it's not totally dead yet.  I can 
add a Linux- and glibc-specific detection function which disables the 
reseeding if LinuxThreads is detected.  (Other systems had strange 
threading libraries as well, but those generally shared PIDs.)


Regarding replacing gettimeofday() with a CPU tick counter, I expect 
that many systems have a very fast gettimeofday() implementation these 
days (based in part on a CPU tick counter).  However, time() has no such 
acceleration on the machines I've tested, so the current code shows a 
significant performance hit compared to 3cd8547a2^.


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.


--
Florian Weimer / Red Hat Product Security Team
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-15 Thread Stephan Mueller
Am Donnerstag, 16. Januar 2014, 08:11:32 schrieb Peter Waltenberg:

Hi Peter,

>The necessary code for MOST platforms is already in OpenSSL
>
>Look for OPENSSL_rdtsc in the crypto. directory.
>O.K. Not all platforms have this, but Sparc, x86/x86_64, s390, ppc,
>Itanium, apha,PA-RISC , ARM have some variant - admitted, quite a few
>hardware variants don't have a TSC, but that's determinable at runtime
>and you could drop back to gettimeofday() to cover those.

Great, then using these high-res timers should be definitely considered 
for the platforms where available (i.e. most common platforms). For any 
other platform, the gettimeofday can be called.
>
>It's at least "better" than gettimeofday() for this purpose - i.e. most
>of the bits can't be determined from outside the box, it moves faster,
>and it's cheaper  to read.

Agreed.

Ciao
Stephan
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-15 Thread Peter Waltenberg
The necessary code for MOST platforms is already in OpenSSL

Look for OPENSSL_rdtsc in the crypto. directory.
O.K. Not all platforms have this, but Sparc, x86/x86_64, s390, ppc,
Itanium, apha,PA-RISC , ARM have some variant - admitted, quite a few
hardware variants don't have a TSC, but that's determinable at runtime and
you could drop back to gettimeofday() to cover those.

It's at least "better" than gettimeofday() for this purpose - i.e. most of
the bits can't be determined from outside the box, it moves faster, and
it's cheaper  to read.

Peter




From:   Stephan Mueller 
To: openssl-dev@openssl.org,
Date:   16/01/2014 07:45
Subject:    Re: [PATCH] Reseed PRNG on PID change
Sent by:owner-openssl-...@openssl.org



Am Donnerstag, 16. Januar 2014, 07:41:21 schrieb Peter Waltenberg:

Hi Peter,

>You have access to high speed event counters on most platforms now.
>Where those are available, use them for reseed data instead of
>gettimeofday(). Far higher resolution, far less performance impact.

That implies, however, either hardware-specific code (i.e. special CPU
instruction) or per operating system specific code (special system call,
library call).

Ciao
Stephan

__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org



__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-15 Thread Stephan Mueller
Am Donnerstag, 16. Januar 2014, 07:41:21 schrieb Peter Waltenberg:

Hi Peter,

>You have access to high speed event counters on most platforms now.
>Where those are available, use them for reseed data instead of
>gettimeofday(). Far higher resolution, far less performance impact.

That implies, however, either hardware-specific code (i.e. special CPU 
instruction) or per operating system specific code (special system call, 
library call).

Ciao
Stephan

__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-15 Thread Peter Waltenberg
You have access to high speed event counters on most platforms now. Where
those are available, use them for reseed data instead of gettimeofday().
Far higher resolution, far less performance impact.

Peter






From:   "Dr. Stephen Henson" 
To: openssl-dev@openssl.org,
Date:   16/01/2014 02:50
Subject:    Re: [PATCH] Reseed PRNG on PID change
Sent by:owner-openssl-...@openssl.org



On Wed, Jan 15, 2014, Florian Weimer wrote:

> Commit 3cd8547a2018ada88a4303067a2aa15eadc17f39 mixed the current
> time into the randomness pool each time RAND_bytes is called.  As
> the resolution of gettimeofday() is limited, I propose to reseed the
> PRNG each time a PID change is detected.
>

I know historically some platforms have different PIDs for different
threads.
That would cause problems with this patch.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org



__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


Re: [PATCH] Reseed PRNG on PID change

2014-01-15 Thread Dr. Stephen Henson
On Wed, Jan 15, 2014, Florian Weimer wrote:

> Commit 3cd8547a2018ada88a4303067a2aa15eadc17f39 mixed the current
> time into the randomness pool each time RAND_bytes is called.  As
> the resolution of gettimeofday() is limited, I propose to reseed the
> PRNG each time a PID change is detected.
> 

I know historically some platforms have different PIDs for different threads.
That would cause problems with this patch.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
__
OpenSSL Project http://www.openssl.org
Development Mailing List   openssl-dev@openssl.org
Automated List Manager   majord...@openssl.org


[PATCH] Reseed PRNG on PID change

2014-01-15 Thread Florian Weimer
Commit 3cd8547a2018ada88a4303067a2aa15eadc17f39 mixed the current time 
into the randomness pool each time RAND_bytes is called.  As the 
resolution of gettimeofday() is limited, I propose to reseed the PRNG 
each time a PID change is detected.


This change might also be an alternative for platforms where the 
gettimeofday() call is prohibitively slow.


--
Florian Weimer / Red Hat Product Security Team
commit 136a8da88ff52ad32f894fb0ecbcab5f4205ca49
Author: Florian Weimer 
Date:   Wed Jan 15 16:46:17 2014 +0100

ssleay_rand_bytes: Re-seed on PID change

diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 6cab308..75382b5 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -153,6 +153,9 @@ static unsigned char md[MD_DIGEST_LENGTH];
 static long md_count[2]={0,0};
 static double entropy=0;
 static int initialized=0;
+#ifndef GETPID_IS_MEANINGLESS
+static pid_t prev_pid=0;
+#endif
 
 static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
* holds CRYPTO_LOCK_RAND
@@ -201,6 +204,7 @@ static void ssleay_rand_cleanup(void)
 	md_count[1]=0;
 	entropy=0;
 	initialized=0;
+	prev_pid=0;
 	}
 
 static int ssleay_rand_add(const void *buf, int num, double add)
@@ -439,7 +443,16 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
 		{
 		RAND_poll();
 		initialized = 1;
+		prev_pid = curr_pid;
+		}
+#ifndef GETPID_IS_MEANINGLESS
+	if (curr_pid != prev_pid)
+		{
+		RAND_poll();
+		prev_pid = curr_pid;
 		}
+#endif
+
 	
 	if (!stirred_pool)
 		do_stir_pool = 1;