bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* [PATCH] getentropy, getrandom: new modules
@ 2020-05-25 19:37 Paul Eggert
  2020-05-30 12:58 ` Bruno Haible
                   ` (8 more replies)
  0 siblings, 9 replies; 27+ messages in thread
From: Paul Eggert @ 2020-05-25 19:37 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

* MODULES.html.sh (func_all_modules):
* lib/unistd.in.h (getentropy, getrandom):
* m4/unistd_h.m4 (gl_UNISTD_H, gl_UNISTD_H_DEFAULTS):
* modules/unistd (unistd.h):
Add support for getentropy, getrandom.
* doc/glibc-functions/getentropy.texi (getentropy):
* doc/glibc-functions/getrandom.texi (getrandom):
These are now fixed on some platforms.
* lib/getentropy.c, lib/getrandom.c, lib/sys_random.in.h:
* m4/getentropy.m4, m4/getrandom.m4:
* modules/getentropy, modules/getentropy-tests:
* modules/getrandom, modules/getrandom-tests:
* tests/test-getentropy.c, tests/test-getrandom.c:
New files.
---
 ChangeLog                           | 18 ++++++++++
 MODULES.html.sh                     |  2 ++
 doc/glibc-functions/getentropy.texi | 10 ++++--
 doc/glibc-functions/getrandom.texi  |  8 +++--
 lib/getentropy.c                    | 51 ++++++++++++++++++++++++++++
 lib/getrandom.c                     | 52 +++++++++++++++++++++++++++++
 lib/sys_random.in.h                 |  9 +++++
 lib/unistd.in.h                     | 34 +++++++++++++++++++
 m4/getentropy.m4                    | 16 +++++++++
 m4/getrandom.m4                     | 15 +++++++++
 m4/unistd_h.m4                      |  8 +++--
 modules/getentropy                  | 29 ++++++++++++++++
 modules/getentropy-tests            | 12 +++++++
 modules/getrandom                   | 44 ++++++++++++++++++++++++
 modules/unistd                      |  4 +++
 tests/test-getentropy.c             | 43 ++++++++++++++++++++++++
 16 files changed, 348 insertions(+), 7 deletions(-)
 create mode 100644 lib/getentropy.c
 create mode 100644 lib/getrandom.c
 create mode 100644 lib/sys_random.in.h
 create mode 100644 m4/getentropy.m4
 create mode 100644 m4/getrandom.m4
 create mode 100644 modules/getentropy
 create mode 100644 modules/getentropy-tests
 create mode 100644 modules/getrandom
 create mode 100644 tests/test-getentropy.c

diff --git a/ChangeLog b/ChangeLog
index 6b2faf17e..b1acb99ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2020-05-25  Paul Eggert  <eggert@cs.ucla.edu>
+
+	getentropy, getrandom: new modules
+	* MODULES.html.sh (func_all_modules):
+	* lib/unistd.in.h (getentropy, getrandom):
+	* m4/unistd_h.m4 (gl_UNISTD_H, gl_UNISTD_H_DEFAULTS):
+	* modules/unistd (unistd.h):
+	Add support for getentropy, getrandom.
+	* doc/glibc-functions/getentropy.texi (getentropy):
+	* doc/glibc-functions/getrandom.texi (getrandom):
+	These are now fixed on some platforms.
+	* lib/getentropy.c, lib/getrandom.c, lib/sys_random.in.h:
+	* m4/getentropy.m4, m4/getrandom.m4:
+	* modules/getentropy, modules/getentropy-tests:
+	* modules/getrandom, modules/getrandom-tests:
+	* tests/test-getentropy.c, tests/test-getrandom.c:
+	New files.
+
 2020-05-25  Bruno Haible  <bruno@clisp.org>
 
 	Add missing C99 dependencies.
diff --git a/MODULES.html.sh b/MODULES.html.sh
index 318a15a1d..4db2a77ec 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -3484,9 +3484,11 @@ func_all_modules ()
   func_module forkpty
   func_module getdomainname
   func_module xgetdomainname
+  func_module getentropy
   func_module getloadavg
   func_module getpagesize
   func_module getprogname
+  func_module getrandom
   func_module getusershell
   func_module lib-symbol-visibility
   func_module login_tty
diff --git a/doc/glibc-functions/getentropy.texi b/doc/glibc-functions/getentropy.texi
index 5ad873a71..5281dcd4e 100644
--- a/doc/glibc-functions/getentropy.texi
+++ b/doc/glibc-functions/getentropy.texi
@@ -15,15 +15,19 @@ Documentation:
 @uref{https://www.kernel.org/doc/man-pages/online/pages/man3/getentropy.3.html,,man getentropy}.
 @end itemize
 
-Gnulib module: ---
+Gnulib module: getentropy
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8,
+Solaris 11.0, Android 9.0.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-This function is missing on many non-glibc platforms:
-glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.0, Cygwin, mingw, MSVC 14, Android 9.0.
+This function is missing on some platforms:
+Minix 3.1.8, IRIX 6.5, mingw, MSVC 14.
 @end itemize
diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
index 25e899d63..2f4debcfe 100644
--- a/doc/glibc-functions/getrandom.texi
+++ b/doc/glibc-functions/getrandom.texi
@@ -19,11 +19,15 @@ Gnulib module: ---
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8,
+Solaris 11.0, Android 9.0.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-This function is missing on many non-glibc platforms:
-glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.0, Cygwin, mingw, MSVC 14, Android 9.0.
+This function is missing on some platforms:
+Minix 3.1.8, IRIX 6.5, mingw, MSVC 14.
 @end itemize
diff --git a/lib/getentropy.c b/lib/getentropy.c
new file mode 100644
index 000000000..2b6c3f55f
--- /dev/null
+++ b/lib/getentropy.c
@@ -0,0 +1,51 @@
+/* Fill a buffer with random bytes.
+   Copyright 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <errno.h>
+#include <sys/random.h>
+
+/* Overwrite BUFFER with random data.  BUFFER contains LENGTH bytes.
+   LENGTH must be at most 256.  Return 0 on success, -1 (setting
+   errno) on failure.  */
+int
+getentropy (void *buffer, size_t length)
+{
+  char *buf = buffer;
+
+  if (length <= 256)
+    for (;;)
+      {
+        ssize_t bytes;
+        if (length == 0)
+          return 0;
+        while ((bytes = getrandom (buf, length, 0)) < 0)
+          if (errno != EINTR)
+            return -1;
+        if (bytes == 0)
+          break;
+        buf += bytes;
+        length -= bytes;
+      }
+
+  errno = EIO;
+  return -1;
+}
diff --git a/lib/getrandom.c b/lib/getrandom.c
new file mode 100644
index 000000000..9b6ecb43b
--- /dev/null
+++ b/lib/getrandom.c
@@ -0,0 +1,52 @@
+/* Obtain a series of random bytes.
+
+   Copyright 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+#include <config.h>
+
+#include <sys/random.h>
+
+#include "minmax.h"
+#include <fcntl.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+/* Set BUFFER (of size LENGTH) to random bytes under the control of FLAGS.
+   Return the number of bytes written, or -1 on error.  */
+ssize_t
+getrandom (void *buffer, size_t length, unsigned int flags)
+{
+  static int randfd[2] = { -1, -1 };
+  bool devrandom = (flags & GRND_RANDOM) != 0;
+  int fd = randfd[devrandom];
+
+  if (fd < 0)
+    {
+      static char const randdevice[][MAX (sizeof NAME_OF_NONCE_DEVICE,
+                                          sizeof NAME_OF_RANDOM_DEVICE)]
+        = { NAME_OF_NONCE_DEVICE, NAME_OF_RANDOM_DEVICE };
+      int oflags = (O_RDONLY + O_CLOEXEC
+                    + (flags & GRND_NONBLOCK ? O_NONBLOCK : 0));
+      fd = open (randdevice[devrandom], oflags);
+      if (fd < 0)
+        return fd;
+      randfd[devrandom] = fd;
+    }
+
+  return read (fd, buffer, length);
+}
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
new file mode 100644
index 000000000..e3f308ce4
--- /dev/null
+++ b/lib/sys_random.in.h
@@ -0,0 +1,9 @@
+#ifndef _SYS_RANDOM_H
+#define _SYS_RANDOM_H 1
+
+#include <sys/types.h>
+#define GRND_NONBLOCK 1
+#define GRND_RANDOM 2
+ssize_t getrandom (void *, size_t, unsigned int);
+
+#endif
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 1454d7e85..4a0d6655a 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -763,6 +763,22 @@ _GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - "
 #endif
 
 
+#if @GNULIB_GETENTROPY@
+/* Fill a buffer with random bytes.  */
+# if !@HAVE_GETENTROPY@
+_GL_FUNCDECL_SYS (getentropy, int, (void *buffer, size_t length));
+# endif
+_GL_CXXALIAS_SYS (getentropy, int, (void *buffer, size_t length));
+_GL_CXXALIASWARN (getentropy);
+#elif defined GNULIB_POSIXCHECK
+# undef getentropy
+# if HAVE_RAW_DECL_GETENTROPY
+_GL_WARN_ON_USE (getentropy, "getentropy is unportable - "
+                 "use gnulib module getentropy for portability");
+# endif
+#endif
+
+
 #if @GNULIB_GETGROUPS@
 /* Return the supplemental groups that the current process belongs to.
    It is unspecified whether the effective group id is in the list.
@@ -1014,6 +1030,24 @@ _GL_WARN_ON_USE (getpass, "getpass is unportable - "
 #endif
 
 
+#if @GNULIB_GETRANDOM@
+/* Fill a buffer with random bytes.  */
+# if !@HAVE_GETRANDOM@
+_GL_FUNCDECL_SYS (getrandom, int, (void *buffer, size_t length,
+                                   unsigned int flags));
+# endif
+_GL_CXXALIAS_SYS (getrandom, int, (void *buffer, size_t length,
+                                   unsigned int flags));
+_GL_CXXALIASWARN (getrandom);
+#elif defined GNULIB_POSIXCHECK
+# undef getrandom
+# if HAVE_RAW_DECL_GETRANDOM
+_GL_WARN_ON_USE (getrandom, "getrandom is unportable - "
+                 "use gnulib module getrandom for portability");
+# endif
+#endif
+
+
 #if @GNULIB_GETUSERSHELL@
 /* Return the next valid login shell on the system, or NULL when the end of
    the list has been reached.  */
diff --git a/m4/getentropy.m4 b/m4/getentropy.m4
new file mode 100644
index 000000000..596544b2e
--- /dev/null
+++ b/m4/getentropy.m4
@@ -0,0 +1,16 @@
+# getentropy.m4
+dnl Copyright 2020 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Paul Eggert.
+
+AC_DEFUN([gl_FUNC_GETENTROPY],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_CHECK_FUNCS_ONCE([getentropy])
+  if test $ac_cv_func_getentropy = no; then
+    HAVE_GETENTROPY=0
+  fi
+])
diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
new file mode 100644
index 000000000..ecb44aebf
--- /dev/null
+++ b/m4/getrandom.m4
@@ -0,0 +1,15 @@
+# getrandom.m4
+dnl Copyright 2020 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Paul Eggert.
+
+AC_DEFUN([gl_FUNC_GETRANDOM],
+[
+  AC_CHECK_FUNCS_ONCE([getrandom])
+  if test "$ac_cv_func_getrandom" != yes; then
+    HAVE_GETRANDOM=0
+  fi
+])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index e776f3bd4..1f39d53e1 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -43,8 +43,8 @@ AC_DEFUN([gl_UNISTD_H],
 #endif
     ]], [access chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir
     fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize
-    getgroups gethostname getlogin getlogin_r getpagesize getpass
-    getusershell setusershell endusershell
+    getentropy getgroups gethostname getlogin getlogin_r getpagesize getpass
+    getrandom getusershell setusershell endusershell
     group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite
     readlink readlinkat rmdir sethostname sleep symlink symlinkat
     truncate ttyname_r unlink unlinkat usleep])
@@ -82,6 +82,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   GNULIB_GETCWD=0;               AC_SUBST([GNULIB_GETCWD])
   GNULIB_GETDOMAINNAME=0;        AC_SUBST([GNULIB_GETDOMAINNAME])
   GNULIB_GETDTABLESIZE=0;        AC_SUBST([GNULIB_GETDTABLESIZE])
+  GNULIB_GETENTROPY=0;           AC_SUBST([GNULIB_GETENTROPY])
   GNULIB_GETGROUPS=0;            AC_SUBST([GNULIB_GETGROUPS])
   GNULIB_GETHOSTNAME=0;          AC_SUBST([GNULIB_GETHOSTNAME])
   GNULIB_GETLOGIN=0;             AC_SUBST([GNULIB_GETLOGIN])
@@ -89,6 +90,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   GNULIB_GETOPT_POSIX=0;         AC_SUBST([GNULIB_GETOPT_POSIX])
   GNULIB_GETPAGESIZE=0;          AC_SUBST([GNULIB_GETPAGESIZE])
   GNULIB_GETPASS=0;              AC_SUBST([GNULIB_GETPASS])
+  GNULIB_GETRANDOM=0;            AC_SUBST([GNULIB_GETRANDOM])
   GNULIB_GETUSERSHELL=0;         AC_SUBST([GNULIB_GETUSERSHELL])
   GNULIB_GROUP_MEMBER=0;         AC_SUBST([GNULIB_GROUP_MEMBER])
   GNULIB_ISATTY=0;               AC_SUBST([GNULIB_ISATTY])
@@ -129,11 +131,13 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   HAVE_FSYNC=1;           AC_SUBST([HAVE_FSYNC])
   HAVE_FTRUNCATE=1;       AC_SUBST([HAVE_FTRUNCATE])
   HAVE_GETDTABLESIZE=1;   AC_SUBST([HAVE_GETDTABLESIZE])
+  HAVE_GETENTROPY=1;      AC_SUBST([HAVE_GETENTROPY])
   HAVE_GETGROUPS=1;       AC_SUBST([HAVE_GETGROUPS])
   HAVE_GETHOSTNAME=1;     AC_SUBST([HAVE_GETHOSTNAME])
   HAVE_GETLOGIN=1;        AC_SUBST([HAVE_GETLOGIN])
   HAVE_GETPAGESIZE=1;     AC_SUBST([HAVE_GETPAGESIZE])
   HAVE_GETPASS=1;         AC_SUBST([HAVE_GETPASS])
+  HAVE_GETRANDOM=1;       AC_SUBST([HAVE_GETRANDOM])
   HAVE_GROUP_MEMBER=1;    AC_SUBST([HAVE_GROUP_MEMBER])
   HAVE_LCHOWN=1;          AC_SUBST([HAVE_LCHOWN])
   HAVE_LINK=1;            AC_SUBST([HAVE_LINK])
diff --git a/modules/getentropy b/modules/getentropy
new file mode 100644
index 000000000..9696c1e1d
--- /dev/null
+++ b/modules/getentropy
@@ -0,0 +1,29 @@
+Description:
+Fill buffer with random bytes.
+
+Files:
+lib/getentropy.c
+m4/getentropy.m4
+
+Depends-on:
+getrandom      [test $HAVE_GETENTROPY = 0]
+extensions
+unistd
+
+configure.ac:
+gl_FUNC_GETENTROPY
+if test $HAVE_GETENTROPY = 0; then
+  AC_LIBOBJ([getentropy])
+fi
+gl_UNISTD_MODULE_INDICATOR([getentropy])
+
+Makefile.am:
+
+Include:
+<unistd.h>
+
+License:
+LGPL
+
+Maintainer:
+all
diff --git a/modules/getentropy-tests b/modules/getentropy-tests
new file mode 100644
index 000000000..b5c4b1144
--- /dev/null
+++ b/modules/getentropy-tests
@@ -0,0 +1,12 @@
+Files:
+tests/test-getentropy.c
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getentropy
+check_PROGRAMS += test-getentropy
diff --git a/modules/getrandom b/modules/getrandom
new file mode 100644
index 000000000..2ae374f61
--- /dev/null
+++ b/modules/getrandom
@@ -0,0 +1,44 @@
+Description:
+Fill buffer with random bytes.
+
+Files:
+lib/getrandom.c
+lib/sys_random.in.h
+m4/getrandom.m4
+
+Depends-on:
+crypto/gc-random    [test $HAVE_GETRANDOM = 0]
+fcntl-h             [test $HAVE_GETRANDOM = 0]
+minmax              [test $HAVE_GETRANDOM = 0]
+open                [test $HAVE_GETRANDOM = 0]
+
+configure.ac:
+gl_FUNC_GETRANDOM
+if test $HAVE_GETRANDOM = 0; then
+  AC_LIBOBJ([getrandom])
+fi
+gl_UNISTD_MODULE_INDICATOR([getrandom])
+
+Makefile.am:
+BUILT_SOURCES += sys/random.h
+
+# We need the following in order to create <sys/random.h> when the system
+# doesn't have one that works with the given compiler.
+sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
+	$(AM_V_at)$(MKDIR_P) sys
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  cat $(srcdir)/sys_random.in.h; \
+	} > $@-t && \
+	mv -f $@-t $@
+MOSTLYCLEANFILES += sys/random.h sys/random.h-t
+MOSTLYCLEANDIRS += sys
+
+Include:
+<sys/random.h>
+
+License:
+LGPL
+
+Maintainer:
+all
diff --git a/modules/unistd b/modules/unistd
index 3c28f36ca..dc32ce056 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -55,6 +55,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \
 	      -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \
 	      -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \
