File openssl-fips_entropy_reseeding.patch of Package openssl

Index: openssl-1.0.2j/crypto/fips/fips_drbg_rand.c
===================================================================
--- openssl-1.0.2j.orig/crypto/fips/fips_drbg_rand.c	2017-07-17 15:37:14.714700121 +0200
+++ openssl-1.0.2j/crypto/fips/fips_drbg_rand.c	2017-07-18 15:55:59.006676034 +0200
@@ -78,6 +78,11 @@ static int fips_drbg_bytes(unsigned char
     unsigned char *adin = NULL;
     size_t adinlen = 0;
     int locked;
+
+    /* seed the DRBG from getrandom */
+    if (count > dctx->min_entropy + dctx->min_nonce)
+        get_urandom(dctx->min_entropy + dctx->min_nonce);
+
     locked = private_RAND_lock(1);
     do {
         size_t rcnt;
Index: openssl-1.0.2j/crypto/rand/md_rand.c
===================================================================
--- openssl-1.0.2j.orig/crypto/rand/md_rand.c	2017-07-17 15:37:14.794701520 +0200
+++ openssl-1.0.2j/crypto/rand/md_rand.c	2017-07-18 15:55:21.266050787 +0200
@@ -343,6 +343,9 @@ int ssleay_rand_bytes(unsigned char *buf
     if (num <= 0)
         return 1;
 
+    /* seed from /dev/urandom */
+    RAND_load_file("/dev/urandom", ENTROPY_NEEDED);
+
     EVP_MD_CTX_init(&m);
     /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
     num_ceil =
Index: openssl-1.0.2j/crypto/rand/rand_lib.c
===================================================================
--- openssl-1.0.2j.orig/crypto/rand/rand_lib.c	2017-07-17 15:37:14.714700121 +0200
+++ openssl-1.0.2j/crypto/rand/rand_lib.c	2017-07-24 13:20:07.151512765 +0200
@@ -65,6 +65,8 @@
 # include <openssl/engine.h>
 #endif
 
+#include <sys/syscall.h>
+#include <linux/random.h>
 #ifdef OPENSSL_FIPS
 # include <openssl/fips.h>
 # include <openssl/fips_rand.h>
@@ -211,6 +213,71 @@ int private_RAND_lock(int lock)
 	return do_lock;
 	}
 
+/* returns 0 on success; 1 otherwise */
+static int getrandom_wrapper(unsigned char *buf, size_t buflen, unsigned int flags)
+{
+#ifdef HAVE_GETRANDOM
+    return getrandom(buf, buflen, 0);
+#else
+# ifdef __NR_getrandom
+    int ret;
+
+    if (buflen > INT_MAX)
+        return 1;
+
+    do {
+        ret = syscall(__NR_getrandom, buf, buflen, flags);
+        if (0 < ret) {
+            buflen -= ret;
+            buf += ret;
+        }
+    } while ((0 < ret || EINTR == errno || ERESTART == errno)
+	       && buflen > 0);
+
+    if (buflen == 0)
+        return 0;
+
+    return 1;
+# else
+    int ret = RAND_load_file("/dev/urandom", buflen);
+        if (ret == buflen)
+            return 0;
+        else
+            return 1;
+# endif
+#endif
+}
+
+#undef BUFSIZE
+#define BUFSIZE 1024
+
+int get_urandom(int bytes)
+{
+    int ret = 0, n;
+    unsigned char buf[BUFSIZE];
+
+    for (;;) {
+        if (bytes > 0)
+            n = (bytes < BUFSIZE) ? bytes : BUFSIZE;
+        else
+            n = BUFSIZE;
+
+        if (getrandom_wrapper(buf, n, 0))
+            break;
+
+        RAND_add(buf, n, (double)n);
+        ret += n;
+        if (bytes > 0) {
+            bytes -= n;
+            if (bytes <= 0)
+                break;
+        }
+    }
+
+    OPENSSL_cleanse(buf, BUFSIZE);
+    return ret;
+}
+
 #ifdef OPENSSL_FIPS
 
 /*
@@ -273,7 +340,10 @@ static int drbg_rand_add(DRBG_CTX *ctx,
     RAND_SSLeay()->add(in, inlen, entropy);
     if (FIPS_rand_status()) {
         int locked = private_RAND_lock(1);
-        FIPS_drbg_reseed(ctx, NULL, 0);
+        /* OpenSSL uses the following seeding chain:
+         * /dev/urandom (via RAND_poll) -> SSLeay MD RNG -> DRBG.
+         * RAND_Add only updates SSLeay MD, not DRBG (bsc#908372) */
+        FIPS_drbg_reseed(ctx, in, inlen);
         if (locked)
             private_RAND_lock(0);
     }
openSUSE Build Service is sponsored by