Blame SOURCES/libgcrypt-1.8.5-getrandom.patch

4bbd51
diff -up libgcrypt-1.8.5/random/rand-internal.h.getrandom libgcrypt-1.8.5/random/rand-internal.h
4bbd51
--- libgcrypt-1.8.5/random/rand-internal.h.getrandom	2017-11-23 19:16:58.000000000 +0100
4bbd51
+++ libgcrypt-1.8.5/random/rand-internal.h	2020-04-20 14:55:34.875949624 +0200
4bbd51
@@ -47,6 +47,7 @@ void _gcry_random_progress (const char *
4bbd51
 
4bbd51
 /*-- random-csprng.c --*/
4bbd51
 void _gcry_rngcsprng_initialize (int full);
4bbd51
+void _gcry_rngcsprng_deinit (void);
4bbd51
 void _gcry_rngcsprng_close_fds (void);
4bbd51
 void _gcry_rngcsprng_dump_stats (void);
4bbd51
 void _gcry_rngcsprng_secure_alloc (void);
4bbd51
@@ -68,6 +69,7 @@ void _gcry_rngcsprng_fast_poll (void);
4bbd51
 
4bbd51
 /*-- random-drbg.c --*/
4bbd51
 void _gcry_rngdrbg_inititialize (int full);
4bbd51
+void _gcry_rngdrbg_deinit (void);
4bbd51
 void _gcry_rngdrbg_close_fds (void);
4bbd51
 void _gcry_rngdrbg_dump_stats (void);
4bbd51
 int  _gcry_rngdrbg_is_faked (void);
4bbd51
diff -up libgcrypt-1.8.5/random/random.c.getrandom libgcrypt-1.8.5/random/random.c
4bbd51
--- libgcrypt-1.8.5/random/random.c.getrandom	2017-11-23 19:16:58.000000000 +0100
4bbd51
+++ libgcrypt-1.8.5/random/random.c	2020-04-20 14:55:34.876949605 +0200
4bbd51
@@ -110,8 +110,8 @@ _gcry_random_read_conf (void)
4bbd51
   unsigned int result = 0;
4bbd51
 
4bbd51
   fp = fopen (fname, "r");
4bbd51
-  if (!fp)
4bbd51
-    return result;
4bbd51
+  if (!fp) /* We make only_urandom the default. */
4bbd51
+    return RANDOM_CONF_ONLY_URANDOM;
4bbd51
 
4bbd51
   for (;;)
4bbd51
     {
4bbd51
@@ -228,6 +228,22 @@ _gcry_random_initialize (int full)
4bbd51
 }
4bbd51
 
4bbd51
 
4bbd51
+/* Deinitialize this random subsystem. */
4bbd51
+void
4bbd51
+_gcry_random_deinit (void)
4bbd51
+{
4bbd51
+  if (fips_mode ())
4bbd51
+    _gcry_rngdrbg_deinit ();
4bbd51
+  else if (rng_types.standard)
4bbd51
+    _gcry_rngcsprng_deinit ();
4bbd51
+  else if (rng_types.fips)
4bbd51
+    _gcry_rngdrbg_deinit ();
4bbd51
+  else
4bbd51
+    _gcry_rngcsprng_deinit ();
4bbd51
+  /* not needed for system */
4bbd51
+}
4bbd51
+
4bbd51
+
4bbd51
 /* If possible close file descriptors used by the RNG. */
4bbd51
 void
4bbd51
 _gcry_random_close_fds (void)
4bbd51
diff -up libgcrypt-1.8.5/random/random-csprng.c.getrandom libgcrypt-1.8.5/random/random-csprng.c
4bbd51
--- libgcrypt-1.8.5/random/random-csprng.c.getrandom	2017-11-23 19:16:58.000000000 +0100
4bbd51
+++ libgcrypt-1.8.5/random/random-csprng.c	2020-04-20 15:04:27.182877975 +0200
4bbd51
@@ -55,6 +55,10 @@
4bbd51
 #ifdef __MINGW32__
4bbd51
 #include <process.h>
4bbd51
 #endif
4bbd51
+#if defined(__linux__) && defined(HAVE_SYSCALL)
4bbd51
+# include <sys/syscall.h>
4bbd51
+# include <linux/random.h>
4bbd51
+#endif
4bbd51
 #include "g10lib.h"
4bbd51
 #include "random.h"
4bbd51
 #include "rand-internal.h"
4bbd51
@@ -343,6 +347,21 @@ _gcry_rngcsprng_initialize (int full)
4bbd51
 }
