aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Colascione2016-10-06 12:46:36 -0700
committerEli Zaretskii2016-11-18 10:42:12 +0200
commita37c08d524db722063111329458dc8f4368c46a2 (patch)
treed9a8d0d7aa273df345fbdaac1fc6c8cd01608fa0 /src
parent4af5981dc75c96e34a27922001106df05ee19e69 (diff)
downloademacs-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.c44
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
2106init_random (void) 2106init_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