From a05f2001ef61780044703d718359ad02714ca838 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Tue, 16 Jun 2026 14:23:19 -0700 Subject: [PATCH 1/3] wp_drbg: gate wc_RNG_DRBG_Reseed on FIPS version wc_RNG_DRBG_Reseed is WOLFSSL_LOCAL in FIPS v5.2.1 (cert4718), causing an undefined-reference link failure; it is public in non-FIPS >= 5.7.2 and FIPS v5.2.4/v6/v7. Gate WP_HAVE_DRBG_RESEED on the FIPS version in settings.h and reseed in place when public, else re-instantiate. Also map --fips-check=v5.2.4 to --enable-fips=v5.2.4 instead of collapsing to v5. --- include/wolfprovider/settings.h | 21 +++++ scripts/utils-wolfssl.sh | 8 ++ src/wp_drbg.c | 144 ++++++++++++++++++++++++++++---- 3 files changed, 158 insertions(+), 15 deletions(-) diff --git a/include/wolfprovider/settings.h b/include/wolfprovider/settings.h index 151bc707..11c93b58 100644 --- a/include/wolfprovider/settings.h +++ b/include/wolfprovider/settings.h @@ -28,6 +28,27 @@ #include #include +/* wc_RNG_DRBG_Reseed is public (WOLFSSL_API) in non-FIPS >= 5.7.2 and FIPS + * v5.2.4+/v6/v7, but WOLFSSL_LOCAL in FIPS v5.2.1 (cert4718). Nested guards so + * an undefined FIPS version component means fallback, not a -Wundef error. */ +#if !defined(HAVE_FIPS) + #if LIBWOLFSSL_VERSION_HEX >= 0x05007002 + #define WP_HAVE_DRBG_RESEED + #endif +#elif !defined(HAVE_FIPS_VERSION_MAJOR) + /* FIPS with unknown version: fall back. */ +#elif HAVE_FIPS_VERSION_MAJOR > 5 + #define WP_HAVE_DRBG_RESEED +#elif HAVE_FIPS_VERSION_MAJOR == 5 && defined(HAVE_FIPS_VERSION_MINOR) + #if HAVE_FIPS_VERSION_MINOR > 2 + #define WP_HAVE_DRBG_RESEED + #elif HAVE_FIPS_VERSION_MINOR == 2 && defined(HAVE_FIPS_VERSION_PATCH) + #if HAVE_FIPS_VERSION_PATCH >= 4 + #define WP_HAVE_DRBG_RESEED + #endif + #endif +#endif + #define WP_HAVE_DIGEST #if !defined(NO_MD5) #define WP_HAVE_MD5 diff --git a/scripts/utils-wolfssl.sh b/scripts/utils-wolfssl.sh index ea789733..e259cdff 100644 --- a/scripts/utils-wolfssl.sh +++ b/scripts/utils-wolfssl.sh @@ -179,7 +179,15 @@ install_wolfssl() { # Determine configure option from tag local fips_configure_arg="" case "$fips_tag" in + v5.2.4|linuxv5.2.4) + # Distinct module (SP math, PATCH 4) — not the v5/cert4718 base + fips_configure_arg="v5.2.4" + ;; + v5.2.3|linuxv5.2.3) + fips_configure_arg="v5.2.3" + ;; v5.2.*|v5.3.*|v5.4.*|v5.5.*|linuxv5.*) + # v5.2.1/cert4718 and other v5.x map to the base v5 module fips_configure_arg="v5" ;; v6.*|linuxv6.*) diff --git a/src/wp_drbg.c b/src/wp_drbg.c index b68a5352..ecb5308b 100644 --- a/src/wp_drbg.c +++ b/src/wp_drbg.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -61,6 +62,10 @@ typedef struct wp_DrbgCtx { OSSL_FUNC_rand_get_seed_fn* parentGetSeed; /** Parent's clear_seed function. */ OSSL_FUNC_rand_clear_seed_fn* parentClearSeed; +#ifndef WP_HAVE_DRBG_RESEED + /** Set when a failed reseed re-instantiation left ctx->rng de-instantiated. */ + int rngError; +#endif } wp_DrbgCtx; @@ -143,6 +148,8 @@ static void wp_drbg_free(wp_DrbgCtx* ctx) } } +static int wp_drbg_uninstantiate(wp_DrbgCtx* ctx); + /** * Instantiate a new DRBG. * @@ -171,6 +178,11 @@ static int wp_drbg_instantiate(wp_DrbgCtx* ctx, unsigned int strength, ok = 0; } + /* Free any existing DRBG before re-allocating to avoid a leak. */ + if (ok && ctx->rng != NULL) { + wp_drbg_uninstantiate(ctx); + } + if (ok && ctx->parentGetSeed != NULL) { /* Get entropy from parent DRBG (no file I/O needed) */ WOLFPROV_MSG_DEBUG(WP_LOG_COMP_RNG, @@ -189,22 +201,29 @@ static int wp_drbg_instantiate(wp_DrbgCtx* ctx, unsigned int strength, } if (ok) { - /* Initialize wolfCrypt RNG with parent-provided seed */ - ctx->rng = OPENSSL_zalloc(sizeof(*ctx->rng)); + /* Use wc_rng_new (>= 5.0) so alloc and free use the same allocator, + * matching the root path and wc_rng_free() in teardown. */ + #if LIBWOLFSSL_VERSION_HEX >= 0x05000000 + ctx->rng = wc_rng_new(seed, (word32)seedLen, NULL); if (ctx->rng == NULL) { ok = 0; } - } - - if (ok) { - int rc = wc_InitRngNonce(ctx->rng, seed, (word32)seedLen); - if (rc != 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, - "wc_InitRngNonce", rc); - OPENSSL_free(ctx->rng); - ctx->rng = NULL; + #else + ctx->rng = OPENSSL_zalloc(sizeof(*ctx->rng)); + if (ctx->rng == NULL) { ok = 0; } + if (ok) { + int rc = wc_InitRngNonce(ctx->rng, seed, (word32)seedLen); + if (rc != 0) { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, + "wc_InitRngNonce", rc); + OPENSSL_clear_free(ctx->rng, sizeof(*ctx->rng)); + ctx->rng = NULL; + ok = 0; + } + } + #endif } /* Clear the seed from parent */ @@ -242,6 +261,13 @@ static int wp_drbg_instantiate(wp_DrbgCtx* ctx, unsigned int strength, #endif } +#ifndef WP_HAVE_DRBG_RESEED + if (ok) { + /* Clear any prior reseed error state. */ + ctx->rngError = 0; + } +#endif + WOLFPROV_LEAVE(WP_LOG_COMP_RNG, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; } @@ -262,6 +288,9 @@ static int wp_drbg_uninstantiate(wp_DrbgCtx* ctx) OPENSSL_clear_free(ctx->rng, sizeof(*ctx->rng)); #endif ctx->rng = NULL; +#ifndef WP_HAVE_DRBG_RESEED + ctx->rngError = 0; +#endif WOLFPROV_LEAVE(WP_LOG_COMP_RNG, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 1); return 1; } @@ -292,6 +321,16 @@ static int wp_drbg_generate(wp_DrbgCtx* ctx, unsigned char* out, if (strength > WP_DRBG_STRENGTH) { ok = 0; } + if (ok && ctx->rng == NULL) { + WOLFPROV_MSG_DEBUG(WP_LOG_COMP_RNG, "DRBG not instantiated"); + ok = 0; + } +#ifndef WP_HAVE_DRBG_RESEED + if (ok && ctx->rngError) { + WOLFPROV_MSG_DEBUG(WP_LOG_COMP_RNG, "DRBG in error state"); + ok = 0; + } +#endif #if 0 if (ok && (addInLen > 0)) { rc = wc_RNG_DRBG_Reseed(ctx->rng, addIn, addInLen); @@ -322,6 +361,10 @@ static int wp_drbg_generate(wp_DrbgCtx* ctx, unsigned char* out, /** * Reseed DRBG. * + * When WP_HAVE_DRBG_RESEED is undefined (FIPS modules without an exported + * wc_RNG_DRBG_Reseed), this re-instantiates rather than reseeding: @p entropy / + * @p addIn are used as the nonce, not as DRBG entropy_input. + * * @param [in, out] ctx DRBG context object. * @param [in] predResist Prediction resistance required. * @param [in] entropy Entropy data to reseed with. @@ -343,8 +386,13 @@ static int wp_drbg_reseed(wp_DrbgCtx* ctx, int predResist, WOLFPROV_ENTER(WP_LOG_COMP_RNG, "wp_drbg_reseed"); + /* Reseed requires an instantiated DRBG. */ + if (ctx->rng == NULL) { + ok = 0; + } + /* If no entropy provided, get fresh entropy from the OS source. */ - if (entropy == NULL || entropyLen == 0) { + if (ok && (entropy == NULL || entropyLen == 0)) { seedLen = 48; seed = OPENSSL_malloc(seedLen); if (seed == NULL) { @@ -363,6 +411,16 @@ static int wp_drbg_reseed(wp_DrbgCtx* ctx, int predResist, } } + /* wolfCrypt RNG APIs take word32 lengths; reject oversized inputs. */ + if (ok && entropyLen > 0xFFFFFFFFU) { + ok = 0; + } + if (ok && addIn != NULL && addInLen > 0xFFFFFFFFU) { + ok = 0; + } + +#ifdef WP_HAVE_DRBG_RESEED + /* In-place SP 800-90A reseed via wolfCrypt's public DRBG API. */ if (ok && entropy != NULL && entropyLen > 0) { rc = wc_RNG_DRBG_Reseed(ctx->rng, entropy, (word32)entropyLen); if (rc != 0) { @@ -379,6 +437,52 @@ static int wp_drbg_reseed(wp_DrbgCtx* ctx, int predResist, ok = 0; } } +#else + /* FIPS modules without an exported wc_RNG_DRBG_Reseed (e.g. cert4718): + * re-instantiate in place via wc_FreeRng() + wc_InitRngNonce() on the same + * WC_RNG struct (entropy/addIn used as the nonce, not as reseed input). A + * failed re-init leaves the DRBG de-instantiated and sets rngError. */ + if (ok && entropy != NULL && entropyLen > 0) { + unsigned char* nonce = NULL; + word32 nonceLen = 0; + + /* Guard against overflow when concatenating entropy || addIn. */ + if (addIn != NULL && addInLen > (0xFFFFFFFFU - entropyLen)) { + ok = 0; + } + if (ok) { + nonceLen = (word32)entropyLen + + ((addIn != NULL) ? (word32)addInLen : 0); + nonce = OPENSSL_malloc(nonceLen); + if (nonce == NULL) { + ok = 0; + } + } + if (ok) { + XMEMCPY(nonce, entropy, entropyLen); + if (addIn != NULL && addInLen > 0) { + XMEMCPY(nonce + entropyLen, addIn, addInLen); + } + } + if (ok) { + wc_FreeRng(ctx->rng); + rc = wc_InitRngNonce(ctx->rng, nonce, nonceLen); + if (rc != 0) { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, + "wc_InitRngNonce", rc); + ctx->rngError = 1; + ok = 0; + } + else { + /* Recovered: clear any prior reseed error. */ + ctx->rngError = 0; + } + } + if (nonce != NULL) { + OPENSSL_clear_free(nonce, nonceLen); + } + } +#endif /* WP_HAVE_DRBG_RESEED */ /* Securely clear and free locally allocated seed buffer. */ if (seed != NULL) { @@ -512,15 +616,25 @@ static int wp_drbg_get_ctx_params(wp_DrbgCtx* ctx, OSSL_PARAM params[]) WOLFPROV_ENTER(WP_LOG_COMP_RNG, "wp_drbg_get_ctx_params"); - (void)ctx; - p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); if ((p != NULL) && (!OSSL_PARAM_set_size_t(p, WP_DRBG_MAX_REQUESTS))) { ok = 0; } if (ok) { + int state = EVP_RAND_STATE_READY; + + if (ctx->rng == NULL) { + state = EVP_RAND_STATE_UNINITIALISED; + } + #ifndef WP_HAVE_DRBG_RESEED + /* Failed reseed re-instantiation left the DRBG de-instantiated. */ + else if (ctx->rngError) { + state = EVP_RAND_STATE_ERROR; + } + #endif + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE); - if ((p != NULL) && (!OSSL_PARAM_set_int(p, EVP_RAND_STATE_READY))) { + if ((p != NULL) && (!OSSL_PARAM_set_int(p, state))) { ok = 0; } } From 4d22a1b1e8214bb78a96bdc55f3a970573973478 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Tue, 16 Jun 2026 16:17:02 -0700 Subject: [PATCH 2/3] wp_drbg: handle null reseed entropy, keep reseed seccomp-safe Draw fresh entropy via wp_urandom_read (cached /dev/urandom fd, survives a seccomp sandbox) on the native path when the caller supplies none; the cert4718 fallback self-seeds via wc_InitRngNonce. Neither path opens a file during reseed. Fixes null-entropy handling the fallback previously skipped, and guards wp_drbg_get_seed while the DRBG is in an error state. --- src/wp_drbg.c | 133 +++++++++++++++++++++--------------- test/test_seccomp_sandbox.c | 21 ++++++ 2 files changed, 99 insertions(+), 55 deletions(-) diff --git a/src/wp_drbg.c b/src/wp_drbg.c index ecb5308b..bbdbdc5c 100644 --- a/src/wp_drbg.c +++ b/src/wp_drbg.c @@ -381,8 +381,6 @@ static int wp_drbg_reseed(wp_DrbgCtx* ctx, int predResist, { int ok = 1; int rc; - unsigned char *seed = NULL; - size_t seedLen = 0; WOLFPROV_ENTER(WP_LOG_COMP_RNG, "wp_drbg_reseed"); @@ -391,28 +389,8 @@ static int wp_drbg_reseed(wp_DrbgCtx* ctx, int predResist, ok = 0; } - /* If no entropy provided, get fresh entropy from the OS source. */ - if (ok && (entropy == NULL || entropyLen == 0)) { - seedLen = 48; - seed = OPENSSL_malloc(seedLen); - if (seed == NULL) { - ok = 0; - } - if (ok) { - OS_Seed osSeed; - rc = wc_GenerateSeed(&osSeed, seed, (word32)seedLen); - if (rc != 0) { - ok = 0; - } - else { - entropy = seed; - entropyLen = seedLen; - } - } - } - /* wolfCrypt RNG APIs take word32 lengths; reject oversized inputs. */ - if (ok && entropyLen > 0xFFFFFFFFU) { + if (ok && entropy != NULL && entropyLen > 0xFFFFFFFFU) { ok = 0; } if (ok && addIn != NULL && addInLen > 0xFFFFFFFFU) { @@ -420,48 +398,92 @@ static int wp_drbg_reseed(wp_DrbgCtx* ctx, int predResist, } #ifdef WP_HAVE_DRBG_RESEED - /* In-place SP 800-90A reseed via wolfCrypt's public DRBG API. */ - if (ok && entropy != NULL && entropyLen > 0) { - rc = wc_RNG_DRBG_Reseed(ctx->rng, entropy, (word32)entropyLen); - if (rc != 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, - "wc_RNG_DRBG_Reseed", rc); - ok = 0; + { + unsigned char* seed = NULL; + size_t seedLen = 0; + + /* An in-place reseed needs explicit entropy. If the caller supplied + * none, draw fresh entropy from the cached /dev/urandom fd (SEED-SRC), + * which stays open across a seccomp sandbox, rather than + * wc_GenerateSeed() which opens /dev/urandom directly and would be + * blocked under the sandbox. */ + if (ok && (entropy == NULL || entropyLen == 0)) { + seedLen = 48; + seed = OPENSSL_malloc(seedLen); + if (seed == NULL) { + ok = 0; + } + if (ok) { + #if defined(WP_HAVE_SEED_SRC) && defined(WP_HAVE_RANDOM) + if (wp_urandom_read(seed, seedLen) != (int)seedLen) { + ok = 0; + } + #else + OS_Seed osSeed; + if (wc_GenerateSeed(&osSeed, seed, (word32)seedLen) != 0) { + ok = 0; + } + #endif + } + if (ok) { + entropy = seed; + entropyLen = seedLen; + } } - } - if (ok && (addInLen > 0) && (addIn != NULL)) { - rc = wc_RNG_DRBG_Reseed(ctx->rng, addIn, (word32)addInLen); - if (rc != 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, - "wc_RNG_DRBG_Reseed", rc); - ok = 0; + + /* In-place SP 800-90A reseed via wolfCrypt's public DRBG API. */ + if (ok && entropy != NULL && entropyLen > 0) { + rc = wc_RNG_DRBG_Reseed(ctx->rng, entropy, (word32)entropyLen); + if (rc != 0) { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, + "wc_RNG_DRBG_Reseed", rc); + ok = 0; + } + } + if (ok && (addInLen > 0) && (addIn != NULL)) { + rc = wc_RNG_DRBG_Reseed(ctx->rng, addIn, (word32)addInLen); + if (rc != 0) { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, + "wc_RNG_DRBG_Reseed", rc); + ok = 0; + } + } + + if (seed != NULL) { + OPENSSL_clear_free(seed, seedLen); } } #else /* FIPS modules without an exported wc_RNG_DRBG_Reseed (e.g. cert4718): * re-instantiate in place via wc_FreeRng() + wc_InitRngNonce() on the same - * WC_RNG struct (entropy/addIn used as the nonce, not as reseed input). A - * failed re-init leaves the DRBG de-instantiated and sets rngError. */ - if (ok && entropy != NULL && entropyLen > 0) { + * WC_RNG struct. wc_InitRngNonce self-seeds fresh entropy_input; with + * SEED-SRC that entropy comes from the cached /dev/urandom fd via the seed + * callback (so it stays sandbox-safe), otherwise from wc_GenerateSeed(). + * Caller entropy/addIn are folded in only as the nonce (which may be empty). + * A failed re-init leaves the DRBG de-instantiated and sets rngError. */ + if (ok) { unsigned char* nonce = NULL; word32 nonceLen = 0; + word32 eLen = (entropy != NULL) ? (word32)entropyLen : 0; + word32 aLen = (addIn != NULL) ? (word32)addInLen : 0; - /* Guard against overflow when concatenating entropy || addIn. */ - if (addIn != NULL && addInLen > (0xFFFFFFFFU - entropyLen)) { + /* Build nonce = entropy || addIn (either may be absent). */ + if (aLen > (0xFFFFFFFFU - eLen)) { ok = 0; } - if (ok) { - nonceLen = (word32)entropyLen + - ((addIn != NULL) ? (word32)addInLen : 0); + if (ok && (eLen + aLen) > 0) { + nonceLen = eLen + aLen; nonce = OPENSSL_malloc(nonceLen); if (nonce == NULL) { ok = 0; } - } - if (ok) { - XMEMCPY(nonce, entropy, entropyLen); - if (addIn != NULL && addInLen > 0) { - XMEMCPY(nonce + entropyLen, addIn, addInLen); + else { + if (eLen > 0) { + XMEMCPY(nonce, entropy, eLen); + } + if (aLen > 0) { + XMEMCPY(nonce + eLen, addIn, aLen); + } } } if (ok) { @@ -484,11 +506,6 @@ static int wp_drbg_reseed(wp_DrbgCtx* ctx, int predResist, } #endif /* WP_HAVE_DRBG_RESEED */ - /* Securely clear and free locally allocated seed buffer. */ - if (seed != NULL) { - OPENSSL_clear_free(seed, seedLen); - } - (void)predResist; WOLFPROV_LEAVE(WP_LOG_COMP_RNG, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); @@ -736,6 +753,12 @@ static size_t wp_drbg_get_seed(wp_DrbgCtx* ctx, unsigned char** pSeed, "DRBG not instantiated"); goto end; } +#ifndef WP_HAVE_DRBG_RESEED + if (ctx->rngError) { + WOLFPROV_MSG_DEBUG(WP_LOG_COMP_RNG, "DRBG in error state"); + goto end; + } +#endif buffer = OPENSSL_secure_malloc(minLen); if (buffer == NULL) { diff --git a/test/test_seccomp_sandbox.c b/test/test_seccomp_sandbox.c index 82d65b94..8b3f3e42 100644 --- a/test/test_seccomp_sandbox.c +++ b/test/test_seccomp_sandbox.c @@ -269,6 +269,27 @@ static int child_test_rand_under_sandbox(OSSL_LIB_CTX *libCtx) err = 1; } + /* Explicitly reseed the public DRBG under the sandbox. With NULL entropy + * this drives wp_drbg_reseed()'s fresh-entropy path, which must use the + * cached /dev/urandom fd (SEED-SRC) and must not open() /dev/urandom. */ + if (err == 0) { + EVP_RAND_CTX *rctx = RAND_get0_public(libCtx); + if (rctx == NULL) { + PRINT_ERR_MSG("RAND_get0_public failed under sandbox"); + err = 1; + } + else if (EVP_RAND_reseed(rctx, 0, NULL, 0, NULL, 0) != 1) { + PRINT_ERR_MSG("EVP_RAND_reseed failed under sandbox"); + err = 1; + } + } + + /* Confirm the DRBG is still usable after the sandboxed reseed. */ + if (err == 0 && RAND_bytes(buf, sizeof(buf)) != 1) { + PRINT_ERR_MSG("RAND_bytes after reseed failed under sandbox"); + err = 1; + } + OSSL_LIB_CTX_set0_default(origCtx); return err; } From 1f1026d6246c62b97399c7bc8a334dd013204763 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Wed, 17 Jun 2026 11:49:56 -0700 Subject: [PATCH 3/3] settings: gate DRBG reseed conservatively (FIPS v5.x linkage varies by bundle) wc_RNG_DRBG_Reseed visibility is not predictable from the FIPS version: across frozen commercial bundles the same v5.2.4 cert is WOLFSSL_LOCAL on a 5.8.4 wrapper but WOLFSSL_API on a 5.9.1 wrapper, so the prior "v5.2.4+ -> native" gate hit `undefined reference to wc_RNG_DRBG_Reseed` on 5.8.4+v5.2.4. Use the native in-place reseed only where the symbol is reliably exported (non-FIPS >= 5.7.2, FIPS v6+) and fall back to DRBG re-instantiation for all FIPS v5.x. Add WP_NO_DRBG_RESEED to force the fallback for any bundle that keeps the symbol WOLFSSL_LOCAL despite its version. Verified: builds + full unit suite pass on 5.8.4/5.9.1 wrappers x v5.2.1/v5.2.4 commercial FIPS bundles (5/5, 136/0). --- include/wolfprovider/settings.h | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/include/wolfprovider/settings.h b/include/wolfprovider/settings.h index 11c93b58..c9754f46 100644 --- a/include/wolfprovider/settings.h +++ b/include/wolfprovider/settings.h @@ -28,25 +28,22 @@ #include #include -/* wc_RNG_DRBG_Reseed is public (WOLFSSL_API) in non-FIPS >= 5.7.2 and FIPS - * v5.2.4+/v6/v7, but WOLFSSL_LOCAL in FIPS v5.2.1 (cert4718). Nested guards so - * an undefined FIPS version component means fallback, not a -Wundef error. */ -#if !defined(HAVE_FIPS) +/* wc_RNG_DRBG_Reseed is WOLFSSL_API in non-FIPS >= 5.7.2 and in FIPS v6+. + * Across FIPS v5.x commercial bundles its linkage is inconsistent: some v5.2.4 + * bundles export it and others keep it WOLFSSL_LOCAL (it depends on both the + * wolfSSL wrapper version and the FIPS cert), so it cannot be predicted from + * the version macros. Use the native in-place reseed only where the symbol is + * reliably exported and fall back to DRBG re-instantiation otherwise (which + * links on every build). Define WP_NO_DRBG_RESEED to force the fallback for a + * bundle that keeps the symbol WOLFSSL_LOCAL despite its version. */ +#if defined(WP_NO_DRBG_RESEED) + /* caller forced the re-instantiation fallback */ +#elif !defined(HAVE_FIPS) #if LIBWOLFSSL_VERSION_HEX >= 0x05007002 #define WP_HAVE_DRBG_RESEED #endif -#elif !defined(HAVE_FIPS_VERSION_MAJOR) - /* FIPS with unknown version: fall back. */ -#elif HAVE_FIPS_VERSION_MAJOR > 5 +#elif defined(HAVE_FIPS_VERSION_MAJOR) && HAVE_FIPS_VERSION_MAJOR >= 6 #define WP_HAVE_DRBG_RESEED -#elif HAVE_FIPS_VERSION_MAJOR == 5 && defined(HAVE_FIPS_VERSION_MINOR) - #if HAVE_FIPS_VERSION_MINOR > 2 - #define WP_HAVE_DRBG_RESEED - #elif HAVE_FIPS_VERSION_MINOR == 2 && defined(HAVE_FIPS_VERSION_PATCH) - #if HAVE_FIPS_VERSION_PATCH >= 4 - #define WP_HAVE_DRBG_RESEED - #endif - #endif #endif #define WP_HAVE_DIGEST