4bbd51
 
4bbd51
 
4bbd51
+void
4bbd51
+_gcry_rngcsprng_deinit (void)
4bbd51
+{
4bbd51
+  lock_pool();
4bbd51
+  pool_writepos = 0;
4bbd51
+  pool_readpos = 0;
4bbd51
+  pool_filled = 0;
4bbd51
+  pool_filled_counter = 0;
4bbd51
+  did_initial_extra_seeding = 0;
4bbd51
+  pool_balance = 0;
4bbd51
+  just_mixed = 0;
4bbd51
+  unlock_pool();
4bbd51
+}
4bbd51
+
4bbd51
+
4bbd51
 /* Try to close the FDs of the random gather module.  This is
4bbd51
    currently only implemented for rndlinux. */
4bbd51
 void
4bbd51
@@ -1116,6 +1135,22 @@ getfnc_gather_random (void))(void (*)(co
4bbd51
              enum random_origins, size_t, int);
4bbd51
 
4bbd51
 #if USE_RNDLINUX
4bbd51
+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
4bbd51
+  long ret;
4bbd51
+  char buffer[1];
4bbd51
+
4bbd51
+  _gcry_pre_syscall ();
4bbd51
+  ret = syscall (__NR_getrandom,
4bbd51
+                 (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK);
4bbd51
+  _gcry_post_syscall ();
4bbd51
+  if (ret != -1 || errno != ENOSYS)
4bbd51
+    {
4bbd51
+      fnc = _gcry_rndlinux_gather_random;
4bbd51
+      return fnc;
4bbd51
+    }
4bbd51
+  else
4bbd51
+          /* The syscall is not supported - fallback to /dev/urandom. */
4bbd51
+#endif
4bbd51
   if ( !access (NAME_OF_DEV_RANDOM, R_OK)
4bbd51
        && !access (NAME_OF_DEV_URANDOM, R_OK))
4bbd51
     {
4bbd51
diff -up libgcrypt-1.8.5/random/random-drbg.c.getrandom libgcrypt-1.8.5/random/random-drbg.c
4bbd51
--- libgcrypt-1.8.5/random/random-drbg.c.getrandom	2017-11-23 19:16:58.000000000 +0100
4bbd51
+++ libgcrypt-1.8.5/random/random-drbg.c	2020-04-20 15:02:37.782947902 +0200
4bbd51
@@ -1811,6 +1811,22 @@ _gcry_rngdrbg_inititialize (int full)
4bbd51
 }
4bbd51
 
4bbd51
 /*
4bbd51
+ * Deinitialize the DRBG invoked by the libgcrypt API
4bbd51
+ * It will be automatically re-initialized on next call
4bbd51
+ */
4bbd51
+void
4bbd51
+_gcry_rngdrbg_deinit (void)
4bbd51
+{
4bbd51
+  drbg_lock ();
4bbd51
+  if (drbg_state)
4bbd51
+    {
4bbd51
+      drbg_uninstantiate (drbg_state);
4bbd51
+      drbg_state = NULL;
4bbd51
+    }
4bbd51
+  drbg_unlock ();
4bbd51
+}
4bbd51
+
4bbd51
+/*
4bbd51
  * Backend handler function for GCRYCTL_DRBG_REINIT
4bbd51
  *
4bbd51
  * Select a different DRBG type and initialize it.
4bbd51
diff -up libgcrypt-1.8.5/random/random.h.getrandom libgcrypt-1.8.5/random/random.h
4bbd51
--- libgcrypt-1.8.5/random/random.h.getrandom	2017-11-23 19:16:58.000000000 +0100
4bbd51
+++ libgcrypt-1.8.5/random/random.h	2020-04-20 14:55:34.877949586 +0200
4bbd51
@@ -29,6 +29,7 @@ void _gcry_register_random_progress (voi
4bbd51
 
4bbd51
 void _gcry_set_preferred_rng_type (int type);
4bbd51
 void _gcry_random_initialize (int full);
4bbd51
+void _gcry_random_deinit (void);
4bbd51
 void _gcry_random_close_fds (void);
4bbd51
 int  _gcry_get_rng_type (int ignore_fips_mode);
4bbd51
 void _gcry_random_dump_stats(void);
4bbd51
diff -up libgcrypt-1.8.5/random/rndlinux.c.getrandom libgcrypt-1.8.5/random/rndlinux.c
4bbd51
--- libgcrypt-1.8.5/random/rndlinux.c.getrandom	2020-04-20 15:01:50.159848963 +0200
4bbd51
+++ libgcrypt-1.8.5/random/rndlinux.c	2020-04-20 16:14:21.901610921 +0200
4bbd51
@@ -35,6 +35,7 @@
4bbd51
 #include <poll.h>
4bbd51
 #if defined(__linux__) && defined(HAVE_SYSCALL)
4bbd51
 # include <sys/syscall.h>
4bbd51
+# include <linux/random.h>
4bbd51
 #endif
4bbd51
 
4bbd51
 #include "types.h"
4bbd51
@@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add
4bbd51
   if (!add)
4bbd51
     {
4bbd51
       /* Special mode to close the descriptors.  */
4bbd51
-      if (fd_random != -1)
4bbd51
+      if (fd_random >= 0)
4bbd51
         {
4bbd51
           close (fd_random);
4bbd51
           fd_random = -1;
4bbd51
         }
4bbd51
-      if (fd_urandom != -1)
4bbd51
+      if (fd_urandom >= 0)
4bbd51
         {
4bbd51
           close (fd_urandom);
4bbd51
           fd_urandom = -1;
4bbd51
@@ -166,12 +167,12 @@ _gcry_rndlinux_gather_random (void (*add
4bbd51
   apid = getpid ();
4bbd51
   if (my_pid != apid)
4bbd51
     {
4bbd51
-      if (fd_random != -1)
4bbd51
+      if (fd_random >= 0)
4bbd51
         {
4bbd51
           close (fd_random);
4bbd51
           fd_random = -1;
4bbd51
         }
4bbd51
-      if (fd_urandom != -1)
4bbd51
+      if (fd_urandom >= 0)
4bbd51
         {
4bbd51
           close (fd_urandom);
4bbd51
           fd_urandom = -1;
4bbd51
@@ -216,7 +217,23 @@ _gcry_rndlinux_gather_random (void (*add
4bbd51
      that we always require the device to be existent but want a more
4bbd51
      graceful behaviour if the rarely needed close operation has been
4bbd51
      used and the device needs to be re-opened later. */
4bbd51
-  if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom)
4bbd51
+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
4bbd51
+   if (fd_urandom != -2 && !_gcry_in_constructor ())
4bbd51
+     {
4bbd51
+       long ret;
4bbd51
+
4bbd51
+       _gcry_pre_syscall ();
4bbd51
+       ret = syscall (__NR_getrandom,
4bbd51
+                      (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK);
4bbd51
+       _gcry_post_syscall ();
4bbd51
+       if (ret > -1 || errno == EAGAIN || errno == EINTR)
4bbd51
+         {
4bbd51
+           fd_urandom = -2;
4bbd51
+           fd_random = -2;
4bbd51
+         }
4bbd51
+     }
4bbd51
+#endif
4bbd51
+  if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom && !_gcry_in_constructor ())
4bbd51
     {
4bbd51
       if (fd_random == -1)
4bbd51
         {
4bbd51
@@ -255,6 +272,7 @@ _gcry_rndlinux_gather_random (void (*add
4bbd51
        * syscall and not a new device and thus we are not able to use
4bbd51
        * select(2) to have a timeout. */
4bbd51
 #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
4bbd51
+      if (fd == -2)
4bbd51
         {
4bbd51
           long ret;
4bbd51
           size_t nbytes;
4bbd51
@@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add
4bbd51
               _gcry_post_syscall ();
4bbd51
             }
4bbd51
           while (ret == -1 && errno == EINTR);
4bbd51
-          if (ret == -1 && errno == ENOSYS)
4bbd51
-            ; /* The syscall is not supported - fallback to pulling from fd.  */
4bbd51
-          else
4bbd51
+          if (1)
4bbd51
             { /* The syscall is supported.  Some sanity checks.  */
4bbd51
               if (ret == -1)
4bbd51
                 log_fatal ("unexpected error from getrandom: %s\n",
4bbd51
diff -up libgcrypt-1.8.5/src/g10lib.h.getrandom libgcrypt-1.8.5/src/g10lib.h
4bbd51
--- libgcrypt-1.8.5/src/g10lib.h.getrandom	2020-04-20 15:08:16.528538580 +0200
4bbd51
+++ libgcrypt-1.8.5/src/g10lib.h	2020-04-20 15:08:28.641309399 +0200
4bbd51
@@ -464,6 +464,6 @@ gpg_err_code_t _gcry_fips_run_selftests
4bbd51
 void _gcry_fips_noreturn (void);
4bbd51
 #define fips_noreturn()  (_gcry_fips_noreturn ())
4bbd51
 
4bbd51
-
4bbd51
+int _gcry_in_constructor (void);
4bbd51
 
4bbd51
 #endif /* G10LIB_H */
4bbd51
diff -up libgcrypt-1.8.5/src/global.c.getrandom libgcrypt-1.8.5/src/global.c
4bbd51
--- libgcrypt-1.8.5/src/global.c.getrandom	2020-04-20 15:06:21.891707597 +0200
4bbd51
+++ libgcrypt-1.8.5/src/global.c	2020-04-20 15:07:29.018437509 +0200
4bbd51
@@ -145,10 +145,18 @@ global_init (void)
4bbd51
 #define FIPS_MODULE_PATH "/etc/system-fips"
4bbd51
 #endif
4bbd51
 
4bbd51
+static int in_constructor = 0;
4bbd51
+
4bbd51
+int _gcry_in_constructor(void)
4bbd51
+{
4bbd51
+  return in_constructor;
4bbd51
+}
4bbd51
+
4bbd51
 void __attribute__ ((constructor)) _gcry_global_constructor (void)
4bbd51
 {
4bbd51
   int rv;
4bbd51
 
4bbd51
+  in_constructor = 1;
4bbd51
   rv = access (FIPS_MODULE_PATH, F_OK);
4bbd51
   if (rv < 0 && errno != ENOENT)
4bbd51
     rv = 0;
4bbd51
@@ -163,10 +171,12 @@ void __attribute__ ((constructor)) _gcry
4bbd51
       /* force selftests */
4bbd51
       global_init();
4bbd51
       _gcry_fips_run_selftests (0);
4bbd51
-      if (!fips_mode())
4bbd51
-         _gcry_random_close_fds ();
4bbd51
+      _gcry_random_close_fds ();
4bbd51
+      _gcry_random_deinit ();
4bbd51
       no_secure_memory = no_secmem_save;
4bbd51
     }
4bbd51
+
4bbd51
+  in_constructor = 0;
4bbd51
 }
4bbd51
 
4bbd51
 /* This function is called by the macro fips_is_operational and makes