Blame SOURCES/libgcrypt-1.5.3-fips-cfgrandom.patch

f268f1
diff -up libgcrypt-1.5.3/random/drbg.c.cfgrandom libgcrypt-1.5.3/random/drbg.c
f268f1
--- libgcrypt-1.5.3/random/drbg.c.cfgrandom	2014-10-30 16:42:49.000000000 +0100
f268f1
+++ libgcrypt-1.5.3/random/drbg.c	2014-10-30 16:46:57.291800433 +0100
f268f1
@@ -485,8 +485,11 @@ gcry_drbg_get_entropy (struct gcry_drbg_
f268f1
   read_cb_size = len;
f268f1
   read_cb_len = 0;
f268f1
 #if USE_RNDLINUX
f268f1
+  _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len,
f268f1
+				     -1);
f268f1
+  read_cb_len = 0;
f268f1
   rc = _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len,
f268f1
-				     GCRY_VERY_STRONG_RANDOM);
f268f1
+				     GCRY_STRONG_RANDOM);
f268f1
 #elif USE_RNDUNIX
f268f1
   rc = _gcry_rndunix_gather_random (read_cb, 0, length,
f268f1
 				    GCRY_VERY_STRONG_RANDOM);
f268f1
diff -up libgcrypt-1.5.3/random/random-fips.c.cfgrandom libgcrypt-1.5.3/random/random-fips.c
f268f1
--- libgcrypt-1.5.3/random/random-fips.c.cfgrandom	2014-10-30 16:42:49.942216405 +0100
f268f1
+++ libgcrypt-1.5.3/random/random-fips.c	2014-10-30 16:42:49.970217037 +0100
6e4d5d
@@ -27,10 +27,10 @@
6e4d5d
    There are 3 random context which map to the different levels of
6e4d5d
    random quality:
6e4d5d
 
6e4d5d
-   Generator                Seed and Key        Kernel entropy (init/reseed)
6e4d5d
-   ------------------------------------------------------------
6e4d5d
-   GCRY_VERY_STRONG_RANDOM  /dev/random         256/128 bits
6e4d5d
-   GCRY_STRONG_RANDOM       /dev/random         256/128 bits
6e4d5d
+   Generator                Seed and Key                      Kernel entropy (init/reseed)
6e4d5d
+   ---------------------------------------------------------------------------------------
6e4d5d
+   GCRY_VERY_STRONG_RANDOM  /etc/gcrypt/rngseed+/dev/urandom  256/128 bits
6e4d5d
+   GCRY_STRONG_RANDOM       /etc/gcrypt/rngseed+/dev/urandom  256/128 bits
6e4d5d
    gcry_create_nonce        GCRY_STRONG_RANDOM  n/a
6e4d5d
 
6e4d5d
    All random generators return their data in 128 bit blocks.  If the
6e4d5d
@@ -40,8 +40,10 @@
6e4d5d
    (SEED_TTL) output blocks; the re-seeding is disabled in test mode.
6e4d5d
 
6e4d5d
    The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are
6e4d5d
-   keyed and seeded from the /dev/random device.  Thus these
6e4d5d
-   generators may block until the kernel has collected enough entropy.
6e4d5d
+   keyed and seeded with data that is loaded from the /etc/gcrypt/rngseed
6e4d5d
+   if the device or symlink to device exists xored with the data
6e4d5d
+   from the /dev/urandom device. This allows the system administrator
6e4d5d
+   to always seed the RNGs from /dev/random if it is required.
6e4d5d
 
6e4d5d
    The gcry_create_nonce generator is keyed and seeded from the
6e4d5d
    GCRY_STRONG_RANDOM generator.  It may also block if the
6e4d5d
@@ -560,9 +562,13 @@ get_entropy (size_t nbytes)
6e4d5d
   entropy_collect_buffer_len = 0;
6e4d5d
 
6e4d5d
 #if USE_RNDLINUX
6e4d5d
+  _gcry_rndlinux_gather_random (entropy_collect_cb, 0,
6e4d5d
+                                     X931_AES_KEYLEN,
6e4d5d
+                                     -1);
6e4d5d
+  entropy_collect_buffer_len = 0;
6e4d5d
   rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0,
6e4d5d
                                      X931_AES_KEYLEN,