+	      -e 's/@''GNULIB_GETENTROPY''@/$(GNULIB_GETENTROPY)/g' \
 	      -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \
 	      -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \
 	      -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \
@@ -62,6 +63,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's/@''GNULIB_GETOPT_POSIX''@/$(GNULIB_GETOPT_POSIX)/g' \
 	      -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \
 	      -e 's/@''GNULIB_GETPASS''@/$(GNULIB_GETPASS)/g' \
+	      -e 's/@''GNULIB_GETRANDOM''@/$(GNULIB_GETRANDOM)/g' \
 	      -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \
 	      -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \
 	      -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \
@@ -103,10 +105,12 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \
 	      -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
 	      -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \
+	      -e 's|@''HAVE_GETENTROPY''@|$(HAVE_GETENTROPY)|g' \
 	      -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \
 	      -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \
 	      -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
 	      -e 's|@''HAVE_GETPASS''@|$(HAVE_GETPASS)|g' \
+	      -e 's|@''HAVE_GETRANDOM''@|$(HAVE_GETRANDOM)|g' \
 	      -e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \
 	      -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \
 	      -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \
diff --git a/tests/test-getentropy.c b/tests/test-getentropy.c
new file mode 100644
index 000000000..845c5dcaf
--- /dev/null
+++ b/tests/test-getentropy.c
@@ -0,0 +1,43 @@
+/* Test the getentropy function.
+   Copyright 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <string.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (getentropy, int, (void *, size_t));
+
+#include "macros.h"
+
+char empty_buf[256];
+char buf[256];
+
+int
+main (int argc, char *argv[])
+{
+  /* If this test fails, there's something wrong with the setup anyway.  */
+  ASSERT (getentropy (buf, sizeof buf) == 0);
+
+  /* This test fails with probability 2**-2048.  (Run it again if so. :-) */
+  ASSERT (memcmp (buf, empty_buf, sizeof buf) != 0);
+
+  return 0;
+}
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH] getentropy, getrandom: new modules
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
@ 2020-05-30 12:58 ` Bruno Haible
  2020-05-30 22:43   ` Paul Eggert
  2020-05-30 13:17 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-05-30 12:58 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

There are several problems with this commit:
  - It causes a Continuous Integration failure.
  - It partially overlaps with the crypto/gc-random module.
  - The ChangeLog entry lists files that were not committed.
  - It conflicts with the declaration on Solaris 11.3 and newer.
  - It adds a new header file, <sys/random.h>, but without the usual
    header file tests in C and C++.

Let me start with the ChangeLog entry:

> * modules/getrandom, modules/getrandom-tests:
> * tests/test-getentropy.c, tests/test-getrandom.c:
> New files.

The files modules/getrandom-tests and tests/test-getrandom.c were
not committed. Let me add some.


2020-05-30  Bruno Haible  <bruno@clisp.org>

	getrandom: Add tests.
	* tests/test-getrandom.c: New file.
	* modules/getrandom-tests: New file.

============================ tests/test-getrandom.c ============================
/* Test of getting random bytes.
   Copyright (C) 2020 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible.  */

#include <config.h>

#include <sys/random.h>

#include "signature.h"
SIGNATURE_CHECK (getrandom, ssize_t, (void *, size_t, unsigned int));

#include <errno.h>
#include <string.h>

#include "macros.h"

int
main (void)
{
  char buf1[8];
  char buf2[8];
  char large_buf[100000];
  ssize_t ret;

  /* Check that different calls produce different results (with a high
     probability).  */
  ret = getrandom (buf1, sizeof (buf1), 0);
  if (ret < 0)
    ASSERT (errno == ENOSYS);
  else
    {
      ret = getrandom (buf2, sizeof (buf2), 0);
      if (ret < 0)
        ASSERT (errno == ENOSYS);
      else
        {
          /* It is very unlikely that two calls to getrandom produce the
             same results.  */
          ASSERT (memcmp (buf1, buf2, sizeof (buf1)) != 0);
        }
    }

  /* Likewise with the "truly random" number generator.  */
  ret = getrandom (buf1, sizeof (buf1), GRND_RANDOM);
  if (ret < 0)
    ASSERT (errno == ENOSYS);
  else
    {
      ret = getrandom (buf2, sizeof (buf2), GRND_RANDOM);
      if (ret < 0)
        ASSERT (errno == ENOSYS);
      else
        {
          /* It is very unlikely that two calls to getrandom produce the
             same results.  */
          ASSERT (memcmp (buf1, buf2, sizeof (buf1)) != 0);
        }
    }

  /* Check that GRND_NONBLOCK works.  */
  ret = getrandom (large_buf, sizeof (large_buf), GRND_RANDOM | GRND_NONBLOCK);
  /* It is very unlikely that so many truly random bytes were ready.  */
  if (ret < 0)
    ASSERT (errno == ENOSYS || errno == EAGAIN);
  else
    ASSERT (ret > 0 && ret < sizeof (large_buf));

  return 0;
}
=========================== modules/getrandom-tests ===========================
Files:
tests/test-getrandom.c
tests/signature.h
tests/macros.h

Depends-on:

configure.ac:

Makefile.am:
TESTS += test-getrandom
check_PROGRAMS += test-getrandom



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] getentropy, getrandom: new modules
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
  2020-05-30 12:58 ` Bruno Haible
@ 2020-05-30 13:17 ` Bruno Haible
  2020-05-30 14:23 ` Bruno Haible
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-30 13:17 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

The getrandom module produces a Continuous Integration failure,
see https://gitlab.com/gnulib/gnulib-ci/-/jobs/574033012 . Namely:

  In file included from getentropy.c:24:0:
  ./sys/random.h:8:9: error: conflicting types for 'getrandom'
   ssize_t getrandom (void *, size_t, unsigned int);
           ^~~~~~~~~
  In file included from getentropy.c:21:0:
  ./unistd.h:1512:1: note: previous declaration of 'getrandom' was here
   _GL_FUNCDECL_SYS (getrandom, int, (void *buffer, size_t length,
   ^
  Makefile:8195: recipe for target 'getentropy.o' failed
  make[4]: *** [getentropy.o] Error 1

Namely, there is a declaration in <sys/random.h> with return type 'ssize_t'
and another declaration in <unistd.h> with return type 'int'.

Since
1) The documentation of this function on glibc systems has return type 'ssize_t'
   https://www.gnu.org/software/libc/manual/html_node/Unpredictable-Bytes.html
   https://www.man7.org/linux/man-pages/man2/getrandom.2.html
2) No known system declares the function in <unistd.h> (Solaris 11 has it in
   <sys/random.h>).

I conclude that gnulib does not need to offer this function in <unistd.h>.


2020-05-30  Bruno Haible  <bruno@clisp.org>

	unistd: Remove conflicting declaration of getrandom().
	* lib/unistd.in.h (getrandom): Remove declaration.
	* m4/unistd_h.m4 (gl_UNISTD_H): Don't test whether getrandom is
	declared.
	(gl_UNISTD_H_DEFAULTS): Don't initialize GNULIB_GETRANDOM,
	HAVE_GETRANDOM.
	* modules/unistd (Makefile.am): Don't substitute GNULIB_GETRANDOM,
	HAVE_GETRANDOM.

diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 4a0d665..906f806 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1030,24 +1030,6 @@ _GL_WARN_ON_USE (getpass, "getpass is unportable - "
 #endif
 
 
-#if @GNULIB_GETRANDOM@
-/* Fill a buffer with random bytes.  */
-# if !@HAVE_GETRANDOM@
-_GL_FUNCDECL_SYS (getrandom, int, (void *buffer, size_t length,
-                                   unsigned int flags));
-# endif
-_GL_CXXALIAS_SYS (getrandom, int, (void *buffer, size_t length,
-                                   unsigned int flags));
-_GL_CXXALIASWARN (getrandom);
-#elif defined GNULIB_POSIXCHECK
-# undef getrandom
-# if HAVE_RAW_DECL_GETRANDOM
-_GL_WARN_ON_USE (getrandom, "getrandom is unportable - "
-                 "use gnulib module getrandom for portability");
-# endif
-#endif
-
-
 #if @GNULIB_GETUSERSHELL@
 /* Return the next valid login shell on the system, or NULL when the end of
    the list has been reached.  */
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 1f39d53..a3b4633 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 78
+# unistd_h.m4 serial 79
 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -44,7 +44,7 @@ AC_DEFUN([gl_UNISTD_H],
     ]], [access chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir
     fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize
     getentropy getgroups gethostname getlogin getlogin_r getpagesize getpass
-    getrandom getusershell setusershell endusershell
+    getusershell setusershell endusershell
     group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite
     readlink readlinkat rmdir sethostname sleep symlink symlinkat
     truncate ttyname_r unlink unlinkat usleep])
@@ -90,7 +90,6 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   GNULIB_GETOPT_POSIX=0;         AC_SUBST([GNULIB_GETOPT_POSIX])
   GNULIB_GETPAGESIZE=0;          AC_SUBST([GNULIB_GETPAGESIZE])
   GNULIB_GETPASS=0;              AC_SUBST([GNULIB_GETPASS])
-  GNULIB_GETRANDOM=0;            AC_SUBST([GNULIB_GETRANDOM])
   GNULIB_GETUSERSHELL=0;         AC_SUBST([GNULIB_GETUSERSHELL])
   GNULIB_GROUP_MEMBER=0;         AC_SUBST([GNULIB_GROUP_MEMBER])
   GNULIB_ISATTY=0;               AC_SUBST([GNULIB_ISATTY])
@@ -137,7 +136,6 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   HAVE_GETLOGIN=1;        AC_SUBST([HAVE_GETLOGIN])
   HAVE_GETPAGESIZE=1;     AC_SUBST([HAVE_GETPAGESIZE])
   HAVE_GETPASS=1;         AC_SUBST([HAVE_GETPASS])
-  HAVE_GETRANDOM=1;       AC_SUBST([HAVE_GETRANDOM])
   HAVE_GROUP_MEMBER=1;    AC_SUBST([HAVE_GROUP_MEMBER])
   HAVE_LCHOWN=1;          AC_SUBST([HAVE_LCHOWN])
   HAVE_LINK=1;            AC_SUBST([HAVE_LINK])
diff --git a/modules/unistd b/modules/unistd
index dc32ce0..f075b78 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -63,7 +63,6 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's/@''GNULIB_GETOPT_POSIX''@/$(GNULIB_GETOPT_POSIX)/g' \
 	      -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \
 	      -e 's/@''GNULIB_GETPASS''@/$(GNULIB_GETPASS)/g' \
-	      -e 's/@''GNULIB_GETRANDOM''@/$(GNULIB_GETRANDOM)/g' \
 	      -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \
 	      -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \
 	      -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \
@@ -110,7 +109,6 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \
 	      -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
 	      -e 's|@''HAVE_GETPASS''@|$(HAVE_GETPASS)|g' \
-	      -e 's|@''HAVE_GETRANDOM''@|$(HAVE_GETRANDOM)|g' \
 	      -e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \
 	      -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \
 	      -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH] getentropy, getrandom: new modules
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
  2020-05-30 12:58 ` Bruno Haible
  2020-05-30 13:17 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
@ 2020-05-30 14:23 ` Bruno Haible
  2020-05-30 23:06   ` sys_random: Work around macOS bug Bruno Haible
  2020-05-30 15:34 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-05-30 14:23 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

