Hello,

this is my first post here, i hope i am in the right place, please redirect me 
if not. I'd like you to reconsider something that has been discussed here 
before [1]: on some platforms, the random number generator in openssl has very 
little entropy after a fork. Eric Wong stumbled over this, and so did Martin 
Bo├člich [2]. The issue does show up on Windows, too. I have a Windows 7 here 
with a fresh Cygwin64 installation, and on it, openssl built with "./Configure 
Cygwin-x86_64 --prefix=/opt/openssl shared" reproducibly shows repeating random 
number sequences with code very similar to Eric Wong's. Now I know that if you 
manually add entropy after a fork the problem does not show up in the first 
place, but this apparently surprises developers, because it seems to be the 
only spot where you really _have_ to seed the RNG. Surprising developers is not 
a good thing, so I suggest the attached patch (against the current github 
sources, i could submit a pull request if that is preferred). It does not do 
anything radical, it just takes these existing lines in md_rand.c, at the 
beginning of ssleay_rand_bytes:

#ifndef GETPID_IS_MEANINGLESS
        pid_t curr_pid = getpid();
#endif

And adds:

#ifndef GETPID_IS_MEANINGLESS
        pid_t curr_pid = getpid();
        if (curr_pid != old_pid)
                {
                initialized = 0;
                old_pid = curr_pid;
               }
#endif

Old_pid is a new static variable of type pid_t, and what this does is simply: 
on systems where getpid() is meaningful, it retrieves and stores the value of 
getpid() and whenever that changes, it sets the already existing variable 
initialized to 0, causing ssleay_rand_bytes to call RAND_poll() a little 
further down, taking a sip from the entropy bottle. RAND_poll() is getting 
called by ssleay_rand_bytes once anyway, so this only repeats that call. 
Looking into the source of the various RAND_poll implementations I could not 
see anything that would preclude it from being called repeatedly, so that seems 
safe to me. Besides, if you reseed manually, you'd call RAND_poll() after every 
fork, too, right?

I tested the patch on Windows and Debian, and the random number sequences are 
now different in all cases. And of course, on systems without getpid(), the 
code is never compiled in the first place.


What do you think?
Ernst-Udo Wallenborn







[1] http://marc.info/?l=openssl-dev&m=130289811108150&w=2
[2] 
http://emboss.github.io/blog/2013/08/21/openssl-prng-is-not-really-fork-safe/

Attachment: reseed_rng_on_fork.patch
Description: reseed_rng_on_fork.patch

Reply via email to