From 4b59d71e276243615d8fcc65bab32d83e6a602ad Mon Sep 17 00:00:00 2001 From: rpm-build Date: Mon, 31 Jul 2023 09:41:29 +0200 Subject: [PATCH 32/35] 0076-FIPS-140-3-DRBG.patch Patch-name: 0076-FIPS-140-3-DRBG.patch Patch-id: 76 Patch-status: | # Downstream only. Reseed DRBG using getrandom(GRND_RANDOM) # https://bugzilla.redhat.com/show_bug.cgi?id=2102541 From-dist-git-commit: 9409bc7044cf4b5773639cce20f51399888c45fd --- crypto/rand/prov_seed.c | 9 ++- providers/implementations/rands/crngt.c | 6 +- providers/implementations/rands/drbg.c | 3 + .../implementations/rands/seeding/rand_unix.c | 64 ++----------------- 4 files changed, 20 insertions(+), 62 deletions(-) diff --git a/crypto/rand/prov_seed.c b/crypto/rand/prov_seed.c index 96c499c957..61c4cd8779 100644 --- a/crypto/rand/prov_seed.c +++ b/crypto/rand/prov_seed.c @@ -20,7 +20,14 @@ size_t ossl_rand_get_entropy(ossl_unused const OSSL_CORE_HANDLE *handle, size_t entropy_available; RAND_POOL *pool; - pool = ossl_rand_pool_new(entropy, 1, min_len, max_len); + /* + * OpenSSL still implements an internal entropy pool of + * some size that is hashed to get seed data. + * Note that this is a conditioning step for which SP800-90C requires + * 64 additional bits from the entropy source to claim the requested + * amount of entropy. + */ + pool = ossl_rand_pool_new(entropy + 64, 1, min_len, max_len); if (pool == NULL) { ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); return 0; diff --git a/providers/implementations/rands/crngt.c b/providers/implementations/rands/crngt.c index fa4a2db14a..1f13fc759e 100644 --- a/providers/implementations/rands/crngt.c +++ b/providers/implementations/rands/crngt.c @@ -133,7 +133,11 @@ size_t ossl_crngt_get_entropy(PROV_DRBG *drbg, * to the nearest byte. If the entropy is of less than full quality, * the amount required should be scaled up appropriately here. */ - bytes_needed = (entropy + 7) / 8; + /* + * FIPS 140-3: the yet draft SP800-90C requires requested entropy + * + 128 bits during initial seeding + */ + bytes_needed = (entropy + 128 + 7) / 8; if (bytes_needed < min_len) bytes_needed = min_len; if (bytes_needed > max_len) diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c index ea55363bf8..423bb91157 100644 --- a/providers/implementations/rands/drbg.c +++ b/providers/implementations/rands/drbg.c @@ -570,6 +570,9 @@ int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance, #endif } +#ifdef FIPS_MODULE + prediction_resistance = 1; +#endif /* Reseed using our sources in addition */ entropylen = get_entropy(drbg, &entropy, drbg->strength, drbg->min_entropylen, drbg->max_entropylen, diff --git a/providers/implementations/rands/seeding/rand_unix.c b/providers/implementations/rands/seeding/rand_unix.c index cd02a0236d..98c917b6d8 100644 --- a/providers/implementations/rands/seeding/rand_unix.c +++ b/providers/implementations/rands/seeding/rand_unix.c @@ -48,6 +48,8 @@ # include # include # include +# include +# include static uint64_t get_time_stamp(void); @@ -341,66 +343,8 @@ static ssize_t syscall_random(void *buf, size_t buflen) * which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion * between size_t and ssize_t is safe even without a range check. */ - - /* - * Do runtime detection to find getentropy(). - * - * Known OSs that should support this: - * - Darwin since 16 (OSX 10.12, IOS 10.0). - * - Solaris since 11.3 - * - OpenBSD since 5.6 - * - Linux since 3.17 with glibc 2.25 - * - FreeBSD since 12.0 (1200061) - * - * Note: Sometimes getentropy() can be provided but not implemented - * internally. So we need to check errno for ENOSYS - */ -# if !defined(__DragonFly__) && !defined(__NetBSD__) -# if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) - extern int getentropy(void *buffer, size_t length) __attribute__((weak)); - - if (getentropy != NULL) { - if (getentropy(buf, buflen) == 0) - return (ssize_t)buflen; - if (errno != ENOSYS) - return -1; - } -# elif defined(OPENSSL_APPLE_CRYPTO_RANDOM) - - if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) - return (ssize_t)buflen; - - return -1; -# else - union { - void *p; - int (*f)(void *buffer, size_t length); - } p_getentropy; - - /* - * We could cache the result of the lookup, but we normally don't - * call this function often. - */ - ERR_set_mark(); - p_getentropy.p = DSO_global_lookup("getentropy"); - ERR_pop_to_mark(); - if (p_getentropy.p != NULL) - return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; -# endif -# endif /* !__DragonFly__ */ - - /* Linux supports this since version 3.17 */ -# if defined(__linux) && defined(__NR_getrandom) - return syscall(__NR_getrandom, buf, buflen, 0); -# elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND) - return sysctl_random(buf, buflen); -# elif (defined(__DragonFly__) && __DragonFly_version >= 500700) \ - || (defined(__NetBSD__) && __NetBSD_Version >= 1000000000) - return getrandom(buf, buflen, 0); -# else - errno = ENOSYS; - return -1; -# endif + /* Red Hat uses downstream patch to always seed from getrandom() */ + return EVP_default_properties_is_fips_enabled(NULL) ? getrandom(buf, buflen, GRND_RANDOM) : getrandom(buf, buflen, 0); } # endif /* defined(OPENSSL_RAND_SEED_GETRANDOM) */ -- 2.41.0