diff options
author | Daniel Colascione <dancol@dancol.org> | 2016-10-06 12:46:36 -0700 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2016-11-18 10:42:12 +0200 |
commit | a37c08d524db722063111329458dc8f4368c46a2 (patch) | |
tree | d9a8d0d7aa273df345fbdaac1fc6c8cd01608fa0 /src | |
parent | 4af5981dc75c96e34a27922001106df05ee19e69 (diff) | |
download | emacs-a37c08d524db722063111329458dc8f4368c46a2.tar.gz |
Speed up initialization by preferring /dev/urandom to GnuTLS
* src/sysdep.c (init_random): Try /dev/urandom before GnuTLS.
(cherry picked from commit a37eba849eddc41375ad73974f6fcb1258aa8eba)
Diffstat (limited to 'src')
-rw-r--r-- | src/sysdep.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index 674e76db7a0..3f941c2000c 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2106,27 +2106,35 @@ void init_random (void) { random_seed v; - if (! (EQ (emacs_gnutls_global_init (), Qt) - && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0)) - { - bool success = false; -#ifndef WINDOWSNT - int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0); - if (0 <= fd) - { - success = emacs_read (fd, &v, sizeof v) == sizeof v; - emacs_close (fd); - } + bool success = false; + + /* First, try seeding the PRNG from the operating system's entropy + source. This approach is both fast and secure. */ +#ifdef WINDOWSNT + success = w32_init_random (&v, sizeof v) == 0; #else - success = w32_init_random (&v, sizeof v) == 0; + int fd = emacs_open ("/dev/urandom", O_RDONLY, 0); + if (0 <= fd) + { + success = emacs_read (fd, &v, sizeof v) == sizeof v; + close (fd); + } #endif - if (! success) - { - /* Fall back to current time value + PID. */ - struct timespec t = current_timespec (); - v = getpid () ^ t.tv_sec ^ t.tv_nsec; - } + + /* If that didn't work, try using GnuTLS, which is secure, but on + some systems, can be somewhat slow. */ + if (!success) + success = EQ (emacs_gnutls_global_init (), Qt) + && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0; + + /* If _that_ didn't work, just use the current time value and PID. + It's at least better than XKCD 221. */ + if (!success) + { + struct timespec t = current_timespec (); + v = getpid () ^ t.tv_sec ^ t.tv_nsec; } + set_random_seed (v); } |