File openssl-fips_entropy_reseeding.patch of Package openssl-1_1.16402
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;
}