[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 5ce5cf6: Use getrandom syscall for nonces
From: |
Paul Eggert |
Subject: |
master 5ce5cf6: Use getrandom syscall for nonces |
Date: |
Sat, 27 Jun 2020 16:03:54 -0400 (EDT) |
branch: master
commit 5ce5cf643840cd6efd25d987bc5b6f12478c50a6
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>
Use getrandom syscall for nonces
* admin/merge-gnulib (GNULIB_MODULES): Add getrandom.
* doc/lispref/text.texi (Format of GnuTLS Cryptography Inputs):
Don’t say that iv-auto uses GNUTLS_RND_NONCE. Also, don’t say
that it returns the IV’s actual value, as it never has done that.
* src/fns.c, src/sysdep.c: Include sys/random.h, for getrandom.
* src/fns.c (Fsecure_hash_algorithms): Use getrandom so that this
function does not depend on HAVE_GNUTLS3.
* src/sysdep.c: Do not include <gnutls/crypto.h>.
(random_seed) [HAVE_LRAND48]: Can be long int now.
(init_random) [!WINDOWSNT]: Use getrandom syscall instead
of opening /dev/urandom, as this works even on GNU/Linux
hosts that lack /dev/urandom. Don’t bother with gnutls_rnd
as it’s not needed now that we have getrandom.
---
admin/merge-gnulib | 2 +-
doc/lispref/text.texi | 8 +++-----
src/fns.c | 15 ++++++++++-----
src/sysdep.c | 32 ++++++--------------------------
4 files changed, 20 insertions(+), 37 deletions(-)
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 99469e4..5a78b05 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -35,7 +35,7 @@ GNULIB_MODULES='
environ execinfo explicit_bzero faccessat
fchmodat fcntl fcntl-h fdopendir
filemode filename filevercmp flexmember fpieee fstatat fsusage fsync futimens
- getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
+ getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog
ieee754-h ignore-value intprops largefile lstat
manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
pathmax pipe2 pselect pthread_sigmask
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 10e8246..0c3813f 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -4813,11 +4813,9 @@ When @var{noerror} is non-@code{nil}, this function
silently uses
@code{raw-text} coding instead.
@item (@code{iv-auto} @var{length})
-This will generate an IV (Initialization Vector) of the specified
-length using the GnuTLS @code{GNUTLS_RND_NONCE} generator and pass it
-to the function. This ensures that the IV is unpredictable and
-unlikely to be reused in the same session. The actual value of the IV
-is returned by the function as described below.
+This generates a random IV (Initialization Vector) of the specified
+length and passes it to the function. This ensures that the IV is
+unpredictable and unlikely to be reused in the same session.
@end table
diff --git a/src/fns.c b/src/fns.c
index b2f84b2..c1465f7 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/>. */
#include <config.h>
#include <stdlib.h>
+#include <sys/random.h>
#include <unistd.h>
#include <filevercmp.h>
#include <intprops.h>
@@ -5267,7 +5268,6 @@ extract_data_from_object (Lisp_Object spec,
}
else if (EQ (object, Qiv_auto))
{
-#ifdef HAVE_GNUTLS3
/* Format: (iv-auto REQUIRED-LENGTH). */
if (! FIXNATP (start))
@@ -5276,14 +5276,19 @@ extract_data_from_object (Lisp_Object spec,
{
EMACS_INT start_hold = XFIXNAT (start);
object = make_uninit_string (start_hold);
- gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold);
+ char *lim = SSDATA (object) + start_hold;
+ for (char *p = SSDATA (object); p < lim; p++)
+ {
+ ssize_t gotten = getrandom (p, lim - p, 0);
+ if (0 <= gotten)
+ p += gotten;
+ else if (errno != EINTR)
+ report_file_error ("Getting random data", Qnil);
+ }
*start_byte = 0;
*end_byte = start_hold;
}
-#else
- error ("GnuTLS is not available, so `iv-auto' can't be used");
-#endif
}
if (!STRINGP (object))
diff --git a/src/sysdep.c b/src/sysdep.c
index cbd306a..6b54ed3 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/>. */
#endif /* HAVE_PWD_H */
#include <limits.h>
#include <stdlib.h>
+#include <sys/random.h>
#include <unistd.h>
#include <c-ctype.h>
@@ -115,16 +116,6 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include "process.h"
#include "cm.h"
-#include "gnutls.h"
-/* MS-Windows loads GnuTLS at run time, if available; we don't want to
- do that during startup just to call gnutls_rnd. */
-#if defined HAVE_GNUTLS && !defined WINDOWSNT
-# include <gnutls/crypto.h>
-#else
-# define emacs_gnutls_global_init() Qnil
-# define gnutls_rnd(level, data, len) (-1)
-#endif
-
#ifdef WINDOWSNT
# include <direct.h>
/* In process.h which conflicts with the local copy. */
@@ -2278,9 +2269,7 @@ init_signals (void)
typedef unsigned int random_seed;
static void set_random_seed (random_seed arg) { srandom (arg); }
#elif defined HAVE_LRAND48
-/* Although srand48 uses a long seed, this is unsigned long to avoid
- undefined behavior on signed integer overflow in init_random. */
-typedef unsigned long int random_seed;
+typedef long int random_seed;
static void set_random_seed (random_seed arg) { srand48 (arg); }
#else
typedef unsigned int random_seed;
@@ -2307,23 +2296,14 @@ init_random (void)
/* First, try seeding the PRNG from the operating system's entropy
source. This approach is both fast and secure. */
#ifdef WINDOWSNT
+ /* FIXME: Perhaps getrandom can be used here too? */
success = w32_init_random (&v, sizeof v) == 0;
#else
- int fd = emacs_open ("/dev/urandom", O_RDONLY, 0);
- if (0 <= fd)
- {
- success = emacs_read (fd, &v, sizeof v) == sizeof v;
- close (fd);
- }
+ verify (sizeof v <= 256);
+ success = getrandom (&v, sizeof v, 0) == sizeof v;
#endif
- /* If that didn't work, try using GnuTLS, which is secure, but on
- some systems, can be somewhat slow. */
- if (!success)
- success = EQ (emacs_gnutls_global_init (), Qt)
- && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0;
-
- /* If _that_ didn't work, just use the current time value and PID.
+ /* If that didn't work, just use the current time value and PID.
It's at least better than XKCD 221. */
if (!success)
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 5ce5cf6: Use getrandom syscall for nonces,
Paul Eggert <=