Blame SOURCES/0076-FIPS-140-3-DRBG.patch

22d461
diff -up openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c.fipsrand openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c
22d461
--- openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c.fipsrand	2022-08-03 11:09:01.301637515 +0200
22d461
+++ openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c	2022-08-03 11:13:00.058688605 +0200
22d461
@@ -48,6 +48,8 @@
22d461
 # include <fcntl.h>
22d461
 # include <unistd.h>
22d461
 # include <sys/time.h>
22d461
+# include <sys/random.h>
22d461
+# include <openssl/evp.h>
22d461
 
22d461
 static uint64_t get_time_stamp(void);
22d461
 static uint64_t get_timer_bits(void);
22d461
@@ -342,66 +342,8 @@ static ssize_t syscall_random(void *buf,
22d461
      * which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion
22d461
      * between size_t and ssize_t is safe even without a range check.
22d461
      */
22d461
-
22d461
-    /*
22d461
-     * Do runtime detection to find getentropy().
22d461
-     *
22d461
-     * Known OSs that should support this:
22d461
-     * - Darwin since 16 (OSX 10.12, IOS 10.0).
22d461
-     * - Solaris since 11.3
22d461
-     * - OpenBSD since 5.6
22d461
-     * - Linux since 3.17 with glibc 2.25
22d461
-     * - FreeBSD since 12.0 (1200061)
22d461
-     *
22d461
-     * Note: Sometimes getentropy() can be provided but not implemented
22d461
-     * internally. So we need to check errno for ENOSYS
22d461
-     */
22d461
-#  if !defined(__DragonFly__) && !defined(__NetBSD__)
22d461
-#    if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux)
22d461
-    extern int getentropy(void *buffer, size_t length) __attribute__((weak));
22d461
-
22d461
-    if (getentropy != NULL) {
22d461
-        if (getentropy(buf, buflen) == 0)
22d461
-            return (ssize_t)buflen;
22d461
-        if (errno != ENOSYS)
22d461
-            return -1;
22d461
-    }
22d461
-#    elif defined(OPENSSL_APPLE_CRYPTO_RANDOM)
22d461
-
22d461
-    if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess)
22d461
-	    return (ssize_t)buflen;
22d461
-
22d461
-    return -1;
22d461
-#    else
22d461
-    union {
22d461
-        void *p;
22d461
-        int (*f)(void *buffer, size_t length);
22d461
-    } p_getentropy;
22d461
-
22d461
-    /*
22d461
-     * We could cache the result of the lookup, but we normally don't
22d461
-     * call this function often.
22d461
-     */
22d461
-    ERR_set_mark();
22d461
-    p_getentropy.p = DSO_global_lookup("getentropy");
22d461
-    ERR_pop_to_mark();
22d461
-    if (p_getentropy.p != NULL)
22d461
-        return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1;
22d461
-#    endif
22d461
-#  endif /* !__DragonFly__ */
22d461
-
22d461
-    /* Linux supports this since version 3.17 */
22d461
-#  if defined(__linux) && defined(__NR_getrandom)
22d461
-    return syscall(__NR_getrandom, buf, buflen, 0);
22d461
-#  elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
22d461
-    return sysctl_random(buf, buflen);
22d461
-#  elif (defined(__DragonFly__)  && __DragonFly_version >= 500700) \
22d461
-     || (defined(__NetBSD__) && __NetBSD_Version >= 1000000000)
22d461
-    return getrandom(buf, buflen, 0);
22d461
-#  else
22d461
-    errno = ENOSYS;
22d461
-    return -1;
22d461
-#  endif
22d461
+    /* Red Hat uses downstream patch to always seed from getrandom() */
22d461
+    return EVP_default_properties_is_fips_enabled(NULL) ? getrandom(buf, buflen, GRND_RANDOM) : getrandom(buf, buflen, 0);
22d461
 }
22d461
 #  endif    /* defined(OPENSSL_RAND_SEED_GETRANDOM) */
22d461
 
22d461
diff -up openssl-3.0.1/providers/implementations/rands/drbg.c.fipsrand openssl-3.0.1/providers/implementations/rands/drbg.c
22d461
--- openssl-3.0.1/providers/implementations/rands/drbg.c.fipsrand	2022-08-03 12:14:39.409370134 +0200
22d461
+++ openssl-3.0.1/providers/implementations/rands/drbg.c	2022-08-03 12:19:06.320700346 +0200
22d461
@@ -575,6 +575,9 @@ int ossl_prov_drbg_reseed(PROV_DRBG *drb
22d461
 #endif
22d461
     }
22d461
 
22d461
+#ifdef FIPS_MODULE
22d461
+    prediction_resistance = 1;
22d461
+#endif
22d461
     /* Reseed using our sources in addition */
22d461
     entropylen = get_entropy(drbg, &entropy, drbg->strength,
22d461
                              drbg->min_entropylen, drbg->max_entropylen,
22d461
diff -up openssl-3.0.1/crypto/rand/prov_seed.c.fipsrand openssl-3.0.1/crypto/rand/prov_seed.c
22d461
--- openssl-3.0.1/crypto/rand/prov_seed.c.fipsrand	2022-08-04 12:17:52.148556301 +0200
22d461
+++ openssl-3.0.1/crypto/rand/prov_seed.c	2022-08-04 12:19:41.783533552 +0200
22d461
@@ -20,7 +20,14 @@ size_t ossl_rand_get_entropy(ossl_unused
22d461
     size_t entropy_available;
22d461
     RAND_POOL *pool;
22d461
 
22d461
-    pool = ossl_rand_pool_new(entropy, 1, min_len, max_len);
22d461
+    /*
22d461
+     * OpenSSL still implements an internal entropy pool of
22d461
+     * some size that is hashed to get seed data.
22d461
+     * Note that this is a conditioning step for which SP800-90C requires
22d461
+     * 64 additional bits from the entropy source to claim the requested
22d461
+     * amount of entropy.
22d461
+     */
22d461
+    pool = ossl_rand_pool_new(entropy + 64, 1, min_len, max_len);
22d461
     if (pool == NULL) {
22d461
         ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
22d461
         return 0;
22d461
diff -up openssl-3.0.1/providers/implementations/rands/crngt.c.fipsrand openssl-3.0.1/providers/implementations/rands/crngt.c
22d461
--- openssl-3.0.1/providers/implementations/rands/crngt.c.fipsrand	2022-08-04 11:56:10.100950299 +0200
22d461
+++ openssl-3.0.1/providers/implementations/rands/crngt.c	2022-08-04 11:59:11.241564925 +0200
22d461
@@ -139,7 +139,11 @@ size_t ossl_crngt_get_entropy(PROV_DRBG
22d461
      * to the nearest byte.  If the entropy is of less than full quality,
22d461
      * the amount required should be scaled up appropriately here.
22d461
      */
22d461
-    bytes_needed = (entropy + 7) / 8;
22d461
+    /*
22d461
+     * FIPS 140-3: the yet draft SP800-90C requires requested entropy
22d461
+     * + 128 bits during initial seeding
22d461
+     */
22d461
+    bytes_needed = (entropy + 128 + 7) / 8;
22d461
     if (bytes_needed < min_len)
22d461
         bytes_needed = min_len;
22d461
     if (bytes_needed > max_len)