File libgcrypt-1.6.1-fips-cfgrandom.patch of Package libgcrypt.14176

Index: libgcrypt-1.8.0/random/rndlinux.c
===================================================================
--- libgcrypt-1.8.0.orig/random/rndlinux.c	2017-07-21 17:45:39.193291437 +0200
+++ libgcrypt-1.8.0/random/rndlinux.c	2017-07-21 17:48:44.539152641 +0200
@@ -40,7 +40,9 @@
 #include "g10lib.h"
 #include "rand-internal.h"
 
-static int open_device (const char *name, int retry);
+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed"
+
+static int open_device (const char *name, int retry, int fatal);
 
 
 static int
@@ -63,7 +65,7 @@ set_cloexec_flag (int fd)
  * a fatal error but retries until it is able to reopen the device.
  */
 static int
-open_device (const char *name, int retry)
+open_device (const char *name, int retry, int fatal)
 {
   int fd;
 
@@ -71,6 +73,8 @@ open_device (const char *name, int retry
     _gcry_random_progress ("open_dev_random", 'X', 1, 0);
  again:
   fd = open (name, O_RDONLY);
+  if (fd == -1 && !fatal)
+      return fd;
   if (fd == -1 && retry)
     {
       struct timeval tv;
@@ -115,6 +119,7 @@ _gcry_rndlinux_gather_random (void (*add
 {
   static int fd_urandom = -1;
   static int fd_random = -1;
+  static int fd_configured = -1;
   static int only_urandom = -1;
   static unsigned char ever_opened;
   int fd;
@@ -150,6 +155,11 @@ _gcry_rndlinux_gather_random (void (*add
           close (fd_urandom);
           fd_urandom = -1;
         }
+      if (fd_configured != -1)
+        {
+          close (fd_configured);
+          fd_configured = -1;
+        }
       return 0;
     }
 
@@ -190,11 +200,21 @@ _gcry_rndlinux_gather_random (void (*add
      that we always require the device to be existent but want a more
      graceful behaviour if the rarely needed close operation has been
      used and the device needs to be re-opened later. */
+
+  if (level == -1)
+    {
+      if (fd_configured == -1)
+        fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 );
+      fd = fd_configured;
+      if (fd == -1)
+        return -1;
+    }
+
   if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom)
     {
       if (fd_random == -1)
         {
-          fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1));
+          fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1);
           ever_opened |= 1;
         }
       fd = fd_random;
@@ -203,7 +223,7 @@ _gcry_rndlinux_gather_random (void (*add
     {
       if (fd_urandom == -1)
         {
-          fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2));
+          fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1);
           ever_opened |= 2;
         }
       fd = fd_urandom;
openSUSE Build Service is sponsored by