3

As I was going through Crypt::SSLeay, preparing it for the next release, I noticed the following code, written way before my time,

...

int rand_bytes_read;
static int bNotFirstTime;
char buf[ 1024 ];

...

if(!bNotFirstTime) {
    SSLeay_add_all_algorithms();
    SSL_load_error_strings();
    ERR_load_crypto_strings();
    SSL_library_init();
    bNotFirstTime = 1;
}

/**** Code from ..., 10/3/2002 ****/
/**** Use /dev/urandom to seed if available  ****/
rand_bytes_read = RAND_load_file("/dev/urandom", 1024);
if (rand_bytes_read <= 0) {
    /* Couldn't read /dev/urandom, just seed off
     * of the stack variable (the old way)
     */
    RAND_seed(buf,sizeof buf);
}

First, it seems to me that the correct way to check if RAND_load_file succeeded is to check if bytes read is equal to bytes requested.

Leaving that aside, it is my understanding that SSL_library_init does seed the PRNG from /dev/urandom if it is available, and from other sources on Windows etc.

  • Is there a reason to try to re-seed the PRNG every time a new context is created (SSL_library_init is only invoked the first time)?

  • Is using the contents of a stack variable an acceptable way to provide randomness?

OpenSSL's Wiki states:

Initialization

OpenSSL will attempt to seed the random number generator automatically upon instantiation by calling RAND_poll. RAND_poll seeds the random number generator using a system-specific entropy source, which is /dev/urandom on UNIX-like operating systems, and is a combination of CryptGenRandom and other sources of entropy on Windows.

Be careful when deferring to RAND_poll on some Unix systems because it does not seed the generator. See the code guarded with OPENSSL_SYS_VXWORKS in rand_unix.c. Additionally, RAND_poll can have negative interactions on newer Windows platforms, so your program could hang or crash depending on the potential issue. See Windows Issues below.

PS: Crypt::SSLeay provides support for Perl's LWP::UserAgent to communicate over HTTPS. It is no longer used by default, but it is maintained so as not to break older setups.

3

With current and not-so-current versions of OpenSSL, this code is useless (but harmless), because OpenSSL will automatically seed itself on /dev/urandom on machines where /dev/urandom is available. This is documented:

On systems that provide /dev/urandom, the randomness device is used to seed the PRNG transparently. However, on all other systems, the application is responsible for seeding the PRNG by calling RAND_add(), RAND_egd() or RAND_load_file().

Actually, the documentation is slightly wrong because on Windows, where there is no /dev/urandom, OpenSSL uses CryptGenRandom(), so the automatic strong seeding still occurs.

On machines where there is no system-provided strong PRNG, the caller must provide entropy "manually", but these systems are, by definition, machines where there is no /dev/urandom.

The contents of an uninitialized stack variable are hardly a good source of entropy, because such contents are usually very deterministic. Reasonable sources of randomness in a machine come from the "physical world", typically precise timings of hardware events.

  • Thank you very much. I am not sure it is harmless, though. With this code, on a Windows system, OpenSSL will seed via CryptGenRandom, and then this code will obliterate it with the contents of buf. My instinct is to remove it. What do you think? – Sinan Ünür Apr 23 '14 at 14:07
  • 2
    RAND_seed() does not replace the internal state, it adds to the entropy. Internally, the mixing is done with a hash function (or something similar). Thus, an application which does useless things (as the one you show) cannot destroy its own security that way (and that is a blessing, because applications often do stupid things when randomness is involved). – Thomas Pornin Apr 23 '14 at 14:13
  • I had missed that. Thank you very much for pointing it out. – Sinan Ünür Apr 23 '14 at 14:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.