aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Colascione2016-10-06 12:46:36 -0700
committerDaniel Colascione2016-10-29 20:00:53 -0700
commita37eba849eddc41375ad73974f6fcb1258aa8eba (patch)
tree4ecb3a7fcbb043f5d84ebe8863d5954a5b31f576 /src
parent27443df092bfb4ada559f8fc024e01f174a5bcb0 (diff)
downloademacs-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.c44
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
2188init_random (void) 2188init_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