[-- Attachment #1: Type: text/plain, Size: 1372 bytes --]

On platforms which do have a <sys/random.h> that does not declare
getrandom() - such as Mac OS X 10.5 or HP-UX 11, gnulib should not override
the system's <sys/random.h>, but augment it. Otherwise we hide system
functions that the user may want to use.

Also, the getrandom() declaration lacks an 'extern "C"' marker in C++ mode.

Also, in getrandom.m4, we must make sure that the initialization of the
variable HAVE_GETRANDOM precedes the HAVE_GETRANDOM=0 statement.

So, let's use the standard idioms.


2020-05-30  Bruno Haible  <bruno@clisp.org>

	sys_random: Add C++ tests.
	* tests/test-sys_random-c++.cc: New file.
	* modules/sys_random-c++-tests: New file.
	* modules/sys_random-tests (Depends-on): Depend on it.

	sys_random: Add tests.
	* tests/test-sys_random.c: New file.
	* modules/sys_random-tests: New file.

	sys_random: New module.
	* lib/sys_random.in.h: Use the common idioms for overridable header
	files.
	* m4/sys_random_h.m4: New file.
	* m4/getrandom.m4 (gl_FUNC_GETRANDOM): Require gl_SYS_RANDOM_H_DEFAULTS.
	* modules/sys_random: New file.
	* modules/getrandom (Files): Remove lib/sys_random.in.h.
	(Depends-on): Add sys_random.
	(configure.ac): Use gl_SYS_RANDOM_MODULE_INDICATOR, not
	gl_UNISTD_MODULE_INDICATOR.
	(Makefile.am): Don't generate sys/random.h here.
	* doc/glibc-headers/sys_random.texi: New file.
	* doc/gnulib.texi: Include it.


[-- Attachment #2: 0001-sys_random-New-module.patch --]
[-- Type: text/x-patch, Size: 11434 bytes --]

From d1b9cea779c7e11af92c88cd546412ecc2a7fcaa Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sat, 30 May 2020 16:18:36 +0200
Subject: [PATCH 1/3] sys_random: New module.

* lib/sys_random.in.h: Use the common idioms for overridable header
files.
* m4/sys_random_h.m4: New file.
* m4/getrandom.m4 (gl_FUNC_GETRANDOM): Require gl_SYS_RANDOM_H_DEFAULTS.
* modules/sys_random: New file.
* modules/getrandom (Files): Remove lib/sys_random.in.h.
(Depends-on): Add sys_random.
(configure.ac): Use gl_SYS_RANDOM_MODULE_INDICATOR, not
gl_UNISTD_MODULE_INDICATOR.
(Makefile.am): Don't generate sys/random.h here.
* doc/glibc-headers/sys_random.texi: New file.
* doc/gnulib.texi: Include it.
---
 ChangeLog                         | 16 +++++++++
 doc/glibc-headers/sys_random.texi | 33 ++++++++++++++++++
 doc/gnulib.texi                   |  2 ++
 lib/sys_random.in.h               | 73 ++++++++++++++++++++++++++++++++++++---
 m4/getrandom.m4                   |  3 +-
 m4/sys_random_h.m4                | 43 +++++++++++++++++++++++
 modules/getrandom                 | 17 ++-------
 modules/sys_random                | 51 +++++++++++++++++++++++++++
 8 files changed, 217 insertions(+), 21 deletions(-)
 create mode 100644 doc/glibc-headers/sys_random.texi
 create mode 100644 m4/sys_random_h.m4
 create mode 100644 modules/sys_random

diff --git a/ChangeLog b/ChangeLog
index 2cb7edd..3c4dd93 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2020-05-30  Bruno Haible  <bruno@clisp.org>
 
+	sys_random: New module.
+	* lib/sys_random.in.h: Use the common idioms for overridable header
+	files.
+	* m4/sys_random_h.m4: New file.
+	* m4/getrandom.m4 (gl_FUNC_GETRANDOM): Require gl_SYS_RANDOM_H_DEFAULTS.
+	* modules/sys_random: New file.
+	* modules/getrandom (Files): Remove lib/sys_random.in.h.
+	(Depends-on): Add sys_random.
+	(configure.ac): Use gl_SYS_RANDOM_MODULE_INDICATOR, not
+	gl_UNISTD_MODULE_INDICATOR.
+	(Makefile.am): Don't generate sys/random.h here.
+	* doc/glibc-headers/sys_random.texi: New file.
+	* doc/gnulib.texi: Include it.
+
+2020-05-30  Bruno Haible  <bruno@clisp.org>
+
 	unistd: Remove conflicting declaration of getrandom().
 	* lib/unistd.in.h (getrandom): Remove declaration.
 	* m4/unistd_h.m4 (gl_UNISTD_H): Don't test whether getrandom is
diff --git a/doc/glibc-headers/sys_random.texi b/doc/glibc-headers/sys_random.texi
new file mode 100644
index 0000000..1c28595
--- /dev/null
+++ b/doc/glibc-headers/sys_random.texi
@@ -0,0 +1,33 @@
+@node sys/random.h
+@section @file{sys/random.h}
+
+Declares the function @code{getrandom} and the flags for it.
+
+Documentation:
+@itemize
+@item
+@ifinfo
+@ref{Unpredictable Bytes,,Generating Unpredictable Bytes,libc},
+@end ifinfo
+@ifnotinfo
+@url{https://www.gnu.org/software/libc/manual/html_node/Unpredictable-Bytes.html},
+@end ifnotinfo
+@item
+@uref{https://www.kernel.org/doc/man-pages/online/pages/man2/getrandom.2.html,,man getrandom}.
+@end itemize
+
+Gnulib module: sys_random
+
+Portability problems fixed by Gnulib:
+@itemize
+@item
+This header file is missing on some platforms:
+glibc 2.24, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.11, IRIX 6.5, Cygwin, mingw, MSVC 14.
+@item
+This header file does not declare the @code{getrandom} function on some platforms:
+Mac OS X 10.5, FreeBSD 11.0, HP-UX 11.31, Solaris 11.0.
+@end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@end itemize
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index 3719978..fd9d9b0 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -3684,6 +3684,7 @@ not worked around by Gnulib.
 * resolv.h::
 * shadow.h::
 * sys/ioctl.h::
+* sys/random.h::
 * sysexits.h::
 * ttyent.h::
 @end menu
@@ -3718,6 +3719,7 @@ not worked around by Gnulib.
 @include glibc-headers/resolv.texi
 @include glibc-headers/shadow.texi
 @include glibc-headers/sys_ioctl.texi
+@include glibc-headers/sys_random.texi
 @include glibc-headers/sysexits.texi
 @include glibc-headers/ttyent.texi
 
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
index e3f308c..3997cf4 100644
--- a/lib/sys_random.in.h
+++ b/lib/sys_random.in.h
@@ -1,9 +1,72 @@
-#ifndef _SYS_RANDOM_H
-#define _SYS_RANDOM_H 1
+/* Substitute for <sys/random.h>.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+# if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+# endif
+@PRAGMA_COLUMNS@
+
+#ifndef _@GUARD_PREFIX@_SYS_RANDOM_H
+
+#if @HAVE_SYS_RANDOM_H@
+
+/* The include_next requires a split double-inclusion guard.  */
+# @INCLUDE_NEXT@ @NEXT_SYS_RANDOM_H@
+
+#endif
+
+#ifndef _@GUARD_PREFIX@_SYS_RANDOM_H
+#define _@GUARD_PREFIX@_SYS_RANDOM_H
 
 #include <sys/types.h>
-#define GRND_NONBLOCK 1
-#define GRND_RANDOM 2
-ssize_t getrandom (void *, size_t, unsigned int);
 
+/* Define the GRND_* constants.  */
+#ifndef GRND_NONBLOCK
+# define GRND_NONBLOCK 1
+# define GRND_RANDOM 2
 #endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Declare overridden functions.  */
+
+
+#if @GNULIB_GETRANDOM@
+/* Fill a buffer with random bytes.  */
+# if !@HAVE_GETRANDOM@
+_GL_FUNCDECL_SYS (getrandom, ssize_t,
+                  (void *buffer, size_t length, unsigned int flags)
+                  _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (getrandom, ssize_t,
+                  (void *buffer, size_t length, unsigned int flags));
+_GL_CXXALIASWARN (getrandom);
+#elif defined GNULIB_POSIXCHECK
+# undef getrandom
+# if HAVE_RAW_DECL_GETRANDOM
+_GL_WARN_ON_USE (getrandom, "getrandom is unportable - "
+                 "use gnulib module getrandom for portability");
+# endif
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_SYS_RANDOM_H */
+#endif /* _@GUARD_PREFIX@_SYS_RANDOM_H */
diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
index ecb44ae..79e5520 100644
--- a/m4/getrandom.m4
+++ b/m4/getrandom.m4
@@ -1,4 +1,4 @@
-# getrandom.m4
+# getrandom.m4 serial 2
 dnl Copyright 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,6 +8,7 @@ dnl Written by Paul Eggert.
 
 AC_DEFUN([gl_FUNC_GETRANDOM],
 [
+  AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS])
   AC_CHECK_FUNCS_ONCE([getrandom])
   if test "$ac_cv_func_getrandom" != yes; then
     HAVE_GETRANDOM=0
diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
new file mode 100644
index 0000000..d78307f
--- /dev/null
+++ b/m4/sys_random_h.m4
@@ -0,0 +1,43 @@
+# sys_random_h.m4 serial 1
+dnl Copyright (C) 2020 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_HEADER_SYS_RANDOM],
+[
+  AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS])
+  dnl <sys/random.h> is always overridden, because of GNULIB_POSIXCHECK.
+  gl_CHECK_NEXT_HEADERS([sys/random.h])
+  if test $ac_cv_header_sys_random_h = yes; then
+    HAVE_SYS_RANDOM_H=1
+  else
+    HAVE_SYS_RANDOM_H=0
+  fi
+  AC_SUBST([HAVE_SYS_RANDOM_H])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use.
+  gl_WARN_ON_USE_PREPARE([[
+#if HAVE_SYS_RANDOM_H
+# include <sys/random.h>
+#endif
+    ]],
+    [getrandom])
+])
+
+AC_DEFUN([gl_SYS_RANDOM_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_SYS_RANDOM_H_DEFAULTS],
+[
+  GNULIB_GETRANDOM=0;     AC_SUBST([GNULIB_GETRANDOM])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_GETRANDOM=1;       AC_SUBST([HAVE_GETRANDOM])
+])
diff --git a/modules/getrandom b/modules/getrandom
index 2ae374f..f7b3ff9 100644
--- a/modules/getrandom
+++ b/modules/getrandom
@@ -3,10 +3,10 @@ Fill buffer with random bytes.
 
 Files:
 lib/getrandom.c
-lib/sys_random.in.h
 m4/getrandom.m4
 
 Depends-on:
+sys_random
 crypto/gc-random    [test $HAVE_GETRANDOM = 0]
 fcntl-h             [test $HAVE_GETRANDOM = 0]
 minmax              [test $HAVE_GETRANDOM = 0]
@@ -17,22 +17,9 @@ gl_FUNC_GETRANDOM
 if test $HAVE_GETRANDOM = 0; then
   AC_LIBOBJ([getrandom])
 fi
-gl_UNISTD_MODULE_INDICATOR([getrandom])
+gl_SYS_RANDOM_MODULE_INDICATOR([getrandom])
 
 Makefile.am:
-BUILT_SOURCES += sys/random.h
-
-# We need the following in order to create <sys/random.h> when the system
-# doesn't have one that works with the given compiler.
-sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  cat $(srcdir)/sys_random.in.h; \
-	} > $@-t && \
-	mv -f $@-t $@
-MOSTLYCLEANFILES += sys/random.h sys/random.h-t
-MOSTLYCLEANDIRS += sys
 
 Include:
 <sys/random.h>
diff --git a/modules/sys_random b/modules/sys_random
new file mode 100644
index 0000000..1d0eb7c
--- /dev/null
+++ b/modules/sys_random
@@ -0,0 +1,51 @@
+Description:
+A GNU-like <sys/random.h>.
+
+Files:
+lib/sys_random.in.h
+m4/sys_random_h.m4
+
+Depends-on:
+include_next
+snippet/arg-nonnull
+snippet/c++defs
+snippet/warn-on-use
+
+configure.ac:
+gl_HEADER_SYS_RANDOM
+AC_PROG_MKDIR_P
+
+Makefile.am:
+BUILT_SOURCES += sys/random.h
+
+# We need the following in order to create <sys/random.h> when the system
+# doesn't have one.
+sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_at)$(MKDIR_P) sys
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_SYS_RANDOM_H''@|$(NEXT_SYS_RANDOM_H)|g' \
+	      -e 's|@''HAVE_SYS_RANDOM_H''@|$(HAVE_SYS_RANDOM_H)|g' \
+	      -e 's/@''GNULIB_GETRANDOM''@/$(GNULIB_GETRANDOM)/g' \
+	      -e 's/@''HAVE_GETRANDOM''@/$(HAVE_GETRANDOM)/g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/sys_random.in.h; \
+	} > $@-t && \
+	mv -f $@-t $@
+MOSTLYCLEANFILES += sys/random.h sys/random.h-t
+MOSTLYCLEANDIRS += sys
+
+Include:
+<sys/random.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
-- 
2.7.4


[-- Attachment #3: 0002-sys_random-Add-tests.patch --]
[-- Type: text/x-patch, Size: 2364 bytes --]

From 7168ecc9cc88793fedca103ae8fc7be56349ca41 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sat, 30 May 2020 16:20:32 +0200
Subject: [PATCH 2/3] sys_random: Add tests.

* tests/test-sys_random.c: New file.
* modules/sys_random-tests: New file.
---
 ChangeLog                |  4 ++++
 modules/sys_random-tests | 10 ++++++++++
 tests/test-sys_random.c  | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+)
 create mode 100644 modules/sys_random-tests
 create mode 100644 tests/test-sys_random.c

diff --git a/ChangeLog b/ChangeLog
index 3c4dd93..f458e9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-05-30  Bruno Haible  <bruno@clisp.org>
 
+	sys_random: Add tests.
+	* tests/test-sys_random.c: New file.
+	* modules/sys_random-tests: New file.
+
 	sys_random: New module.
 	* lib/sys_random.in.h: Use the common idioms for overridable header
 	files.
diff --git a/modules/sys_random-tests b/modules/sys_random-tests
new file mode 100644
index 0000000..24fea63
--- /dev/null
+++ b/modules/sys_random-tests
@@ -0,0 +1,10 @@
+Files:
+tests/test-sys_random.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-sys_random
+check_PROGRAMS += test-sys_random
diff --git a/tests/test-sys_random.c b/tests/test-sys_random.c
new file mode 100644
index 0000000..56da27b
--- /dev/null
+++ b/tests/test-sys_random.c
@@ -0,0 +1,32 @@
+/* Test of <sys/random.h> substitute.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <sys/random.h>
+
+/* Check that the necessary constants are defined.  */
+int flags[] =
+  {
+    GRND_RANDOM,
+    GRND_NONBLOCK
+  };
+
+int
+main (void)
+{
+  return 0;
+}
-- 
2.7.4


[-- Attachment #4: 0003-sys_random-Add-C-tests.patch --]
[-- Type: text/x-patch, Size: 3122 bytes --]

From 9e7d098310117f0b17e7868124652a392b0a9854 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sat, 30 May 2020 16:22:25 +0200
Subject: [PATCH 3/3] sys_random: Add C++ tests.

* tests/test-sys_random-c++.cc: New file.
* modules/sys_random-c++-tests: New file.
* modules/sys_random-tests (Depends-on): Depend on it.
---
 ChangeLog                    |  5 +++++
 modules/sys_random-c++-tests | 18 ++++++++++++++++++
 modules/sys_random-tests     |  1 +
 tests/test-sys_random-c++.cc | 35 +++++++++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+)
 create mode 100644 modules/sys_random-c++-tests
 create mode 100644 tests/test-sys_random-c++.cc

diff --git a/ChangeLog b/ChangeLog
index f458e9d..c5a3bd5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-05-30  Bruno Haible  <bruno@clisp.org>
 
+	sys_random: Add C++ tests.
+	* tests/test-sys_random-c++.cc: New file.
+	* modules/sys_random-c++-tests: New file.
+	* modules/sys_random-tests (Depends-on): Depend on it.
+
 	sys_random: Add tests.
 	* tests/test-sys_random.c: New file.
 	* modules/sys_random-tests: New file.
diff --git a/modules/sys_random-c++-tests b/modules/sys_random-c++-tests
new file mode 100644
index 0000000..e07d81f
--- /dev/null
+++ b/modules/sys_random-c++-tests
@@ -0,0 +1,18 @@
+Files:
+tests/test-sys_random-c++.cc
+tests/signature.h
+
+Status:
+c++-test
+
+Depends-on:
+ansi-c++-opt
+
+configure.ac:
+
+Makefile.am:
+if ANSICXX
+TESTS += test-sys_random-c++
+check_PROGRAMS += test-sys_random-c++
+test_sys_random_c___SOURCES = test-sys_random-c++.cc
+endif
diff --git a/modules/sys_random-tests b/modules/sys_random-tests
index 24fea63..2208c5a 100644
--- a/modules/sys_random-tests
+++ b/modules/sys_random-tests
@@ -2,6 +2,7 @@ Files:
 tests/test-sys_random.c
 
 Depends-on:
+sys_random-c++-tests
 
 configure.ac:
 
diff --git a/tests/test-sys_random-c++.cc b/tests/test-sys_random-c++.cc
new file mode 100644
index 0000000..7477b3a
--- /dev/null
+++ b/tests/test-sys_random-c++.cc
@@ -0,0 +1,35 @@
+/* Test of <sys/random.h> substitute in C++ mode.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2020.  */
+
+#define GNULIB_NAMESPACE gnulib
+#include <config.h>
+
+#include <sys/random.h>
+
+#include "signature.h"
+
+
+#if GNULIB_TEST_GETRANDOM
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getrandom, ssize_t, (void *, size_t, unsigned int));
+#endif
+
+
+int
+main ()
+{
+}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH] getentropy, getrandom: new modules
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
                   ` (2 preceding siblings ...)
  2020-05-30 14:23 ` Bruno Haible
@ 2020-05-30 15:34 ` Bruno Haible
  2020-05-30 23:14 ` fix list of crypto devices for NetBSD, OpenBSD Bruno Haible
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-30 15:34 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

Now that we have a <sys/random.h> module with test cases, we see that
there is a conflict with the function defined on Solaris 11.3 and newer:

../gllib/sys/random.h: In member function ‘gnulib::_gl_getrandom_wrapper::operator gnulib::_gl_getrandom_wrapper::type() const’:
../gllib/sys/random.h:535:1: error: invalid conversion from ‘int (*)(void*, std::size_t, uint_t) {aka int (*)(void*, long unsigned int, unsigned int)}’ to ‘gnulib::_gl_getrandom_wrapper::type {aka long int (*)(void*, long unsigned int, unsigned int)}’ [-fpermissive]
 _GL_CXXALIAS_SYS (getrandom, ssize_t,
 ^

See https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html

Thus, we need to override the function if it has a different return type.


2020-05-30  Bruno Haible  <bruno@clisp.org>

	getrandom: Override incompatible system function on Solaris 11.
	* lib/sys_random.in.h (getrandom): Override if REPLACE_GETRANDOM is 1.
	* lib/getrandom.c (getrandom): When the system has getrandom, just
	invoke it.
	* m4/getrandom.m4 (gl_FUNC_GETRANDOM): Set REPLACE_GETRANDOM if the
	system's getrandom function's prototype is not the expected one.
	* m4/sys_random_h.m4 (gl_SYS_RANDOM_H_DEFAULTS): Initialize
	REPLACE_GETRANDOM.
	* modules/sys_random (Makefile.am): Substitute REPLACE_GETRANDOM.
	* modules/getrandom (modules/getrandom): Consider REPLACE_GETRANDOM.
	* tests/test-getrandom.c (main): Allow error EINVAL as an alternative to
	EAGAIN.
	* doc/glibc-functions/getrandom.texi: Mention the new module and the
	Solaris problem.

diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
index 2f4debc..2d93556 100644
--- a/doc/glibc-functions/getrandom.texi
+++ b/doc/glibc-functions/getrandom.texi
@@ -15,7 +15,7 @@ Documentation:
 @uref{https://www.kernel.org/doc/man-pages/online/pages/man2/getrandom.2.html,,man getrandom}.
 @end itemize
 
-Gnulib module: ---
+Gnulib module: getrandom
 
 Portability problems fixed by Gnulib:
 @itemize
@@ -23,6 +23,9 @@ Portability problems fixed by Gnulib:
 This function is missing on some platforms:
 glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8,
 Solaris 11.0, Android 9.0.
+@item
+This function has a different return type on some platforms:
+Solaris 11.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/getrandom.c b/lib/getrandom.c
index 9b6ecb4..f20ffe0 100644
--- a/lib/getrandom.c
+++ b/lib/getrandom.c
@@ -21,16 +21,21 @@
 
 #include <sys/random.h>
 
-#include "minmax.h"
 #include <fcntl.h>
 #include <stdbool.h>
 #include <unistd.h>
 
+#include "minmax.h"
+
 /* Set BUFFER (of size LENGTH) to random bytes under the control of FLAGS.
    Return the number of bytes written, or -1 on error.  */
 ssize_t
 getrandom (void *buffer, size_t length, unsigned int flags)
+#undef getrandom
 {
+#if HAVE_GETRANDOM
+  return getrandom (buffer, length, flags);
+#else
   static int randfd[2] = { -1, -1 };
   bool devrandom = (flags & GRND_RANDOM) != 0;
   int fd = randfd[devrandom];
@@ -49,4 +54,5 @@ getrandom (void *buffer, size_t length, unsigned int flags)
     }
 
   return read (fd, buffer, length);
+#endif
 }
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
index 3997cf4..4d12db9 100644
--- a/lib/sys_random.in.h
+++ b/lib/sys_random.in.h
@@ -51,13 +51,25 @@
 
 #if @GNULIB_GETRANDOM@
 /* Fill a buffer with random bytes.  */
-# if !@HAVE_GETRANDOM@
+# if @REPLACE_GETRANDOM@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef getrandom
+#   define getrandom rpl_getrandom
+#  endif
+_GL_FUNCDECL_RPL (getrandom, ssize_t,
+                  (void *buffer, size_t length, unsigned int flags)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (getrandom, ssize_t,
+                  (void *buffer, size_t length, unsigned int flags));
+# else
+#  if !@HAVE_GETRANDOM@
 _GL_FUNCDECL_SYS (getrandom, ssize_t,
                   (void *buffer, size_t length, unsigned int flags)
                   _GL_ARG_NONNULL ((1)));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (getrandom, ssize_t,
                   (void *buffer, size_t length, unsigned int flags));
+# endif
 _GL_CXXALIASWARN (getrandom);
 #elif defined GNULIB_POSIXCHECK
 # undef getrandom
diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
index 79e5520..9fee059 100644
--- a/m4/getrandom.m4
+++ b/m4/getrandom.m4
@@ -1,4 +1,4 @@
-# getrandom.m4 serial 2
+# getrandom.m4 serial 3
 dnl Copyright 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -12,5 +12,23 @@ AC_DEFUN([gl_FUNC_GETRANDOM],
   AC_CHECK_FUNCS_ONCE([getrandom])
   if test "$ac_cv_func_getrandom" != yes; then
     HAVE_GETRANDOM=0
+  else
+    dnl On Solaris 11.4 the return type is 'int', not 'ssize_t'.
+    AC_CACHE_CHECK([whether getrandom is compatible with its GNU+BSD signature],
+      [gl_cv_func_getrandom_ok],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#include <sys/random.h>
+              #include <sys/types.h>
+              ssize_t getrandom (void *, size_t, unsigned int);
+            ]],
+            [[]])
+         ],
+         [gl_cv_func_getrandom_ok=yes],
+         [gl_cv_func_getrandom_ok=no])
+      ])
+    if test $gl_cv_func_getrandom_ok = no; then
+      REPLACE_GETRANDOM=1
+    fi
   fi
 ])
diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
index d78307f..2ab96ef 100644
--- a/m4/sys_random_h.m4
+++ b/m4/sys_random_h.m4
@@ -1,4 +1,4 @@
-# sys_random_h.m4 serial 1
+# sys_random_h.m4 serial 2
 dnl Copyright (C) 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,4 +40,5 @@ AC_DEFUN([gl_SYS_RANDOM_H_DEFAULTS],
   GNULIB_GETRANDOM=0;     AC_SUBST([GNULIB_GETRANDOM])
   dnl Assume proper GNU behavior unless another module says otherwise.
   HAVE_GETRANDOM=1;       AC_SUBST([HAVE_GETRANDOM])
+  REPLACE_GETRANDOM=1;    AC_SUBST([REPLACE_GETRANDOM])
 ])
diff --git a/modules/getrandom b/modules/getrandom
index f7b3ff9..e94686d 100644
--- a/modules/getrandom
+++ b/modules/getrandom
@@ -8,13 +8,13 @@ m4/getrandom.m4
 Depends-on:
 sys_random
 crypto/gc-random    [test $HAVE_GETRANDOM = 0]
