diff options
| author | Daniel Colascione | 2016-10-06 12:46:36 -0700 |
|---|---|---|
| committer | Eli Zaretskii | 2016-11-18 10:42:12 +0200 |
| commit | a37c08d524db722063111329458dc8f4368c46a2 (patch) | |
| tree | d9a8d0d7aa273df345fbdaac1fc6c8cd01608fa0 /src | |
| parent | 4af5981dc75c96e34a27922001106df05ee19e69 (diff) | |
| download | emacs-a37c08d524db722063111329458dc8f4368c46a2.tar.gz emacs-a37c08d524db722063111329458dc8f4368c46a2.zip | |
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 | |||
| 2106 | init_random (void) | 2106 | init_random (void) |
| 2107 | { | 2107 | { |
| 2108 | random_seed v; | 2108 | random_seed v; |
| 2109 | if (! (EQ (emacs_gnutls_global_init (), Qt) | 2109 | bool success = false; |
| 2110 | && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0)) | 2110 | |
| 2111 | { | 2111 | /* First, try seeding the PRNG from the operating system's entropy |
| 2112 | bool success = false; | 2112 | source. This approach is both fast and secure. */ |
| 2113 | #ifndef WINDOWSNT | 2113 | #ifdef WINDOWSNT |
| 2114 | int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0); | 2114 | success = w32_init_random (&v, sizeof v) == 0; |
| 2115 | if (0 <= fd) | ||
| 2116 | { | ||
| 2117 | success = emacs_read (fd, &v, sizeof v) == sizeof v; | ||
| 2118 | emacs_close (fd); | ||
| 2119 | } | ||
| 2120 | #else | 2115 | #else |
| 2121 | success = w32_init_random (&v, sizeof v) == 0; | 2116 | int fd = emacs_open ("/dev/urandom", O_RDONLY, 0); |
| 2117 | if (0 <= fd) | ||
| 2118 | { | ||
| 2119 | success = emacs_read (fd, &v, sizeof v) == sizeof v; | ||
| 2120 | close (fd); | ||
| 2121 | } | ||
| 2122 | #endif | 2122 | #endif |
| 2123 | if (! success) | 2123 | |
| 2124 | { | 2124 | /* If that didn't work, try using GnuTLS, which is secure, but on |
| 2125 | /* Fall back to current time value + PID. */ | 2125 | some systems, can be somewhat slow. */ |
| 2126 | struct timespec t = current_timespec (); | 2126 | if (!success) |
| 2127 | v = getpid () ^ t.tv_sec ^ t.tv_nsec; | 2127 | success = EQ (emacs_gnutls_global_init (), Qt) |
| 2128 | } | 2128 | && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0; |
| 2129 | |||
| 2130 | /* If _that_ didn't work, just use the current time value and PID. | ||
| 2131 | It's at least better than XKCD 221. */ | ||
| 2132 | if (!success) | ||
| 2133 | { | ||
| 2134 | struct timespec t = current_timespec (); | ||
| 2135 | v = getpid () ^ t.tv_sec ^ t.tv_nsec; | ||
| 2129 | } | 2136 | } |
| 2137 | |||
| 2130 | set_random_seed (v); | 2138 | set_random_seed (v); |
| 2131 | } | 2139 | } |
| 2132 | 2140 | ||