File openssl-fips_entropy_reseeding.patch of Package openssl-1_1.13606

Index: openssl-1.1.0i/crypto/fips/fips_drbg_rand.c
===================================================================
--- openssl-1.1.0i.orig/crypto/fips/fips_drbg_rand.c	2019-11-28 17:29:36.640059417 +0100
+++ openssl-1.1.0i/crypto/fips/fips_drbg_rand.c	2019-11-28 17:30:27.404427622 +0100
@@ -90,6 +90,11 @@ static int fips_drbg_bytes(unsigned char
     int rv = 0;
     unsigned char *adin = NULL;
     size_t adinlen = 0;
+
+    /* seed the DRBG from getrandom */
+    if (count > dctx->min_entropy + dctx->min_nonce)
+        get_urandom(dctx->min_entropy + dctx->min_nonce);
+
     CRYPTO_THREAD_write_lock(fips_rand_lock);
     do {
         size_t rcnt;
Index: openssl-1.1.0i/crypto/rand/md_rand.c
===================================================================
--- openssl-1.1.0i.orig/crypto/rand/md_rand.c	2019-11-28 17:29:36.640059417 +0100
+++ openssl-1.1.0i/crypto/rand/md_rand.c	2019-11-28 17:31:39.516951331 +0100
@@ -318,6 +318,9 @@ static int rand_bytes(unsigned char *buf
     if (num <= 0)
         return 1;
 
+    /* seed from /dev/urandom */
+    RAND_load_file("/dev/urandom", ENTROPY_NEEDED);
+
     m = EVP_MD_CTX_new();
     if (m == NULL)
         goto err_mem;
Index: openssl-1.1.0i/crypto/rand/rand_lib.c
===================================================================
--- openssl-1.1.0i.orig/crypto/rand/rand_lib.c	2019-11-28 17:29:36.640059417 +0100
+++ openssl-1.1.0i/crypto/rand/rand_lib.c	2019-11-29 15:02:28.918638244 +0100
@@ -15,6 +15,8 @@
 #include <openssl/engine.h>
 #include "internal/thread_once.h"
 
+#include <sys/syscall.h>
+#include <linux/random.h>
 #ifdef OPENSSL_FIPS
 # include <openssl/fips.h>
 # include <openssl/fips_rand.h>
@@ -165,6 +167,71 @@ int RAND_status(void)
     return 0;
 }
 
+/* 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
 
 /*
@@ -226,7 +293,10 @@ static int drbg_rand_add(DRBG_CTX *ctx,
 {
     RAND_OpenSSL()->add(in, inlen, entropy);
     if (FIPS_rand_status()) {
-        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);
     }
     return 1;
 }