-fcntl-h             [test $HAVE_GETRANDOM = 0]
-minmax              [test $HAVE_GETRANDOM = 0]
-open                [test $HAVE_GETRANDOM = 0]
+fcntl-h             [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
+minmax              [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
+open                [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
 
 configure.ac:
 gl_FUNC_GETRANDOM
-if test $HAVE_GETRANDOM = 0; then
+if test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1; then
   AC_LIBOBJ([getrandom])
 fi
 gl_SYS_RANDOM_MODULE_INDICATOR([getrandom])
diff --git a/modules/sys_random b/modules/sys_random
index 1d0eb7c..b88507b 100644
--- a/modules/sys_random
+++ b/modules/sys_random
@@ -32,6 +32,7 @@ sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_N
 	      -e 's|@''HAVE_SYS_RANDOM_H''@|$(HAVE_SYS_RANDOM_H)|g' \
 	      -e 's/@''GNULIB_GETRANDOM''@/$(GNULIB_GETRANDOM)/g' \
 	      -e 's/@''HAVE_GETRANDOM''@/$(HAVE_GETRANDOM)/g' \
+	      -e 's/@''REPLACE_GETRANDOM''@/$(REPLACE_GETRANDOM)/g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
diff --git a/tests/test-getrandom.c b/tests/test-getrandom.c
index 3c84f87..8b25958 100644
--- a/tests/test-getrandom.c
+++ b/tests/test-getrandom.c
@@ -75,7 +75,8 @@ main (void)
   ret = getrandom (large_buf, sizeof (large_buf), GRND_RANDOM | GRND_NONBLOCK);
   /* It is very unlikely that so many truly random bytes were ready.  */
   if (ret < 0)
-    ASSERT (errno == ENOSYS || errno == EAGAIN);
+    ASSERT (errno == ENOSYS || errno == EAGAIN
+            || errno == EINVAL /* Solaris */);
   else
     ASSERT (ret > 0 && ret < sizeof (large_buf));
 



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH] getentropy, getrandom: new modules
  2020-05-30 12:58 ` Bruno Haible
@ 2020-05-30 22:43   ` Paul Eggert
  2020-05-31 11:23     ` getrandom vs. crypto/gc-random Bruno Haible
  0 siblings, 1 reply; 27+ messages in thread
From: Paul Eggert @ 2020-05-30 22:43 UTC (permalink / raw)
  To: Bruno Haible; +Cc: bug-gnulib

On 5/30/20 5:58 AM, Bruno Haible wrote:
> There are several problems with this commit:
>   - It causes a Continuous Integration failure.
>   - It partially overlaps with the crypto/gc-random module.
>   - The ChangeLog entry lists files that were not committed.
>   - It conflicts with the declaration on Solaris 11.3 and newer.
>   - It adds a new header file, <sys/random.h>, but without the usual
>     header file tests in C and C++.

Thanks for fixing most of those problems.

The remaining issue is "partial overlap with crypto/gc-random". To fix that, I
am thinking that getrandom should remove its dependency on crypto/gc-random, and
should simply use "/dev/urandom" for the nonce device without worrying about
whether crypto/gc-random would define NAME_OF_NONCE_DEVICE to "/dev/urandom".
This should work on all current porting targets and should simplify maintenance
by lessening dependencies on the crypto/gc-random module, which pulls in several
other modules that some packages won't want to bother with.


^ permalink raw reply	[flat|nested] 27+ messages in thread

* sys_random: Work around macOS bug
  2020-05-30 14:23 ` Bruno Haible
@ 2020-05-30 23:06   ` Bruno Haible
  2020-05-30 23:28     ` Jeffrey Walton
  0 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-05-30 23:06 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

On Mac OS X, the header file <sys/random.h> is not self-contained.

On Mac OS X 10.5:

  In file included from ./sys/random.h:28,
                   from ../../gllib/getrandom.c:22:
  /usr/include/sys/random.h:37: error: syntax error before ‘u_int’

It needs <sys/types.h> to be included first.

On Mac OS X 10.13:

  In file included from ../../gllib/getrandom.c:22:
  In file included from ./sys/random.h:28:
  /usr/include/sys/random.h:36:17: error: expected parameter declarator
  __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
                  ^

It needs <stdlib.h> or <unistd.h> to be included first.

This patch provides a workaround.


2020-05-30  Bruno Haible  <bruno@clisp.org>

	sys_random: Work around macOS bug.
	* m4/sys_random_h.m4 (gl_HEADER_SYS_RANDOM): Include <sys/types.h> and
	<stdlib.h> before <sys/random.h>.
	* m4/getrandom.m4 (gl_FUNC_GETRANDOM): Likewise.
	* lib/sys_random.in.h: On macOS, include <sys/types.h> and <stdlib.h>
	first.
	* doc/glibc-headers/sys_random.texi: Mention the macOS problem.

diff --git a/doc/glibc-headers/sys_random.texi b/doc/glibc-headers/sys_random.texi
index 1c28595..3f33962 100644
--- a/doc/glibc-headers/sys_random.texi
+++ b/doc/glibc-headers/sys_random.texi
@@ -24,6 +24,9 @@ Portability problems fixed by Gnulib:
 This header file is missing on some platforms:
 glibc 2.24, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.11, IRIX 6.5, Cygwin, mingw, MSVC 14.
 @item
+This header file is not self-contained on some platforms:
+Mac OS X 10.13.
+@item
 This header file does not declare the @code{getrandom} function on some platforms:
 Mac OS X 10.5, FreeBSD 11.0, HP-UX 11.31, Solaris 11.0.
 @end itemize
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
index 4d12db9..290fa39 100644
--- a/lib/sys_random.in.h
+++ b/lib/sys_random.in.h
@@ -23,6 +23,14 @@
 
 #if @HAVE_SYS_RANDOM_H@
 
+/* On Mac OS X 10.5, <sys/random.h> assumes prior inclusion of <sys/types.h>.
+   On Max OS X 10.13, <sys/random.h> assumes prior inclusion of a file that
+   includes <Availability.h>, such as <stdlib.h> or <unistd.h>.  */
+# if defined __APPLE__ && defined __MACH__                  /* Mac OS X */
+#  include <sys/types.h>
+#  include <stdlib.h>
+# endif
+
 /* The include_next requires a split double-inclusion guard.  */
 # @INCLUDE_NEXT@ @NEXT_SYS_RANDOM_H@
 
diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
index 9fee059..779c6ad 100644
--- a/m4/getrandom.m4
+++ b/m4/getrandom.m4
@@ -1,4 +1,4 @@
-# getrandom.m4 serial 3
+# getrandom.m4 serial 4
 dnl Copyright 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -18,8 +18,10 @@ AC_DEFUN([gl_FUNC_GETRANDOM],
       [gl_cv_func_getrandom_ok],
       [AC_COMPILE_IFELSE(
          [AC_LANG_PROGRAM(
-            [[#include <sys/random.h>
+            [[/* Additional includes are needed before <sys/random.h> on Mac OS X.  */
               #include <sys/types.h>
+              #include <stdlib.h>
+              #include <sys/random.h>
               ssize_t getrandom (void *, size_t, unsigned int);
             ]],
             [[]])
diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
index 135d241..c4505b6 100644
--- a/m4/sys_random_h.m4
+++ b/m4/sys_random_h.m4
@@ -1,4 +1,4 @@
-# sys_random_h.m4 serial 2
+# sys_random_h.m4 serial 3
 dnl Copyright (C) 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -20,6 +20,9 @@ AC_DEFUN([gl_HEADER_SYS_RANDOM],
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[
 #if HAVE_SYS_RANDOM_H
+/* Additional includes are needed before <sys/random.h> on Mac OS X.  */
+# include <sys/types.h>
+# include <stdlib.h>
 # include <sys/random.h>
 #endif
     ]],



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* fix list of crypto devices for NetBSD, OpenBSD
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
                   ` (3 preceding siblings ...)
  2020-05-30 15:34 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
@ 2020-05-30 23:14 ` Bruno Haible
  2020-05-31 10:57 ` fix list of crypto devices for Solaris Bruno Haible
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-30 23:14 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

The list of crypto devices in m4/gc-random.m4 is from 2006.

I get test failures of module 'getrandom' on current versions of
NetBSD and OpenBSD (NetBSD 7.0 and 9.0, and OpenBSD 6.5, to be precise).
These platforms have the quasi-standard /dev/random and /dev/urandom
meanwhile. No more /dev/srandom exists.

This patch fixes the test failures.


2020-05-30  Bruno Haible  <bruno@clisp.org>

	crypto/gc-random: Fix list of crypto devices for NetBSD, OpenBSD.
	* m4/gc-random.m4 (gl_GC_RANDOM): Don't special-case NetBSD and OpenBSD.

diff --git a/m4/gc-random.m4 b/m4/gc-random.m4
index 958c871..15751cb 100644
--- a/m4/gc-random.m4
+++ b/m4/gc-random.m4
@@ -1,4 +1,4 @@
-# gc-random.m4 serial 7
+# gc-random.m4 serial 8
 dnl Copyright (C) 2005-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -12,18 +12,12 @@ AC_DEFUN([gl_GC_RANDOM],
   AC_REQUIRE([AC_CANONICAL_HOST])
 
   case "$host_os" in
-    *openbsd* | *mirbsd*)
+    *mirbsd*)
       NAME_OF_RANDOM_DEVICE="/dev/srandom"
       NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/prandom"
       NAME_OF_NONCE_DEVICE="/dev/urandom"
       ;;
 
-    *netbsd*)
-      NAME_OF_RANDOM_DEVICE="/dev/srandom"
-      NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom"
-      NAME_OF_NONCE_DEVICE="/dev/urandom"
-      ;;
-
     *solaris* | *irix* | *dec-osf* )
       NAME_OF_RANDOM_DEVICE="/dev/random"
       NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/random"



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: sys_random: Work around macOS bug
  2020-05-30 23:06   ` sys_random: Work around macOS bug Bruno Haible
@ 2020-05-30 23:28     ` Jeffrey Walton
  2020-05-31 10:29       ` Apple platforms Bruno Haible
  0 siblings, 1 reply; 27+ messages in thread
From: Jeffrey Walton @ 2020-05-30 23:28 UTC (permalink / raw)
  To: bug-gnulib

On Sat, May 30, 2020 at 7:06 PM Bruno Haible <bruno@clisp.org> wrote:
>
> On Mac OS X, the header file <sys/random.h> is not self-contained.
>
> On Mac OS X 10.5:
>
>   In file included from ./sys/random.h:28,
>                    from ../../gllib/getrandom.c:22:
>   /usr/include/sys/random.h:37: error: syntax error before ‘u_int’
>
> It needs <sys/types.h> to be included first.
>
> On Mac OS X 10.13:
>
>   In file included from ../../gllib/getrandom.c:22:
>   In file included from ./sys/random.h:28:
>   /usr/include/sys/random.h:36:17: error: expected parameter declarator
>   __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
>                   ^
>
> It needs <stdlib.h> or <unistd.h> to be included first.
>
> This patch provides a workaround.
>
>
> 2020-05-30  Bruno Haible  <bruno@clisp.org>
>
>         sys_random: Work around macOS bug.
>         * m4/sys_random_h.m4 (gl_HEADER_SYS_RANDOM): Include <sys/types.h> and
>         <stdlib.h> before <sys/random.h>.
>         * m4/getrandom.m4 (gl_FUNC_GETRANDOM): Likewise.
>         * lib/sys_random.in.h: On macOS, include <sys/types.h> and <stdlib.h>
>         first.
>         * doc/glibc-headers/sys_random.texi: Mention the macOS problem.
>
> diff --git a/doc/glibc-headers/sys_random.texi b/doc/glibc-headers/sys_random.texi
> index 1c28595..3f33962 100644
> --- a/doc/glibc-headers/sys_random.texi
> +++ b/doc/glibc-headers/sys_random.texi
> @@ -24,6 +24,9 @@ Portability problems fixed by Gnulib:
>  This header file is missing on some platforms:
>  glibc 2.24, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.11, IRIX 6.5, Cygwin, mingw, MSVC 14.
>  @item
> +This header file is not self-contained on some platforms:
> +Mac OS X 10.13.
> +@item
>  This header file does not declare the @code{getrandom} function on some platforms:
>  Mac OS X 10.5, FreeBSD 11.0, HP-UX 11.31, Solaris 11.0.
>  @end itemize
> diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
> index 4d12db9..290fa39 100644
> --- a/lib/sys_random.in.h
> +++ b/lib/sys_random.in.h
> @@ -23,6 +23,14 @@
>
>  #if @HAVE_SYS_RANDOM_H@
>
> +/* On Mac OS X 10.5, <sys/random.h> assumes prior inclusion of <sys/types.h>.
> +   On Max OS X 10.13, <sys/random.h> assumes prior inclusion of a file that
> +   includes <Availability.h>, such as <stdlib.h> or <unistd.h>.  */
> +# if defined __APPLE__ && defined __MACH__                  /* Mac OS X */
> +#  include <sys/types.h>
> +#  include <stdlib.h>
> +# endif
> +
>  /* The include_next requires a split double-inclusion guard.  */
>  # @INCLUDE_NEXT@ @NEXT_SYS_RANDOM_H@
>
> diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
> index 9fee059..779c6ad 100644
> --- a/m4/getrandom.m4
> +++ b/m4/getrandom.m4
> @@ -1,4 +1,4 @@
> -# getrandom.m4 serial 3
> +# getrandom.m4 serial 4
>  dnl Copyright 2020 Free Software Foundation, Inc.
>  dnl This file is free software; the Free Software Foundation
>  dnl gives unlimited permission to copy and/or distribute it,
> @@ -18,8 +18,10 @@ AC_DEFUN([gl_FUNC_GETRANDOM],
>        [gl_cv_func_getrandom_ok],
>        [AC_COMPILE_IFELSE(
>           [AC_LANG_PROGRAM(
> -            [[#include <sys/random.h>
> +            [[/* Additional includes are needed before <sys/random.h> on Mac OS X.  */
>                #include <sys/types.h>
> +              #include <stdlib.h>
> +              #include <sys/random.h>
>                ssize_t getrandom (void *, size_t, unsigned int);
>              ]],
>              [[]])
> diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
> index 135d241..c4505b6 100644
> --- a/m4/sys_random_h.m4
> +++ b/m4/sys_random_h.m4
> @@ -1,4 +1,4 @@
> -# sys_random_h.m4 serial 2
> +# sys_random_h.m4 serial 3
>  dnl Copyright (C) 2020 Free Software Foundation, Inc.
>  dnl This file is free software; the Free Software Foundation
>  dnl gives unlimited permission to copy and/or distribute it,
> @@ -20,6 +20,9 @@ AC_DEFUN([gl_HEADER_SYS_RANDOM],
>    dnl corresponding gnulib module is not in use.
>    gl_WARN_ON_USE_PREPARE([[
>  #if HAVE_SYS_RANDOM_H
> +/* Additional includes are needed before <sys/random.h> on Mac OS X.  */
> +# include <sys/types.h>
> +# include <stdlib.h>
>  # include <sys/random.h>
>  #endif
>      ]],

On Apple platforms, when targeting specific devices like AppleTV, you
should include Apple's <TargetConditionals.h>.

You will also need <TargetConditionals.h> to determine platform
support for function calls like fork(). Not all Apple platforms
provide fork and friends.

Jeff


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Apple platforms
  2020-05-30 23:28     ` Jeffrey Walton
@ 2020-05-31 10:29       ` Bruno Haible
  0 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 10:29 UTC (permalink / raw)
  To: bug-gnulib, noloader

Jeffrey Walton wrote:
> On Apple platforms, when targeting specific devices like AppleTV, you
> should include Apple's <TargetConditionals.h>.
> 
> You will also need <TargetConditionals.h> to determine platform
> support for function calls like fork(). Not all Apple platforms
> provide fork and friends.

In GNU, we don't write software for Apple devices that put the users
into a jail. I think iOS devices are in this category; AppleTV and
AppleWatch probably as well.

The GPLv3 has provisions to legally disallow some of the GNU code on
such devices. The fact that we distribute parts of gnulib under other
licenses (such as LGPLv2+) does not mean that we endorse such practices
by Apple.

Compared to this, the fact that iOS does not have a file system in the
sense of POSIX - and therefore makes large parts of gnulib inapplicable -
is only a "minor" technical issue.

Bruno



^ permalink raw reply	[flat|nested] 27+ messages in thread

* fix list of crypto devices for Solaris
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
                   ` (4 preceding siblings ...)
  2020-05-30 23:14 ` fix list of crypto devices for NetBSD, OpenBSD Bruno Haible
@ 2020-05-31 10:57 ` Bruno Haible
  2020-05-31 16:26 ` getrandom: Add support for native Windows Bruno Haible
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 10:57 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

Solaris too (even Solaris 9) has /dev/random and /dev/urandom. The
manpage credits Linux:

     An  implementation  of  the  /dev/random  and   /dev/urandom
     kernel-based random number generator first appeared in Linux
     1.3.30.


2020-05-31  Bruno Haible  <bruno@clisp.org>

	crypto/gc-random: Fix list of crypto devices for Solaris.
	* m4/gc-random.m4 (gl_GC_RANDOM): Don't special-case Solaris.

diff --git a/m4/gc-random.m4 b/m4/gc-random.m4
index 15751cb..a7812a3 100644
--- a/m4/gc-random.m4
+++ b/m4/gc-random.m4
@@ -1,4 +1,4 @@
-# gc-random.m4 serial 8
+# gc-random.m4 serial 9
 dnl Copyright (C) 2005-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -18,7 +18,7 @@ AC_DEFUN([gl_GC_RANDOM],
       NAME_OF_NONCE_DEVICE="/dev/urandom"
       ;;
 
-    *solaris* | *irix* | *dec-osf* )
+    *irix* | *dec-osf* )
       NAME_OF_RANDOM_DEVICE="/dev/random"
       NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/random"
       NAME_OF_NONCE_DEVICE="/dev/random"



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-05-30 22:43   ` Paul Eggert
@ 2020-05-31 11:23     ` Bruno Haible
  2020-05-31 11:47       ` Bruno Haible
                         ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 11:23 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Simon Josefsson, bug-gnulib

Paul Eggert wrote:
> The remaining issue is "partial overlap with crypto/gc-random".

Yes. It has three aspects:

1) The list of random devices, determined through gc-random.m4.

> To fix that, I
> am thinking that getrandom should remove its dependency on crypto/gc-random, and
> should simply use "/dev/urandom" for the nonce device without worrying about
> whether crypto/gc-random would define NAME_OF_NONCE_DEVICE to "/dev/urandom".
> This should work on all current porting targets and should simplify maintenance
> by lessening dependencies on the crypto/gc-random module, which pulls in several
> other modules that some packages won't want to bother with.

I agree. In my testing yesterday, I found that /dev/random and /dev/urandom are
present in all modern versions of operating systems, except native Windows.
I tested:
  Linux Fedora 1       OK
  Linux Ubuntu 16.04   OK
  Linux Ubuntu 18.04   OK
  Linux Ubuntu 20.04   OK
  Linux Alpine 3.9     OK
  Hurd 2019            OK
  GNU/kFreeBSD         OK
  Mac OS X 10.5        OK
  Mac OS X 10.13       OK
  FreeBSD 11           OK
  FreeBSD 12           OK
  NetBSD 7.0           OK
  NetBSD 9.0           OK
  OpenBSD 6.5          OK
  AIX 7.1              OK
  Solaris 10           OK
  Solaris 11.0         OK
  Solaris 11.3         OK
  Solaris 11.4         OK
  Solaris OpenIndiana  OK
  Haiku                OK
  Cygwin               OK
  Minix 3.3            OK

Seeing this, the configure options --enable-random-device,
--enable-pseudo-random-device, --enable-nonce-device are not needed any more
- neither for gc-gnulib nor for getrandom. I won't remove them from gc-random.m4
(since that is Simon's responsibility), but I agree with you that for getrandom
we can use the two de-facto standard device names.

2) The native Windows code. For getrandom one will need a use of CryptGenRandom.
But refactoring this code in a way that makes it reusable by getrandom is more
effect than it's worth (because in gc-gnulib.c the code wants a failure already
in gc_init if the crypto context cannot be allocated, whereas for getrandom
we will just have getrandom fail).

3) There is the question whether getrandom() should be based on module
crypto/gc-random. That is, whether the configure script should accept an
option --with-libgcrypt, in order to use libgcrypt when available.
I think the answer is "no", for two reasons:
  * Would we want to override the glibc function getrandom() with an
    implementation that requires an external library? Most likely no.
  * I think libgcrypt is for programs that have strong cryptographic
    needs, such as gpg or ssh-keygen. For most other programs, the system-
    provided /dev/random should be enough.
    As the unit test is showing, /dev/random does not have the highest quality
    of random numbers (at least, it does not block when you ask for 100000
    random bytes) on
      Hurd, Mac OS X, FreeBSD, OpenBSD, AIX, Minix, Haiku,
    but this quality-of-implementation issue should be ignorable for things
    like https. libgcrypt is accumulating the entropy through subprocesses,
    which is likely overkill for a simple application like 'wget' or 'ssh'.

CCing Simon, because he may enlighten us on this.

Bruno



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-05-31 11:23     ` getrandom vs. crypto/gc-random Bruno Haible
@ 2020-05-31 11:47       ` Bruno Haible
  2020-05-31 13:14       ` Jeffrey Walton
  2020-05-31 13:23       ` Simon Josefsson
  2 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 11:47 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Simon Josefsson, bug-gnulib

> 1) The list of random devices, determined through gc-random.m4.
> 
> > To fix that, I
> > am thinking that getrandom should remove its dependency on crypto/gc-random, and
> > should simply use "/dev/urandom" for the nonce device without worrying about
> > whether crypto/gc-random would define NAME_OF_NONCE_DEVICE to "/dev/urandom".
> > This should work on all current porting targets and should simplify maintenance
> > by lessening dependencies on the crypto/gc-random module, which pulls in several
> > other modules that some packages won't want to bother with.
> 
> I agree. In my testing yesterday, I found that /dev/random and /dev/urandom are
> present in all modern versions of operating systems, except native Windows.
> I tested:
>   Linux Fedora 1       OK
>   Linux Ubuntu 16.04   OK
>   Linux Ubuntu 18.04   OK
>   Linux Ubuntu 20.04   OK
>   Linux Alpine 3.9     OK
>   Hurd 2019            OK
>   GNU/kFreeBSD         OK
>   Mac OS X 10.5        OK
>   Mac OS X 10.13       OK
>   FreeBSD 11           OK
>   FreeBSD 12           OK
>   NetBSD 7.0           OK
>   NetBSD 9.0           OK
>   OpenBSD 6.5          OK
>   AIX 7.1              OK
>   Solaris 10           OK
>   Solaris 11.0         OK
>   Solaris 11.3         OK
>   Solaris 11.4         OK
>   Solaris OpenIndiana  OK
>   Haiku                OK
>   Cygwin               OK
>   Minix 3.3            OK
> 
> Seeing this, the configure options --enable-random-device,
> --enable-pseudo-random-device, --enable-nonce-device are not needed any more
> - neither for gc-gnulib nor for getrandom. I won't remove them from gc-random.m4
> (since that is Simon's responsibility), but I agree with you that for getrandom
> we can use the two de-facto standard device names.

Done as follows.


2020-05-31  Bruno Haible  <bruno@clisp.org>

	getrandom: Simplify the determination of the random number devices.
	Suggested by Paul Eggert in
	<https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00383.html>.
	* lib/getrandom.c (NAME_OF_RANDOM_DEVICE, NAME_OF_NONCE_DEVICE): New
	macros.
	* modules/getrandom (Depends-on): Remove crypto/gc-random.

diff --git a/lib/getrandom.c b/lib/getrandom.c
index f20ffe0..0cc3dc3 100644
--- a/lib/getrandom.c
+++ b/lib/getrandom.c
@@ -27,6 +27,25 @@
 
 #include "minmax.h"
 
+/* These devices exist on all platforms except native Windows.  */
+#if !(defined _WIN32 && ! defined __CYGWIN__)
+
+/* Name of a device through which the kernel returns high quality random
+   numbers, from an entropy pool.  When the pool is empty, the call blocks
+   until entropy sources have added enough bits of entropy.  */
+# ifndef NAME_OF_RANDOM_DEVICE
+#  define NAME_OF_RANDOM_DEVICE "/dev/random"
+# endif
+
+/* Name of a device through which the kernel returns random or pseudo-random
+   numbers.  It uses an entropy pool, but, in order to avoid blocking, adds
+   bits generated by a pseudo-random number generator, as needed.  */
+# ifndef NAME_OF_NONCE_DEVICE
+#  define NAME_OF_NONCE_DEVICE "/dev/urandom"
+# endif
+
+#endif
+
 /* Set BUFFER (of size LENGTH) to random bytes under the control of FLAGS.
    Return the number of bytes written, or -1 on error.  */
 ssize_t
diff --git a/modules/getrandom b/modules/getrandom
index e94686d..8aa4be2 100644
--- a/modules/getrandom
+++ b/modules/getrandom
@@ -7,7 +7,6 @@ m4/getrandom.m4
 
 Depends-on:
 sys_random
-crypto/gc-random    [test $HAVE_GETRANDOM = 0]
 fcntl-h             [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
 minmax              [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]
 open                [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1]



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-05-31 11:23     ` getrandom vs. crypto/gc-random Bruno Haible
  2020-05-31 11:47       ` Bruno Haible
@ 2020-05-31 13:14       ` Jeffrey Walton
  2020-05-31 13:23       ` Simon Josefsson
  2 siblings, 0 replies; 27+ messages in thread
From: Jeffrey Walton @ 2020-05-31 13:14 UTC (permalink / raw)
  To: Bruno Haible; +Cc: Simon Josefsson, Paul Eggert, bug-gnulib

On Sun, May 31, 2020 at 7:23 AM Bruno Haible <bruno@clisp.org> wrote:
>
>  ...
> 3) There is the question whether getrandom() should be based on module
> crypto/gc-random. That is, whether the configure script should accept an
> option --with-libgcrypt, in order to use libgcrypt when available.
> I think the answer is "no", for two reasons:
>   * Would we want to override the glibc function getrandom() with an
>     implementation that requires an external library? Most likely no.
>   * I think libgcrypt is for programs that have strong cryptographic
>     needs, such as gpg or ssh-keygen. For most other programs, the system-
>     provided /dev/random should be enough.

/dev/random should no longer be used on Linux. See
https://lkml.org/lkml/2017/7/20/993.

Jeff


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-05-31 11:23     ` getrandom vs. crypto/gc-random Bruno Haible
  2020-05-31 11:47       ` Bruno Haible
  2020-05-31 13:14       ` Jeffrey Walton
@ 2020-05-31 13:23       ` Simon Josefsson
  2020-05-31 19:02         ` Bruno Haible
  2 siblings, 1 reply; 27+ messages in thread
From: Simon Josefsson @ 2020-05-31 13:23 UTC (permalink / raw)
  To: Bruno Haible, Paul Eggert; +Cc: bug-gnulib

[-- Attachment #1: Type: text/plain, Size: 1232 bytes --]

There is a lot to be said about randomness, but for the purpose of
getrandom() and getentropy(), which to my knowledge aren't globally
standardized (de-factor or otherwise) and well-specified what semantics
re cryptographic properties they should have, I agree it make sense to
keep the implementation small and using gc-random probably causes more
problems than it solves.

Historically, the problem is that for cryptographic purposes,
/dev/random and /dev/urandom can be a really bad choice on many
platforms.  This has probably been improved over the years, especially
on the most relevant platforms, but still: for any application that
needs portable randomness for some particular crypto property, the
getrandom, getentropy, and /dev/*random interfaces are not sufficient. 
The gc-random module wasn't really perfect in this regard, it required
that people used libgcrypt or provided a known-good randomness device
that is different for every platform .  The gc-random logic was
incomplete here.

There ought to be a word about in the gnulib documentation for
getrandom() and getentropy() so that applications don't assume these
gnulib modules provides crypto-strength output on all platforms.

/Simon


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* getrandom: Add support for native Windows
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
                   ` (5 preceding siblings ...)
  2020-05-31 10:57 ` fix list of crypto devices for Solaris Bruno Haible
@ 2020-05-31 16:26 ` Bruno Haible
  2020-05-31 16:41   ` Jeffrey Walton
  2020-05-31 16:49 ` getrandom: doc and test tweaks Bruno Haible
  2020-05-31 18:15 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
  8 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 16:26 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Jeffrey Walton, Paul Eggert

Native Windows is the only platform without the /dev/random and
/dev/urandom devices; it therefore needs special code.

Jeffrey Walton wrote:
> On modern Windows systems you should use BCryptGenRandom for the
> material. CryptGenRandom is deprecated.

Thanks for the pointer.

This patch implements it: try BCryptGenRandom first, and fall back on
CryptGenRandom.


2020-05-31  Bruno Haible  <bruno@clisp.org>

	getrandom: Add support for native Windows.
	* lib/getrandom.c: Include <errno.h>, <windows.h>, <bcrypt.h>,
	<wincrypt.h>.
	(CRYPT_VERIFY_CONTEXT): New macro.
	(LoadLibrary, CryptAcquireContext): Redirect to the variant with suffix
	'A'.
	(GetProcAddress): New macro.
	(BCryptGenRandomFuncType): New type.
	(BCryptGenRandomFunc, initialized): New variables.
	(initialize): New function.
	(getrandom): On native Windows, use <bcrypt.h> API when available, and
	<wincrypt.h> API as fallback.
	* m4/getrandom.m4 (gl_FUNC_GETRANDOM): Set LIB_GETRANDOM.
	* modules/getrandom (Link): New section.
	* modules/getentropy (Link): Likewise.
	* modules/getrandom-tests (Makefile.am): Link test-getrandom against
	$(LIB_GETRANDOM).
	* modules/getentropy-tests (Makefile.am): Link test-getentropy against
	$(LIB_GETRANDOM).
	* modules/sys_random-c++-tests (Makefile.am): Link test-sys_random-c++
	against $(LIB_GETRANDOM).
	* doc/glibc-functions/getrandom.texi: Mention the native Windows
	support.

diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
index 2d93556..99712c7 100644
--- a/doc/glibc-functions/getrandom.texi
+++ b/doc/glibc-functions/getrandom.texi
@@ -22,7 +22,7 @@ Portability problems fixed by Gnulib:
 @item
 This function is missing on some platforms:
 glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8,
-Solaris 11.0, Android 9.0.
+Solaris 11.0, mingw, MSVC 14, Android 9.0.
 @item
 This function has a different return type on some platforms:
 Solaris 11.4.
@@ -32,5 +32,5 @@ Portability problems not fixed by Gnulib:
 @itemize
 @item
 This function is missing on some platforms:
-Minix 3.1.8, IRIX 6.5, mingw, MSVC 14.
+Minix 3.1.8, IRIX 6.5.
 @end itemize
diff --git a/lib/getrandom.c b/lib/getrandom.c
index 0cc3dc3..ad49cae 100644
--- a/lib/getrandom.c
+++ b/lib/getrandom.c
@@ -21,14 +21,65 @@
 
 #include <sys/random.h>
 
+#include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
 #include <unistd.h>
 
+#if defined _WIN32 && ! defined __CYGWIN__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <bcrypt.h>
+# if !HAVE_LIB_BCRYPT
+#  include <wincrypt.h>
+#  ifndef CRYPT_VERIFY_CONTEXT
+#   define CRYPT_VERIFY_CONTEXT 0xF0000000
+#  endif
+# endif
+#endif
+
 #include "minmax.h"
 
+#if defined _WIN32 && ! defined __CYGWIN__
+
+/* Don't assume that UNICODE is not defined.  */
+# undef LoadLibrary
+# define LoadLibrary LoadLibraryA
+# undef CryptAcquireContext
+# define CryptAcquireContext CryptAcquireContextA
+
+# if !HAVE_LIB_BCRYPT
+
+/* Avoid warnings from gcc -Wcast-function-type.  */
+#  define GetProcAddress \
+    (void *) GetProcAddress
+
+/* BCryptGenRandom with the BCRYPT_USE_SYSTEM_PREFERRED_RNG flag works only
+   starting with Windows 7.  */
+typedef NTSTATUS (WINAPI * BCryptGenRandomFuncType) (BCRYPT_ALG_HANDLE, UCHAR *, ULONG, ULONG);
+static BCryptGenRandomFuncType BCryptGenRandomFunc = NULL;
+static BOOL initialized = FALSE;
+
+static void
+initialize (void)
+{
+  HMODULE bcrypt = LoadLibrary ("bcrypt.dll");
+  if (bcrypt != NULL)
+    {
+      BCryptGenRandomFunc =
+        (BCryptGenRandomFuncType) GetProcAddress (bcrypt, "BCryptGenRandom");
+    }
+  initialized = TRUE;
+}
+
+# else
+
+#  define BCryptGenRandomFunc BCryptGenRandom
+
+# endif
+
+#else
 /* These devices exist on all platforms except native Windows.  */
-#if !(defined _WIN32 && ! defined __CYGWIN__)
 
 /* Name of a device through which the kernel returns high quality random
    numbers, from an entropy pool.  When the pool is empty, the call blocks
@@ -52,7 +103,56 @@ ssize_t
 getrandom (void *buffer, size_t length, unsigned int flags)
 #undef getrandom
 {
-#if HAVE_GETRANDOM
+#if defined _WIN32 && ! defined __CYGWIN__
+  /* BCryptGenRandom, defined in <bcrypt.h>
+     <https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom>
+     with the BCRYPT_USE_SYSTEM_PREFERRED_RNG flag
+     works in Windows 7 and newer.  */
+  static int bcrypt_not_working /* = 0 */;
+  if (!bcrypt_not_working)
+    {
+# if !HAVE_LIB_BCRYPT
+      if (!initialized)
+        initialize ();
+# endif
+      if (BCryptGenRandomFunc != NULL
+          && BCryptGenRandomFunc (NULL, buffer, length,
+                                  BCRYPT_USE_SYSTEM_PREFERRED_RNG)
+             == 0 /*STATUS_SUCCESS*/)
+        return length;
+      bcrypt_not_working = 1;
+    }
+# if !HAVE_LIB_BCRYPT
+  /* CryptGenRandom, defined in <wincrypt.h>
+     <https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom>
+     works in older releases as well, but is now deprecated.
+     CryptAcquireContext, defined in <wincrypt.h>
+     <https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta>  */
+  {
+    static int crypt_initialized /* = 0 */;
+    static HCRYPTPROV provider;
+    if (!crypt_initialized)
+      {
+        if (CryptAcquireContext (&provider, NULL, NULL, PROV_RSA_FULL,
+                                 CRYPT_VERIFY_CONTEXT))
+          crypt_initialized = 1;
+        else
+          crypt_initialized = -1;
+      }
+    if (crypt_initialized >= 0)
+      {
+        if (!CryptGenRandom (provider, length, buffer))
+          {
+            errno = EIO;
+            return -1;
+          }
+        return length;
+      }
+  }
+# endif
+  errno = ENOSYS;
+  return -1;
+#elif HAVE_GETRANDOM
   return getrandom (buffer, length, flags);
 #else
   static int randfd[2] = { -1, -1 };
diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
index 779c6ad..37fb100 100644
--- a/m4/getrandom.m4
+++ b/m4/getrandom.m4
@@ -1,4 +1,4 @@
-# getrandom.m4 serial 4
+# getrandom.m4 serial 5
 dnl Copyright 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -33,4 +33,32 @@ AC_DEFUN([gl_FUNC_GETRANDOM],
       REPLACE_GETRANDOM=1
     fi
   fi
+
+  case "$host_os" in
+    mingw*)
+      AC_CACHE_CHECK([whether the bcrypt library is guaranteed to be present],
+        [gl_cv_lib_assume_bcrypt],
+        [AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[#include <windows.h>]],
+              [[#if !(_WIN32_WINNT >= _WIN32_WINNT_WIN7)
+                  cannot assume it
+                #endif
+              ]])
+           ],
+           [gl_cv_lib_assume_bcrypt=yes],
+           [gl_cv_lib_assume_bcrypt=no])
+        ])
+      if test $gl_cv_lib_assume_bcrypt = yes; then
+        AC_DEFINE([HAVE_LIB_BCRYPT], [1],
+          [Define to 1 if the bcrypt library is guaranteed to be present.])
+        LIB_GETRANDOM='-lbcrypt'
+      else
+        LIB_GETRANDOM='-ladvapi32'
+      fi
+      ;;
+    *)
+      LIB_GETRANDOM= ;;
+  esac
+  AC_SUBST([LIB_GETRANDOM])
 ])
diff --git a/modules/getentropy b/modules/getentropy
index 9696c1e..680aa47 100644
--- a/modules/getentropy
+++ b/modules/getentropy
@@ -22,6 +22,9 @@ Makefile.am:
 Include:
 <unistd.h>
 
+Link:
+$(LIB_GETRANDOM)
+
 License:
 LGPL
 
diff --git a/modules/getentropy-tests b/modules/getentropy-tests
index b5c4b11..7ad7861 100644
--- a/modules/getentropy-tests
+++ b/modules/getentropy-tests
@@ -10,3 +10,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-getentropy
 check_PROGRAMS += test-getentropy
+test_getentropy_LDADD = $(LDADD) $(LIB_GETRANDOM)
diff --git a/modules/getrandom b/modules/getrandom
index 8aa4be2..76437eb 100644
--- a/modules/getrandom
+++ b/modules/getrandom
@@ -23,6 +23,9 @@ Makefile.am:
 Include:
 <sys/random.h>
 
+Link:
+$(LIB_GETRANDOM)
+
 License:
 LGPL
 
diff --git a/modules/getrandom-tests b/modules/getrandom-tests
index 8982173..b7f64dd 100644
--- a/modules/getrandom-tests
+++ b/modules/getrandom-tests
@@ -10,3 +10,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-getrandom
 check_PROGRAMS += test-getrandom
+test_getrandom_LDADD = $(LDADD) @LIB_GETRANDOM@
diff --git a/modules/sys_random-c++-tests b/modules/sys_random-c++-tests
index e07d81f..5b3c505 100644
--- a/modules/sys_random-c++-tests
+++ b/modules/sys_random-c++-tests
@@ -15,4 +15,5 @@ if ANSICXX
 TESTS += test-sys_random-c++
 check_PROGRAMS += test-sys_random-c++
 test_sys_random_c___SOURCES = test-sys_random-c++.cc
+test_sys_random_c___LDADD = $(LDADD) $(LIB_GETRANDOM)
 endif



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: getrandom: Add support for native Windows
  2020-05-31 16:26 ` getrandom: Add support for native Windows Bruno Haible
@ 2020-05-31 16:41   ` Jeffrey Walton
  0 siblings, 0 replies; 27+ messages in thread
From: Jeffrey Walton @ 2020-05-31 16:41 UTC (permalink / raw)
  To: bug-gnulib

On Sun, May 31, 2020 at 12:26 PM Bruno Haible <bruno@clisp.org> wrote:
>
> Native Windows is the only platform without the /dev/random and
> /dev/urandom devices; it therefore needs special code.
>
> Jeffrey Walton wrote:
> > On modern Windows systems you should use BCryptGenRandom for the
> > material. CryptGenRandom is deprecated.
>
> Thanks for the pointer.
>
> This patch implements it: try BCryptGenRandom first, and fall back on
> CryptGenRandom.

There's one platform you might have some trouble with because neither
CryptGenRandom or BCryptGenRandom are available. That's Windows Phone
8 and Windows Store 8.

I have never experienced the problem in practice. I don't think anyone
bothers writing code for Windows Phone 8.

Also see https://social.msdn.microsoft.com/Forums/vstudio/en-US/25b83e13-c85f-4aa1-a057-88a279ea3fd6/what-crypto-random-generator-c-code-could-use-on-wp81.

Jeff


^ permalink raw reply	[flat|nested] 27+ messages in thread

* getrandom: doc and test tweaks
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
                   ` (6 preceding siblings ...)
  2020-05-31 16:26 ` getrandom: Add support for native Windows Bruno Haible
@ 2020-05-31 16:49 ` Bruno Haible
  2020-05-31 18:15 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
  8 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 16:49 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

Adding some more precision to the documentation, and tweaking the unit test.


2020-05-31  Bruno Haible  <bruno@clisp.org>

	getrandom: Doc and test tweaks.
	* lib/getrandom.c (getrandom): Mention that it never returns 0, and that
	it sets errno when failing.
	* tests/test-getrandom.c (main): Disable the high-quality check on those
	platforms on which it fails.
	* doc/glibc-functions/getrandom.texi: Add Minix, AIX, HP-UX, IRIX,
	Cygwin to the list of platforms that don't have the function. Add a note
	about the quality of the result.
	* doc/glibc-headers/sys_random.texi: Don't mention the 'getrandom'
	declaration; this is fixed by module 'getrandom'.

diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
index 99712c7..3baf390 100644
--- a/doc/glibc-functions/getrandom.texi
+++ b/doc/glibc-functions/getrandom.texi
@@ -21,8 +21,7 @@ Portability problems fixed by Gnulib:
 @itemize
 @item
 This function is missing on some platforms:
-glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8,
-Solaris 11.0, mingw, MSVC 14, Android 9.0.
+glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.0, Cygwin, mingw, MSVC 14, Android 9.0.
 @item
 This function has a different return type on some platforms:
 Solaris 11.4.
@@ -30,7 +29,6 @@ Solaris 11.4.
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-Minix 3.1.8, IRIX 6.5.
+This function cannot produce truly random numbers on some platforms:
+GNU/Hurd, Mac OS X, GNU/kFreeBSD, FreeBSD 12.0, OpenBSD 6.5, Minix 3.3, AIX 7.1, Haiku, mingw, MSVC 14.
 @end itemize
diff --git a/doc/glibc-headers/sys_random.texi b/doc/glibc-headers/sys_random.texi
index 3f33962..8f5951d 100644
--- a/doc/glibc-headers/sys_random.texi
+++ b/doc/glibc-headers/sys_random.texi
@@ -26,9 +26,6 @@ glibc 2.24, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.11, IRIX 6.5
 @item
 This header file is not self-contained on some platforms:
 Mac OS X 10.13.
-@item
-This header file does not declare the @code{getrandom} function on some platforms:
-Mac OS X 10.5, FreeBSD 11.0, HP-UX 11.31, Solaris 11.0.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/getrandom.c b/lib/getrandom.c
index ad49cae..f0b3f53 100644
--- a/lib/getrandom.c
+++ b/lib/getrandom.c
@@ -98,7 +98,8 @@ initialize (void)
 #endif
 
 /* Set BUFFER (of size LENGTH) to random bytes under the control of FLAGS.
-   Return the number of bytes written, or -1 on error.  */
+   Return the number of bytes written (> 0).
+   Upon error, return -1 and set errno.  */
 ssize_t
 getrandom (void *buffer, size_t length, unsigned int flags)
 #undef getrandom
diff --git a/tests/test-getrandom.c b/tests/test-getrandom.c
index 8b25958..f4a31c6 100644
--- a/tests/test-getrandom.c
+++ b/tests/test-getrandom.c
@@ -73,12 +73,37 @@ main (void)
 
   /* Check that GRND_NONBLOCK works.  */
   ret = getrandom (large_buf, sizeof (large_buf), GRND_RANDOM | GRND_NONBLOCK);
+  ASSERT (ret <= (ssize_t) sizeof (large_buf));
   /* It is very unlikely that so many truly random bytes were ready.  */
   if (ret < 0)
     ASSERT (errno == ENOSYS || errno == EAGAIN
             || errno == EINVAL /* Solaris */);
   else
-    ASSERT (ret > 0 && ret < sizeof (large_buf));
+    {
+      ASSERT (ret > 0);
+      /* This assertion fails on
+           - GNU/Hurd,
+           - Mac OS X,
+           - GNU/kFreeBSD, FreeBSD 12.0,
+           - OpenBSD 6.5,
+           - Minix 3.3,
+           - AIX 7.1,
+           - Haiku,
+           - native Windows.
+         This indicates that the function, when called with GRND_RANDOM flag,
+         probably does not return truly random numbers, but instead uses a
+         pseudo-random number generator.  */
+#if !(defined __GNU__ || (defined __APPLE__ && defined __MACH__) || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __minix || defined _AIX || defined __HAIKU__ || (defined _WIN32 && ! defined __CYGWIN__))
+      ASSERT (ret < (ssize_t) sizeof (large_buf));
+#endif
+    }
+
+  if (getrandom (buf1, 1, 0) < 1)
+    if (getrandom (buf1, 1, GRND_RANDOM) < 1)
+      {
+        fputs ("Skipping test: getrandom is ineffective\n", stderr);
+        return 77;
+      }
 
   return 0;
 }



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH] getentropy, getrandom: new modules
  2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
                   ` (7 preceding siblings ...)
  2020-05-31 16:49 ` getrandom: doc and test tweaks Bruno Haible
@ 2020-05-31 18:15 ` Bruno Haible
  8 siblings, 0 replies; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 18:15 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

[-- Attachment #1: Type: text/plain, Size: 811 bytes --]

Now that we're done with the 'getrandom' module, a fix and a tweak for
the 'getentropy' module.


2020-05-31  Bruno Haible  <bruno@clisp.org>

	getentropy: Enhance tests.
	* tests/test-getentropy.c (main): Add one more test.
	* tests/test-unistd-c++.cc: Check the signature of getentropy.

2020-05-31  Bruno Haible  <bruno@clisp.org>

	getentropy: Work around a macOS and Solaris problem.
	* lib/unistd.in.h: Include <sys/random.h>, when needed for the
	'getentropy' module.
	* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize
	UNISTD_H_HAVE_SYS_RANDOM_H.
	* m4/sys_random_h.m4 (gl_HEADER_SYS_RANDOM): Set
	UNISTD_H_HAVE_SYS_RANDOM_H.
	* modules/unistd (Makefile.am): Substitute UNISTD_H_HAVE_SYS_RANDOM_H.
	* doc/glibc-functions/getentropy.texi: Document the macOS and Solaris
	problem. List more platforms.


[-- Attachment #2: 0001-getentropy-Work-around-a-macOS-and-Solaris-problem.patch --]
[-- Type: text/x-patch, Size: 5925 bytes --]

From 7ed87a1bcaabe12c823b46f67b4e36402581f41e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 31 May 2020 20:12:04 +0200
Subject: [PATCH 1/2] getentropy: Work around a macOS and Solaris problem.

* lib/unistd.in.h: Include <sys/random.h>, when needed for the
'getentropy' module.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize
UNISTD_H_HAVE_SYS_RANDOM_H.
* m4/sys_random_h.m4 (gl_HEADER_SYS_RANDOM): Set
UNISTD_H_HAVE_SYS_RANDOM_H.
* modules/unistd (Makefile.am): Substitute UNISTD_H_HAVE_SYS_RANDOM_H.
* doc/glibc-functions/getentropy.texi: Document the macOS and Solaris
problem. List more platforms.
---
 ChangeLog                           | 13 +++++++++++++
 doc/glibc-functions/getentropy.texi | 10 +++++-----
 lib/unistd.in.h                     | 11 +++++++++++
 m4/sys_random_h.m4                  |  7 ++++++-
 m4/unistd_h.m4                      |  3 ++-
 modules/unistd                      |  1 +
 6 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ecb8d4b..8f03864 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2020-05-31  Bruno Haible  <bruno@clisp.org>
 
+	getentropy: Work around a macOS and Solaris problem.
+	* lib/unistd.in.h: Include <sys/random.h>, when needed for the
+	'getentropy' module.
+	* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize
+	UNISTD_H_HAVE_SYS_RANDOM_H.
+	* m4/sys_random_h.m4 (gl_HEADER_SYS_RANDOM): Set
+	UNISTD_H_HAVE_SYS_RANDOM_H.
+	* modules/unistd (Makefile.am): Substitute UNISTD_H_HAVE_SYS_RANDOM_H.
+	* doc/glibc-functions/getentropy.texi: Document the macOS and Solaris
+	problem. List more platforms.
+
+2020-05-31  Bruno Haible  <bruno@clisp.org>
+
 	getrandom: Doc and test tweaks.
 	* lib/getrandom.c (getrandom): Mention that it never returns 0, and that
 	it sets errno when failing.
diff --git a/doc/glibc-functions/getentropy.texi b/doc/glibc-functions/getentropy.texi
index 5281dcd..b7717e5 100644
--- a/doc/glibc-functions/getentropy.texi
+++ b/doc/glibc-functions/getentropy.texi
@@ -21,13 +21,13 @@ Portability problems fixed by Gnulib:
 @itemize
 @item
 This function is missing on some platforms:
-glibc 2.24, Mac OS X 10.5, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8,
-Solaris 11.0, Android 9.0.
+glibc 2.24, Mac OS X 10.11, FreeBSD 11.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.0, Cygwin, mingw, MSVC 14, Android 9.0.
+@item
+This function is declared in @code{<sys/random.h>}, not in @code{<unistd.h>},
+on some platforms:
+Mac OS X 10.13, Solaris 11.4, Android 9.0.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-Minix 3.1.8, IRIX 6.5, mingw, MSVC 14.
 @end itemize
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 906f806..71904fe 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -118,6 +118,17 @@
 # include <netdb.h>
 #endif
 
+/* Mac OS X 10.13, Solaris 11.4, and Android 9.0 declare getentropy in
+   <sys/random.h>, not in <unistd.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if (@GNULIB_GETENTROPY@ || defined GNULIB_POSIXCHECK) \
+    && ((defined __APPLE__ && defined __MACH__) || defined __sun \
+        || defined __ANDROID__) \
+    && @UNISTD_H_HAVE_SYS_RANDOM_H@ \
+    && !defined __GLIBC__
+# include <sys/random.h>
+#endif
+
 /* Android 4.3 declares fchownat in <sys/stat.h>, not in <unistd.h>.  */
 /* But avoid namespace pollution on glibc systems.  */
 #if (@GNULIB_FCHOWNAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \
diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
index c4505b6..a964b15 100644
--- a/m4/sys_random_h.m4
+++ b/m4/sys_random_h.m4
@@ -1,4 +1,4 @@
-# sys_random_h.m4 serial 3
+# sys_random_h.m4 serial 4
 dnl Copyright (C) 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -16,6 +16,11 @@ AC_DEFUN([gl_HEADER_SYS_RANDOM],
   fi
   AC_SUBST([HAVE_SYS_RANDOM_H])
 
+  m4_ifdef([gl_UNISTD_H_DEFAULTS], [AC_REQUIRE([gl_UNISTD_H_DEFAULTS])])
+  if test $ac_cv_header_sys_random_h = yes; then
+    UNISTD_H_HAVE_SYS_RANDOM_H=1
+  fi
+
   dnl Check for declarations of anything we want to poison if the
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index a3b4633..dfa38f8 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 79
+# unistd_h.m4 serial 80
 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -200,6 +200,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   REPLACE_UNLINKAT=0;     AC_SUBST([REPLACE_UNLINKAT])
   REPLACE_USLEEP=0;       AC_SUBST([REPLACE_USLEEP])
   REPLACE_WRITE=0;        AC_SUBST([REPLACE_WRITE])
+  UNISTD_H_HAVE_SYS_RANDOM_H=0; AC_SUBST([UNISTD_H_HAVE_SYS_RANDOM_H])
   UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H])
   UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0;
                            AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS])
diff --git a/modules/unistd b/modules/unistd
index f075b78..5550646 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -174,6 +174,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
 	      -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \
 	      -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \
+	      -e 's|@''UNISTD_H_HAVE_SYS_RANDOM_H''@|$(UNISTD_H_HAVE_SYS_RANDOM_H)|g' \
 	      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \
 	      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-- 
2.7.4


[-- Attachment #3: 0002-getentropy-Enhance-tests.patch --]
[-- Type: text/x-patch, Size: 2176 bytes --]

From c73b331059b79e9d53c9c7ad3a905580f292d972 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 31 May 2020 20:13:27 +0200
Subject: [PATCH 2/2] getentropy: Enhance tests.

* tests/test-getentropy.c (main): Add one more test.
* tests/test-unistd-c++.cc: Check the signature of getentropy.
---
 ChangeLog                |  6 ++++++
 tests/test-getentropy.c  | 11 +++++++++++
 tests/test-unistd-c++.cc |  4 ++++
 3 files changed, 21 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 8f03864..fbda5ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-05-31  Bruno Haible  <bruno@clisp.org>
 
+	getentropy: Enhance tests.
+	* tests/test-getentropy.c (main): Add one more test.
+	* tests/test-unistd-c++.cc: Check the signature of getentropy.
+
+2020-05-31  Bruno Haible  <bruno@clisp.org>
+
 	getentropy: Work around a macOS and Solaris problem.
 	* lib/unistd.in.h: Include <sys/random.h>, when needed for the
 	'getentropy' module.
diff --git a/tests/test-getentropy.c b/tests/test-getentropy.c
index 845c5dc..8659b6d 100644
--- a/tests/test-getentropy.c
+++ b/tests/test-getentropy.c
@@ -39,5 +39,16 @@ main (int argc, char *argv[])
   /* This test fails with probability 2**-2048.  (Run it again if so. :-) */
   ASSERT (memcmp (buf, empty_buf, sizeof buf) != 0);
 
+  /* It is very unlikely that two calls to getentropy produce the same
+     results.  */
+  {
+    char buf1[8];
+    char buf2[8];
+
+    ASSERT (getentropy (buf1, sizeof (buf1)) == 0);
+    ASSERT (getentropy (buf2, sizeof (buf2)) == 0);
+    ASSERT (memcmp (buf1, buf2, sizeof (buf1)) != 0);
+  }
+
   return 0;
 }
diff --git a/tests/test-unistd-c++.cc b/tests/test-unistd-c++.cc
index cf8d3fc..6d4c8fb 100644
--- a/tests/test-unistd-c++.cc
+++ b/tests/test-unistd-c++.cc
@@ -94,6 +94,10 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::getdomainname, int, (char *, size_t));
 SIGNATURE_CHECK (GNULIB_NAMESPACE::getdtablesize, int, (void));
 #endif
 
+#if GNULIB_TEST_GETENTROPY
+SIGNATURE_CHECK (GNULIB_NAMESPACE::getentropy, int, (void *, size_t));
+#endif
+
 #if GNULIB_TEST_GETGROUPS
 SIGNATURE_CHECK (GNULIB_NAMESPACE::getgroups, int, (int, gid_t *));
 #endif
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-05-31 13:23       ` Simon Josefsson
@ 2020-05-31 19:02         ` Bruno Haible
  2020-06-01 13:45           ` Jeffrey Walton
  0 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-05-31 19:02 UTC (permalink / raw)
  To: Simon Josefsson; +Cc: Paul Eggert, bug-gnulib

Hi Simon,

Thanks for your insights.

> Historically, the problem is that for cryptographic purposes,
> /dev/random and /dev/urandom can be a really bad choice on many
> platforms.  This has probably been improved over the years, especially
> on the most relevant platforms, but still

Indeed. Even without having done multidimensional correlation analysis
(as explained in Knuth vol. 2), it looks fishy that getrandom() with
GRND_RANDOM is able to return 100000 bytes of "random" data instantly
on
  GNU/Hurd, Mac OS X, GNU/kFreeBSD, FreeBSD 12.0, OpenBSD 6.5,
  Minix 3.3, AIX 7.1, Haiku, and native Windows.
I would have expected something better on OpenBSD at least...

> The gc-random module wasn't really perfect in this regard, it required
> that people used libgcrypt or provided a known-good randomness device
> that is different for every platform .  The gc-random logic was
> incomplete here.

Feel free to enhance it. I'm not touching this code, because I lack
the profound crypto know-how.

> There ought to be a word about in the gnulib documentation for
> getrandom() and getentropy() so that applications don't assume these
> gnulib modules provides crypto-strength output on all platforms.

I'm adding these notes in the documentation:


2020-05-31  Bruno Haible  <bruno@clisp.org>

	getrandom, getentropy: Mention the crypto/gc-random module.
	Suggested by Simon Josefsson in
	<https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00400.html>.
	* doc/glibc-functions/getrandom.texi: Mention the quality issues and the
	crypto/gc-random module.
	* doc/glibc-functions/getentropy.texi: Likewise.

diff --git a/doc/glibc-functions/getentropy.texi b/doc/glibc-functions/getentropy.texi
index b7717e5..998bcf4 100644
--- a/doc/glibc-functions/getentropy.texi
+++ b/doc/glibc-functions/getentropy.texi
@@ -31,3 +31,9 @@ Mac OS X 10.13, Solaris 11.4, Android 9.0.
 Portability problems not fixed by Gnulib:
 @itemize
 @end itemize
+
+Note: This function does not provides high-quality random numbers, as needed
+by some crypto applications.  If you want such high-quality random numbers,
+use the function @code{getrandom} with the @code{GRND_RANDOM} flag or (better)
+use the @samp{crypto/gc-random} module and configure with
+@samp{--with-libgcrypt}.
diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
index 3baf390..7488f6f 100644
--- a/doc/glibc-functions/getrandom.texi
+++ b/doc/glibc-functions/getrandom.texi
@@ -29,6 +29,12 @@ Solaris 11.4.
 
 Portability problems not fixed by Gnulib:
 @itemize
-This function cannot produce truly random numbers on some platforms:
+This function cannot produce truly random numbers, even when the
+@code{GRND_RANDOM} flag is given, on some platforms:
 GNU/Hurd, Mac OS X, GNU/kFreeBSD, FreeBSD 12.0, OpenBSD 6.5, Minix 3.3, AIX 7.1, Haiku, mingw, MSVC 14.
 @end itemize
+
+Note: This function does not provides high-quality random numbers, as needed
+by some crypto applications, even when the @code{GRND_RANDOM} flag is given.
+If you want such high-quality random numbers, use the @samp{crypto/gc-random}
+module and configure with @samp{--with-libgcrypt}.



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-05-31 19:02         ` Bruno Haible
@ 2020-06-01 13:45           ` Jeffrey Walton
  2020-06-01 16:53             ` Bruno Haible
  0 siblings, 1 reply; 27+ messages in thread
From: Jeffrey Walton @ 2020-06-01 13:45 UTC (permalink / raw)
  To: bug-gnulib

On Sun, May 31, 2020 at 3:02 PM Bruno Haible <bruno@clisp.org> wrote:
>
> Hi Simon,
>
> Thanks for your insights.
>
> > Historically, the problem is that for cryptographic purposes,
> > /dev/random and /dev/urandom can be a really bad choice on many
> > platforms.  This has probably been improved over the years, especially
> > on the most relevant platforms, but still
>
> Indeed. Even without having done multidimensional correlation analysis
> (as explained in Knuth vol. 2), it looks fishy that getrandom() with
> GRND_RANDOM is able to return 100000 bytes of "random" data instantly
> on
>   GNU/Hurd, Mac OS X, GNU/kFreeBSD, FreeBSD 12.0, OpenBSD 6.5,
>   Minix 3.3, AIX 7.1, Haiku, and native Windows.
> I would have expected something better on OpenBSD at least...
>
> > The gc-random module wasn't really perfect in this regard, it required
> > that people used libgcrypt or provided a known-good randomness device
> > that is different for every platform .  The gc-random logic was
> > incomplete here.
>
> Feel free to enhance it. I'm not touching this code, because I lack
> the profound crypto know-how.
>
> > There ought to be a word about in the gnulib documentation for
> > getrandom() and getentropy() so that applications don't assume these
> > gnulib modules provides crypto-strength output on all platforms.
>
> I'm adding these notes in the documentation:
>
>
> 2020-05-31  Bruno Haible  <bruno@clisp.org>
>
>         getrandom, getentropy: Mention the crypto/gc-random module.
>         Suggested by Simon Josefsson in
>         <https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00400.html>.
>         * doc/glibc-functions/getrandom.texi: Mention the quality issues and the
>         crypto/gc-random module.
>         * doc/glibc-functions/getentropy.texi: Likewise.
>
> diff --git a/doc/glibc-functions/getentropy.texi b/doc/glibc-functions/getentropy.texi
> index b7717e5..998bcf4 100644
> --- a/doc/glibc-functions/getentropy.texi
> +++ b/doc/glibc-functions/getentropy.texi
> @@ -31,3 +31,9 @@ Mac OS X 10.13, Solaris 11.4, Android 9.0.
>  Portability problems not fixed by Gnulib:
>  @itemize
>  @end itemize
> +
> +Note: This function does not provides high-quality random numbers, as needed
> +by some crypto applications.  If you want such high-quality random numbers,
> +use the function @code{getrandom} with the @code{GRND_RANDOM} flag or (better)
> +use the @samp{crypto/gc-random} module and configure with
> +@samp{--with-libgcrypt}.
> diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
> index 3baf390..7488f6f 100644
> --- a/doc/glibc-functions/getrandom.texi
> +++ b/doc/glibc-functions/getrandom.texi
> @@ -29,6 +29,12 @@ Solaris 11.4.
>
>  Portability problems not fixed by Gnulib:
>  @itemize
> -This function cannot produce truly random numbers on some platforms:
> +This function cannot produce truly random numbers, even when the
> +@code{GRND_RANDOM} flag is given, on some platforms:
>  GNU/Hurd, Mac OS X, GNU/kFreeBSD, FreeBSD 12.0, OpenBSD 6.5, Minix 3.3, AIX 7.1, Haiku, mingw, MSVC 14.
>  @end itemize
> +
> +Note: This function does not provides high-quality random numbers, as needed
> +by some crypto applications, even when the @code{GRND_RANDOM} flag is given.
> +If you want such high-quality random numbers, use the @samp{crypto/gc-random}
> +module and configure with @samp{--with-libgcrypt}.

Nowadays it may be prudent to simply state the data returned from the
prng should be treated as a seed and not used directly. Some folks
will use it directly even though the security properties may not be
present. For folks who need crypto parameters, suggest they use
Krawczyk's HDKF to extract the entropy from the seed and expand it.
HKDF provides provable security properties and Krawczyk provides the
analysis.

I would avoid labels like "low quality" and "high quality". It is
impossible to judge at runtime without auditing mechanisms in place
operating on the returned data. Even trying to pick a test at runtime
to judge the stream is like trying to pin jello to a wall.

Also, it looks like (to me) getrandom may suffer VM rollback attacks.
So claiming a stream is high quality may be questionable if a reboot
produces the same stream.

The problem of VM rollback attacks is kind of tricky. For that problem
you usually use hedging. Also see "When Virtual is Harder than Real:
Security Challenges in Virtual Machine Based Computing Environments"
and "When Good Randomness Goes Bad: Virtual Machine Reset
Vulnerabilities and Hedging Deployed Cryptography".

Jeff


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-06-01 13:45           ` Jeffrey Walton
@ 2020-06-01 16:53             ` Bruno Haible
  2020-06-01 18:13               ` Paul Eggert
  0 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-06-01 16:53 UTC (permalink / raw)
  To: bug-gnulib, noloader

Hi Jeffrey,

I'm trying to state in simple-to-understand words what Simon said
about getrandom(), getentropy(), and libgcrypt.

If you have a better wording, please submit a patch.

> Nowadays it may be prudent to simply state the data returned from the
> prng should be treated as a seed and not used directly.

Why? Why would it not be OK to use it in tempname(), for example?
Whether the number come from an in-kernel pseudo-random-number generator
or from a user-mode pseudo-random-number generator, doesn't change
things.

> For folks who need crypto parameters, suggest they use
> Krawczyk's HDKF to extract the entropy from the seed and expand it.
> HKDF provides provable security properties and Krawczyk provides the
> analysis.

If the algorithm you mean is already contained libgcrypt, referring to
libgcrypt should be enough, no? If not, and if Krawczyk's algorithm
is as important as you present it, why is it not in libgcrypt?

> I would avoid labels like "low quality" and "high quality".

Is "crypto-strength", as Simon formulated it, a better term? IMO, it
requires a bit of knowledge, to understand that "crypto-strength" means
"very high quality".

Also, there are no absolute terms, I guess - since it depends on the
OS, and the OSes are getting better over time.

> It is
> impossible to judge at runtime without auditing mechanisms in place
> operating on the returned data. Even trying to pick a test at runtime
> to judge the stream is like trying to pin jello to a wall.

Do you have time to analyze the strength of getrandom() and
getentropy() on a dozen of platforms? I don't. Therefore I can't put
in more than a subjective measurement.

> Also, it looks like (to me) getrandom may suffer VM rollback attacks.
> So claiming a stream is high quality may be questionable if a reboot
> produces the same stream.

On which systems does getrandom() have this problem? Also, it surely
depends on the way it's configured. If it has a network interface to the
host machine, and the number of packets per second on that network interface
is used as an entropy source, there should be no problem.

I don't wish to enter to a time-consuming dialogue about security.
All I wish is to have a reasonably short and understandable piece of text
for the Gnulib documentation.

Bruno



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-06-01 16:53             ` Bruno Haible
@ 2020-06-01 18:13               ` Paul Eggert
  2020-06-01 19:01                 ` Bruno Haible
  0 siblings, 1 reply; 27+ messages in thread
From: Paul Eggert @ 2020-06-01 18:13 UTC (permalink / raw)
  To: Bruno Haible; +Cc: noloader, bug-gnulib

[-- Attachment #1: Type: text/plain, Size: 862 bytes --]

>> Also, it looks like (to me) getrandom may suffer VM rollback attacks.
>> So claiming a stream is high quality may be questionable if a reboot
>> produces the same stream.
> On which systems does getrandom() have this problem?

In theory, it could be any system. Even a hardware random-number generator can
be virtualized and the underlying VM can produce any "random" numbers it likes.

For tempname and coreutils I doubt whether this matters. People aren't (or at
least shouldn't :-) be using the output of tempname or shuf to generate
cryptographic keys; they're just trying to create names that don't clash, or
shuffle their playlists.

I installed the attached patch to the Gnulib doc, which attempts to address this
along with the GRND_INSECURE business.

At some point I suppose we should "#define GRND_INSECURE 0" on platforms that
lack GRND_INSECURE.

[-- Attachment #2: 0001-doc-improve-randomness-discussion.patch --]
[-- Type: text/x-patch, Size: 4209 bytes --]

From fd79a21d939d829c67670e9a9bf69e0b408197cc Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon, 1 Jun 2020 11:08:36 -0700
Subject: [PATCH] doc: improve randomness discussion

Inspired by comments from Jeffrey Walton in:
https://lists.gnu.org/r/bug-gnulib/2020-06/msg00002.html
* doc/glibc-functions/getentropy.texi (getentropy):
* doc/glibc-functions/getrandom.texi (getrandom):
Improve discussion of problems with "random" data,
and cite Ristenpart & Yilek.  Also, mention GRND_INSECURE.
---
 ChangeLog                           | 10 ++++++++++
 doc/glibc-functions/getentropy.texi | 14 +++++++++-----
 doc/glibc-functions/getrandom.texi  | 25 ++++++++++++++++++-------
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f7adf2722..87ab168e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2020-06-01  Paul Eggert  <eggert@cs.ucla.edu>
+
+	doc: improve randomness discussion
+	Inspired by comments from Jeffrey Walton in:
+	https://lists.gnu.org/r/bug-gnulib/2020-06/msg00002.html
+	* doc/glibc-functions/getentropy.texi (getentropy):
+	* doc/glibc-functions/getrandom.texi (getrandom):
+	Improve discussion of problems with "random" data,
+	and cite Ristenpart & Yilek.  Also, mention GRND_INSECURE.
+
 2020-06-01  Asher Gordon  <AsDaGo@posteo.net>
 
 	doc: Change '.' to '@.' where appropriate.
diff --git a/doc/glibc-functions/getentropy.texi b/doc/glibc-functions/getentropy.texi
index 998bcf46d..c9884ad24 100644
--- a/doc/glibc-functions/getentropy.texi
+++ b/doc/glibc-functions/getentropy.texi
@@ -32,8 +32,12 @@ Portability problems not fixed by Gnulib:
 @itemize
 @end itemize
 
-Note: This function does not provides high-quality random numbers, as needed
-by some crypto applications.  If you want such high-quality random numbers,
-use the function @code{getrandom} with the @code{GRND_RANDOM} flag or (better)
-use the @samp{crypto/gc-random} module and configure with
-@samp{--with-libgcrypt}.
+@noindent
+Although this function is intended to produce random data, the data's
+security properties may not be appropriate for your application.
+For example, identical ``random'' data streams might be produced by
+rebooted virtual machines.  If this is of concern you may need to use
+additional techniques such as hedging.@footnote{Ristenpart T, Yilek
+S@. @url{http://pages.cs.wisc.edu/~rist/papers/sslhedge.pdf, When good
+randomness goes bad: virtual machine vulnerabilities and hedging
+deployed cryptography}. NDSS 2010.}
diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
index 7488f6faa..f3a20a09d 100644
--- a/doc/glibc-functions/getrandom.texi
+++ b/doc/glibc-functions/getrandom.texi
@@ -29,12 +29,23 @@ Solaris 11.4.
 
 Portability problems not fixed by Gnulib:
 @itemize
-This function cannot produce truly random numbers, even when the
-@code{GRND_RANDOM} flag is given, on some platforms:
-GNU/Hurd, Mac OS X, GNU/kFreeBSD, FreeBSD 12.0, OpenBSD 6.5, Minix 3.3, AIX 7.1, Haiku, mingw, MSVC 14.
+@item
+The @code{GRND_INSECURE} flag is missing on some platforms:
+glibc 2.31, macOS 10.15, GNU/kFreeBSD, FreeBSD 12.0, OpenBSD 6.5,
+Minix 3.3, Haiku.
+
+@item
+The @code{GRND_RANDOM} flag has different effects on different platforms.
+Some platforms ignore the flag, or yield data that can fail to be
+random in some cases.
 @end itemize
 
-Note: This function does not provides high-quality random numbers, as needed
-by some crypto applications, even when the @code{GRND_RANDOM} flag is given.
-If you want such high-quality random numbers, use the @samp{crypto/gc-random}
-module and configure with @samp{--with-libgcrypt}.
+@noindent
+Although this function is intended to produce random data, the data's
+security properties may not be appropriate for your application.
+For example, identical ``random'' data streams might be produced by
+rebooted virtual machines.  If this is of concern you may need to use
+additional techniques such as hedging.@footnote{Ristenpart T, Yilek
+S@. @url{http://pages.cs.wisc.edu/~rist/papers/sslhedge.pdf, When good
+randomness goes bad: virtual machine vulnerabilities and hedging
+deployed cryptography}. NDSS 2010.}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-06-01 18:13               ` Paul Eggert
@ 2020-06-01 19:01                 ` Bruno Haible
  2020-06-01 23:00                   ` Paul Eggert
  0 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-06-01 19:01 UTC (permalink / raw)
  To: Paul Eggert; +Cc: noloader, bug-gnulib, Simon Josefsson

Hi Paul,

> I installed the attached patch to the Gnulib doc, which attempts to address this
> along with the GRND_INSECURE business.

No guidance regarding getrandom vs. crypto/gc-random any more?

We have two modules, 'getrandom' and 'crypto/gc-random' (in fact 3, if you also
count 'getentropy'), but no guidance when the users should choose one or the
other. As a user, I would expect to find such a guidance.

Bruno



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-06-01 19:01                 ` Bruno Haible
@ 2020-06-01 23:00                   ` Paul Eggert
  2020-06-01 23:51                     ` Bruno Haible
  0 siblings, 1 reply; 27+ messages in thread
From: Paul Eggert @ 2020-06-01 23:00 UTC (permalink / raw)
  To: Bruno Haible; +Cc: noloader, bug-gnulib, Simon Josefsson

On 6/1/20 12:01 PM, Bruno Haible wrote:
> No guidance regarding getrandom vs. crypto/gc-random any more?

The main advantage of getrandom and/or getentropy over crypto/gc-random is the
simpler API and lower maintenance/runtime overhead. crypto/gc-random is a better
match if you're already using the other crypto/* APIs. I could add text along
these lines if this sounds like a good idea.

Come to think of it, crypto/gc-random could be rewritten to use getrandom. This
should improve crypto/gc-random's performance, and should avoid some issues on
platforms where /dev/urandom doesn't exist but the getrandom syscall does.


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-06-01 23:00                   ` Paul Eggert
@ 2020-06-01 23:51                     ` Bruno Haible
  2020-06-02  0:04                       ` Paul Eggert
  0 siblings, 1 reply; 27+ messages in thread
From: Bruno Haible @ 2020-06-01 23:51 UTC (permalink / raw)
  To: Paul Eggert; +Cc: noloader, bug-gnulib, Simon Josefsson

Hi Paul,

> > No guidance regarding getrandom vs. crypto/gc-random any more?
> 
> The main advantage of getrandom and/or getentropy over crypto/gc-random is the
> simpler API and lower maintenance/runtime overhead. crypto/gc-random is a better
> match if you're already using the other crypto/* APIs. I could add text along
> these lines if this sounds like a good idea.

Yes, that would sound good.

> Come to think of it, crypto/gc-random could be rewritten to use getrandom.

Yes, that sounds reasonable. libgcrypt (the "big brother" of crypto/gc-random)
also already uses getentropy or getrandom.

Simon, what do you think?

> should avoid some issues on
> platforms where /dev/urandom doesn't exist but the getrandom syscall does.

Yes. /dev/urandom exists in all OSes (except native Windows). The syscall was
introduced for the benefit of containers (Linux) or jails (FreeBSD), where
the devices may not be available, and for situations where the file descriptor
table of the process is full. [1]

Bruno

[1] https://lwn.net/Articles/606141/



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: getrandom vs. crypto/gc-random
  2020-06-01 23:51                     ` Bruno Haible
@ 2020-06-02  0:04                       ` Paul Eggert
  0 siblings, 0 replies; 27+ messages in thread
From: Paul Eggert @ 2020-06-02  0:04 UTC (permalink / raw)
  To: Bruno Haible; +Cc: noloader, bug-gnulib, Simon Josefsson

[-- Attachment #1: Type: text/plain, Size: 177 bytes --]

On 6/1/20 4:51 PM, Bruno Haible wrote:

>> I could add text along
>> these lines if this sounds like a good idea.
> 
> Yes, that would sound good.

Done via the attached patch.

[-- Attachment #2: 0001-getentropy-getrandom-compare-to-crypto-gc-random.patch --]
[-- Type: text/x-patch, Size: 1698 bytes --]

From af3ff63e457ddb6ba29295e3d5b78a93d834cb8e Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon, 1 Jun 2020 17:02:54 -0700
Subject: [PATCH] getentropy, getrandom: compare to crypto/gc-random

---
 doc/glibc-functions/getentropy.texi | 4 ++++
 doc/glibc-functions/getrandom.texi  | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/doc/glibc-functions/getentropy.texi b/doc/glibc-functions/getentropy.texi
index 2f66ada63..1689a7763 100644
--- a/doc/glibc-functions/getentropy.texi
+++ b/doc/glibc-functions/getentropy.texi
@@ -41,3 +41,7 @@ additional techniques such as hedging.@footnote{Ristenpart T, Yilek
 S@. @url{http://pages.cs.wisc.edu/~rist/papers/sslhedge.pdf, When good
 randomness goes bad: virtual machine vulnerabilities and hedging
 deployed cryptography}. NDSS 2010.}
+
+Related modules include @code{getrandom}, which has a more-flexible
+but more-complex API, and @code{crypto/gc-random}, which is likely a
+better match for code already using the other @code{crypto} APIs.
diff --git a/doc/glibc-functions/getrandom.texi b/doc/glibc-functions/getrandom.texi
index adf7aefcc..a2a259f04 100644
--- a/doc/glibc-functions/getrandom.texi
+++ b/doc/glibc-functions/getrandom.texi
@@ -49,3 +49,7 @@ additional techniques such as hedging.@footnote{Ristenpart T, Yilek
 S@. @url{http://pages.cs.wisc.edu/~rist/papers/sslhedge.pdf, When good
 randomness goes bad: virtual machine vulnerabilities and hedging
 deployed cryptography}. NDSS 2010.}
+
+Related modules include @code{getentropy}, which has a simpler but
+more-limited API, and @code{crypto/gc-random}, which is likely a
+better match for code already using the other @code{crypto} APIs.
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2020-06-02  0:04 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-25 19:37 [PATCH] getentropy, getrandom: new modules Paul Eggert
2020-05-30 12:58 ` Bruno Haible
2020-05-30 22:43   ` Paul Eggert
2020-05-31 11:23     ` getrandom vs. crypto/gc-random Bruno Haible
2020-05-31 11:47       ` Bruno Haible
2020-05-31 13:14       ` Jeffrey Walton
2020-05-31 13:23       ` Simon Josefsson
2020-05-31 19:02         ` Bruno Haible
2020-06-01 13:45           ` Jeffrey Walton
2020-06-01 16:53             ` Bruno Haible
2020-06-01 18:13               ` Paul Eggert
2020-06-01 19:01                 ` Bruno Haible
2020-06-01 23:00                   ` Paul Eggert
2020-06-01 23:51                     ` Bruno Haible
2020-06-02  0:04                       ` Paul Eggert
2020-05-30 13:17 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
2020-05-30 14:23 ` Bruno Haible
2020-05-30 23:06   ` sys_random: Work around macOS bug Bruno Haible
2020-05-30 23:28     ` Jeffrey Walton
2020-05-31 10:29       ` Apple platforms Bruno Haible
2020-05-30 15:34 ` [PATCH] getentropy, getrandom: new modules Bruno Haible
2020-05-30 23:14 ` fix list of crypto devices for NetBSD, OpenBSD Bruno Haible
2020-05-31 10:57 ` fix list of crypto devices for Solaris Bruno Haible
2020-05-31 16:26 ` getrandom: Add support for native Windows Bruno Haible
2020-05-31 16:41   ` Jeffrey Walton
2020-05-31 16:49 ` getrandom: doc and test tweaks Bruno Haible
2020-05-31 18:15 ` [PATCH] getentropy, getrandom: new modules Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).