aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fns.c15
-rw-r--r--src/sysdep.c32
2 files changed, 16 insertions, 31 deletions
diff --git a/src/fns.c b/src/fns.c
index b2f84b202de..c1465f7fe3c 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22 22
23#include <stdlib.h> 23#include <stdlib.h>
24#include <sys/random.h>
24#include <unistd.h> 25#include <unistd.h>
25#include <filevercmp.h> 26#include <filevercmp.h>
26#include <intprops.h> 27#include <intprops.h>
@@ -5267,7 +5268,6 @@ extract_data_from_object (Lisp_Object spec,
5267 } 5268 }
5268 else if (EQ (object, Qiv_auto)) 5269 else if (EQ (object, Qiv_auto))
5269 { 5270 {
5270#ifdef HAVE_GNUTLS3
5271 /* Format: (iv-auto REQUIRED-LENGTH). */ 5271 /* Format: (iv-auto REQUIRED-LENGTH). */
5272 5272
5273 if (! FIXNATP (start)) 5273 if (! FIXNATP (start))
@@ -5276,14 +5276,19 @@ extract_data_from_object (Lisp_Object spec,
5276 { 5276 {
5277 EMACS_INT start_hold = XFIXNAT (start); 5277 EMACS_INT start_hold = XFIXNAT (start);
5278 object = make_uninit_string (start_hold); 5278 object = make_uninit_string (start_hold);
5279 gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold); 5279 char *lim = SSDATA (object) + start_hold;
5280 for (char *p = SSDATA (object); p < lim; p++)
5281 {
5282 ssize_t gotten = getrandom (p, lim - p, 0);
5283 if (0 <= gotten)
5284 p += gotten;
5285 else if (errno != EINTR)
5286 report_file_error ("Getting random data", Qnil);
5287 }
5280 5288
5281 *start_byte = 0; 5289 *start_byte = 0;
5282 *end_byte = start_hold; 5290 *end_byte = start_hold;
5283 } 5291 }
5284#else
5285 error ("GnuTLS is not available, so `iv-auto' can't be used");
5286#endif
5287 } 5292 }
5288 5293
5289 if (!STRINGP (object)) 5294 if (!STRINGP (object))
diff --git a/src/sysdep.c b/src/sysdep.c
index cbd306a6b67..6b54ed3b6ec 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
27#endif /* HAVE_PWD_H */ 27#endif /* HAVE_PWD_H */
28#include <limits.h> 28#include <limits.h>
29#include <stdlib.h> 29#include <stdlib.h>
30#include <sys/random.h>
30#include <unistd.h> 31#include <unistd.h>
31 32
32#include <c-ctype.h> 33#include <c-ctype.h>
@@ -115,16 +116,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
115#include "process.h" 116#include "process.h"
116#include "cm.h" 117#include "cm.h"
117 118
118#include "gnutls.h"
119/* MS-Windows loads GnuTLS at run time, if available; we don't want to
120 do that during startup just to call gnutls_rnd. */
121#if defined HAVE_GNUTLS && !defined WINDOWSNT
122# include <gnutls/crypto.h>
123#else
124# define emacs_gnutls_global_init() Qnil
125# define gnutls_rnd(level, data, len) (-1)
126#endif
127
128#ifdef WINDOWSNT 119#ifdef WINDOWSNT
129# include <direct.h> 120# include <direct.h>
130/* In process.h which conflicts with the local copy. */ 121/* In process.h which conflicts with the local copy. */
@@ -2278,9 +2269,7 @@ init_signals (void)
2278typedef unsigned int random_seed; 2269typedef unsigned int random_seed;
2279static void set_random_seed (random_seed arg) { srandom (arg); } 2270static void set_random_seed (random_seed arg) { srandom (arg); }
2280#elif defined HAVE_LRAND48 2271#elif defined HAVE_LRAND48
2281/* Although srand48 uses a long seed, this is unsigned long to avoid 2272typedef long int random_seed;
2282 undefined behavior on signed integer overflow in init_random. */
2283typedef unsigned long int random_seed;
2284static void set_random_seed (random_seed arg) { srand48 (arg); } 2273static void set_random_seed (random_seed arg) { srand48 (arg); }
2285#else 2274#else
2286typedef unsigned int random_seed; 2275typedef unsigned int random_seed;
@@ -2307,23 +2296,14 @@ init_random (void)
2307 /* First, try seeding the PRNG from the operating system's entropy 2296 /* First, try seeding the PRNG from the operating system's entropy
2308 source. This approach is both fast and secure. */ 2297 source. This approach is both fast and secure. */
2309#ifdef WINDOWSNT 2298#ifdef WINDOWSNT
2299 /* FIXME: Perhaps getrandom can be used here too? */
2310 success = w32_init_random (&v, sizeof v) == 0; 2300 success = w32_init_random (&v, sizeof v) == 0;
2311#else 2301#else
2312 int fd = emacs_open ("/dev/urandom", O_RDONLY, 0); 2302 verify (sizeof v <= 256);
2313 if (0 <= fd) 2303 success = getrandom (&v, sizeof v, 0) == sizeof v;
2314 {
2315 success = emacs_read (fd, &v, sizeof v) == sizeof v;
2316 close (fd);
2317 }
2318#endif 2304#endif
2319 2305
2320 /* If that didn't work, try using GnuTLS, which is secure, but on 2306 /* If that didn't work, just use the current time value and PID.
2321 some systems, can be somewhat slow. */
2322 if (!success)
2323 success = EQ (emacs_gnutls_global_init (), Qt)
2324 && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0;
2325
2326 /* If _that_ didn't work, just use the current time value and PID.
2327 It's at least better than XKCD 221. */ 2307 It's at least better than XKCD 221. */
2328 if (!success) 2308 if (!success)
2329 { 2309 {