6e4d5d
-                                     GCRY_VERY_STRONG_RANDOM);
6e4d5d
+                                     GCRY_STRONG_RANDOM);
6e4d5d
 #elif USE_RNDW32
6e4d5d
   do
6e4d5d
     {
f268f1
diff -up libgcrypt-1.5.3/random/rndlinux.c.cfgrandom libgcrypt-1.5.3/random/rndlinux.c
f268f1
--- libgcrypt-1.5.3/random/rndlinux.c.cfgrandom	2014-10-30 16:42:49.949216563 +0100
f268f1
+++ libgcrypt-1.5.3/random/rndlinux.c	2014-10-30 16:42:49.971217059 +0100
f268f1
@@ -37,7 +37,9 @@
6e4d5d
 #include "g10lib.h"
6e4d5d
 #include "rand-internal.h"
6e4d5d
 
6e4d5d
-static int open_device ( const char *name );
6e4d5d
+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed"
6e4d5d
+
6e4d5d
+static int open_device ( const char *name, int fatal );
6e4d5d
 
6e4d5d
 
6e4d5d
 static int
f268f1
@@ -58,13 +60,17 @@ set_cloexec_flag (int fd)
6e4d5d
  * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists)).
6e4d5d
  */
6e4d5d
 static int
6e4d5d
-open_device ( const char *name )
6e4d5d
+open_device ( const char *name, int fatal )
6e4d5d
 {
6e4d5d
   int fd;
6e4d5d
 
6e4d5d
   fd = open ( name, O_RDONLY );
6e4d5d
   if ( fd == -1 )
6e4d5d
-    log_fatal ("can't open %s: %s\n", name, strerror(errno) );
6e4d5d
+    {
6e4d5d
+      if (! fatal)
6e4d5d
+        return fd;
6e4d5d
+      log_fatal ("can't open %s: %s\n", name, strerror(errno) );
6e4d5d
+    }
6e4d5d
 
6e4d5d
   if (set_cloexec_flag (fd))
6e4d5d
     log_error ("error setting FD_CLOEXEC on fd %d: %s\n",
f268f1
@@ -93,6 +99,7 @@ _gcry_rndlinux_gather_random (void (*add
6e4d5d
 {
6e4d5d
   static int fd_urandom = -1;
6e4d5d
   static int fd_random = -1;
6e4d5d
+  static int fd_configured = -1;
6e4d5d
   int fd;
6e4d5d
   int n;
6e4d5d
   byte buffer[768];
f268f1
@@ -101,6 +108,7 @@ _gcry_rndlinux_gather_random (void (*add
6e4d5d
   size_t last_so_far = 0;
6e4d5d
   int any_need_entropy = 0;
6e4d5d
   int delay;
6e4d5d
+  size_t orig_length = length;
6e4d5d
 
6e4d5d
   /* First read from a hardware source.  However let it account only
6e4d5d
      for up to 50% of the requested bytes.  */
f268f1
@@ -111,16 +119,26 @@ _gcry_rndlinux_gather_random (void (*add
6e4d5d
     length -= n_hw;
6e4d5d
 
6e4d5d
   /* Open the requested device.  */
6e4d5d
+
6e4d5d
+  if (level == -1)
6e4d5d
+    {
6e4d5d
+      if (fd_configured == -1)
6e4d5d
+        fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0 );
6e4d5d
+      fd = fd_configured;
6e4d5d
+      if (fd == -1)
6e4d5d
+        return -1;
6e4d5d
+    }
6e4d5d
+
6e4d5d
   if (level >= 2)
6e4d5d
     {
6e4d5d
       if( fd_random == -1 )
6e4d5d
-        fd_random = open_device ( NAME_OF_DEV_RANDOM );
6e4d5d
+        fd_random = open_device ( NAME_OF_DEV_RANDOM, 1 );
6e4d5d
       fd = fd_random;
6e4d5d
     }
6e4d5d
-  else
6e4d5d
+  else if (level != -1)
6e4d5d
     {
6e4d5d
       if( fd_urandom == -1 )
6e4d5d
-        fd_urandom = open_device ( NAME_OF_DEV_URANDOM );
6e4d5d
+        fd_urandom = open_device ( NAME_OF_DEV_URANDOM, 1 );
6e4d5d
       fd = fd_urandom;
6e4d5d
     }
6e4d5d