diff options
| author | Daniel Colascione | 2016-10-06 12:46:36 -0700 |
|---|---|---|
| committer | Daniel Colascione | 2016-10-29 20:00:53 -0700 |
| commit | a37eba849eddc41375ad73974f6fcb1258aa8eba (patch) | |
| tree | 4ecb3a7fcbb043f5d84ebe8863d5954a5b31f576 /src | |
| parent | 27443df092bfb4ada559f8fc024e01f174a5bcb0 (diff) | |
| download | emacs-a37eba849eddc41375ad73974f6fcb1258aa8eba.tar.gz emacs-a37eba849eddc41375ad73974f6fcb1258aa8eba.zip | |
Speed up initialization by preferring /dev/urandom to GnuTLS
* src/sysdep.c (init_random): Try /dev/urandom before GnuTLS.
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 0121f01631c..55d29bcc814 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -2188,27 +2188,35 @@ void | |||
| 2188 | init_random (void) | 2188 | init_random (void) |
| 2189 | { | 2189 | { |
| 2190 | random_seed v; | 2190 | random_seed v; |
| 2191 | if (! (EQ (emacs_gnutls_global_init (), Qt) | 2191 | bool success = false; |
| 2192 | && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0)) | 2192 | |
| 2193 | { | 2193 | /* First, try seeding the PRNG from the operating system's entropy |
| 2194 | bool success = false; | 2194 | source. This approach is both fast and secure. */ |
| 2195 | #ifndef WINDOWSNT | 2195 | #ifdef WINDOWSNT |
| 2196 | int fd = emacs_open ("/dev/urandom", O_RDONLY, 0); | 2196 | success = w32_init_random (&v, sizeof v) == 0; |
| 2197 | if (0 <= fd) | ||
| 2198 | { | ||
| 2199 | success = emacs_read (fd, &v, sizeof v) == sizeof v; | ||
| 2200 | emacs_close (fd); | ||
| 2201 | } | ||
| 2202 | #else | 2197 | #else |
| 2203 | success = w32_init_random (&v, sizeof v) == 0; | 2198 | int fd = emacs_open ("/dev/urandom", O_RDONLY, 0); |
| 2199 | if (0 <= fd) | ||
| 2200 | { | ||
| 2201 | success = emacs_read (fd, &v, sizeof v) == sizeof v; | ||
| 2202 | close (fd); | ||
| 2203 | } | ||
| 2204 | #endif | 2204 | #endif |
| 2205 | if (! success) | 2205 | |
| 2206 | { | 2206 | /* If that didn't work, try using GnuTLS, which is secure, but on |
| 2207 | /* Fall back to current time value + PID. */ | 2207 | some systems, can be somewhat slow. */ |
| 2208 | struct timespec t = current_timespec (); | 2208 | if (!success) |
| 2209 | v = getpid () ^ t.tv_sec ^ t.tv_nsec; | 2209 | success = EQ (emacs_gnutls_global_init (), Qt) |
| 2210 | } | 2210 | && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0; |
| 2211 | |||
| 2212 | /* If _that_ didn't work, just use the current time value and PID. | ||
| 2213 | It's at least better than XKCD 221. */ | ||
| 2214 | if (!success) | ||
| 2215 | { | ||
| 2216 | struct timespec t = current_timespec (); | ||
| 2217 | v = getpid () ^ t.tv_sec ^ t.tv_nsec; | ||
| 2211 | } | 2218 | } |
| 2219 | |||
| 2212 | set_random_seed (v); | 2220 | set_random_seed (v); |
| 2213 | } | 2221 | } |
| 2214 | 2222 | ||