wolfcrypt/test/test.c: work around false positive cppcheck nullPointer warning in random_bank_test().
CMakeLists.txt, cmake/options.h.in: add WOLFSSL_SLHDSAVERIFYONLY.
wolfcrypt/src/random.c: allow WC_HAVE_RNG_BANKREF with HAVE_FIPS if WOLFSSL_FIPS_DEV.
wolfssl/wolfcrypt/random.h:
* remove WC_RNG_BANK_SUPPORT from the exclusion list for WC_RNG_LOCK_ATFORK
* pivot WC_HAVE_RNG_BANKREF on WC_RNG_WANT_BANKREF_SUPPORT, with FIPS exclusion.
wolfcrypt/src/rng_bank.c: update wc_InitRng_BankRef_local() and wc_BankRef_Release() to use WC_RNG_FLAG_BANKREF, not WC_DRBG_BANKREF.
wolfssl/wolfcrypt/rng_bank.h: remove backward-compat clause defining WC_HAVE_RNG_BANKREF.
linuxkm/lkcapi_rsa_glue.c: refactor km_rsa_ctx_init_rng() to check ctx->rng.flags, not ctx->rng.status, for bankref status.
configure.ac: in ENABLED_RNG_BANK setup, split out WC_RNG_WANT_BANKREF_SUPPORT as a separate flag, and don't define it if FIPS.
wolfcrypt/benchmark/fips_cast_bench.c: omit bench_pct_slhdsa() if defined(WOLFSSL_SLHDSA_VERIFY_ONLY).
wolfcrypt/test/test.c: in myCryptoDevCb(), add HAVE_INTEL_RDRAND to list of macros enabling use of wc_RNG_GenerateBlock() for WC_ALGO_TYPE_RNG.
linuxkm/Makefile: use bash-4.3-compatible syntax in $(()) expression.
.wolfssl_known_macro_extras: remove unneeded entries.
linuxkm/lkcapi_sha_glue.c: in wc_linuxkm_drbg_generate_tfm(), break out of the loop unconditionally if !WC_LINUXKM_HAVE_RNG_INVALIDATION, matching other nearby generator loops.
wolfcrypt/src/random.c:
* in Hash_df() and Hash512_df(), break out of the generate loop on error.
* in Hash_DRBG_Generate() and Hash512_DRBG_Generate(), wipe output blocks on error (otherwise, future retry will recapitulate some of the same output bytes, since errors no longer leave mutated state).
* in Hash_DRBG_StirGenerate(), map error codes from Hash*_DRBG_Generate() correctly.
* in wc_RNG_GenerateBlock(), return early from failed wc_RNG_DRBG_NextSeedNow_local() for both DRBG_CONT_FIPS_E and RNG_FAILURE_E.
wolfcrypt/src/sha256.c, wolfcrypt/src/sha512.c, wolfcrypt/src/sha3.c:
* Don't exclude WOLFSSL_ASYNC_CRYPT from in-place (true) reset implementations -- the Free+Init_ex fallback silently dropped the async device binding, and async builds are compatible with in-place reset.
* Remove frivolous asserts on in-place reset implementation when WOLFSSL_KERNEL_MODE.
linuxkm/lkcapi_sha_glue.c: in wc_linuxkm_entropy_daemon(), relax the invalidation-time root_rng reseed loop with an actual sleep, to prevent flat-out retry spinning.
wolfcrypt/src/random.c: in wc_FreeRng(), wipe rng->nextStir.
wolfcrypt/src/sha3.c: fix wc_Shake128_Reset() and wc_Shake256_Reset() to properly set shake->hashType.
linuxkm/lkcapi_sha_glue.c, doc/dox_comments/header_files/rng_bank.h:
Serialize whole-object RNG-bank transitions against invalidation walks: add
WC_RNG_BANK_HAVE_INST_OP_GATE (present whenever a root_rng or the next-seed
banker is), regating inst_op_gate from WC_RNG_HAVE_NEXT_SEED; bracket
wc_rng_bank_invalidate_entropy()'s full walk with a spin-acquired gate claim,
excluding it from instance and root free/reinstantiate cycles; add
wc_rng_bank_root_rng_reinit(), a gate-bracketed retire-and-reinstantiate used by
the linuxkm entropy daemon's post-invalidation last-ditch arm; fix a gate leak
in wc_rng_bank_inst_reinit()'s lock-read failure path.
Fixes for RNG invalidation handling, WC_RNG_BANK_HAVE_ROOT_RNG gating, and
CONFIG_PREEMPT_RT preemption balance:
* Pivot on WC_RNG_BANK_HAVE_ROOT_RNG for the entropy daemon's root_rng
setup/teardown, the root stats dump, and the invalidation pre/post checks,
replacing hand-spelled feature disjunctions -- glue now follows root_rng
member existence exactly, including the WC_RNG_HAVE_LOCK-only configs the
old spellings missed, and root-less configs now compile the affected
functions cleanly.
* Wipe staged output on invalidation in the user-facing paths:
wc_get_random_bytes_user() and wc_extract_crng_user() now ForceZero the
staged block on EAGAIN before the post-check. Bytes generated before an
invalidation was noticed may be live in a forked VM; wc__get_random_bytes()
already wiped, the user paths did not.
* Rework invalidation retry in wc__get_random_bytes(): retire the ad-hoc
1-second jiffies window in favor of rng_invalidation_post_check() as the
single bounding authority -- EAGAIN retries, anything else is terminal
(-ETIMEDOUT/-EBUSY/-EINTR from the post-check) -- matching the user-facing
paths.
* WC_DRBG_NEXT_STIR_LEN -> WC_RNG_NEXT_STIR_LEN ripple in
wc_mix_pool_bytes(); root stats label "wc_entropyd root" -> "default bank
root" (the stats are the bank's root's, daemon or no daemon).
* wc_lkm_LockMutex(): latch wc_linuxkm_can_block() once at entry (the
caller's context is the disposition that matters, and the function itself
toggles preemption), and on CONFIG_PREEMPT_RT kernels skip the
post-trylock preempt_enable() -- RT spin_trylock() does not disable
preemption, so re-enabling underflowed the preempt count.
Fix error-trace machinery and add missing WC_NO_ERR_TRACE()s: errno-domain
comparisons in the PK and SHA glue and module_hooks (ENOMEM, EAGAIN, EINTR,
EBADMSG, and wolfCrypt INTERRUPTED_E/NOT_READY_E sites) now use the
-WC_NO_ERR_TRACE(E*) idiom, with .wolfssl_known_macro_extras updated to match.
Change default kernel "mutex" (spinlock) behavior: atomic-context callers now
never spin -- they trylock and fail fast -- and task-context lockers re-enable
preemption (and with it, migration) immediately after acquisition, rebalancing
the preempt count just before release. The legacy behavior -- task-context
holders promoted to non-preemptible for the duration of the hold, permitting
atomic-context callers (except NMI) to spin-wait -- remains available via a new
WC_LINUXKM_SPIN_IN_ATOMIC macro, which is #error-incompatible with
CONFIG_PREEMPT_RT; the mutex state field (.irq_flags vs .preempt_reenabled)
follows the selected regime, and wc_lkm_UnlockMutex() moves out of line (with a
pie redirect table entry).
Add pre- and post-checks bracketing DRBG operations against the invalidation
recovery window (keyed off last_invalidation_at, stamped at invalidation). The
pre-check works as a waiting room, keeping callers from generating a CAS scan
storm during the invalidation recovery interval (during which there are no
usable RNGs system-wide). In the post-check, -EAGAIN passes through for another
lap, a window overrun returns -ETIMEDOUT, atomic-context callers get one-shot
-EBUSY (blockability is checked before signal state, because in hardirq context
`current` is an unrelated task), pending signals return -EINTR, and otherwise
the caller relaxes and retries. Both checks have stubs so reduced
configurations build, and in-window messaging is ratelimited.
Add emergency reinitialization of the entropy daemon's root_rng: when the
recovery sweep finds the root invalidated, the daemon retries
wc_RNG_DRBG_Reseed_Now() with an uncredited timestamp nonce while the failure
remains retryable (BUSY_E, NOT_READY_E, ENTROPY_RT_E, ENTROPY_APT_E), relaxing
between attempts; for the default bank the reseed runs with preemption disabled
to maximize its chances. If the reseed fails terminally, the daemon makes one
last-ditch recovery via wc_FreeRng() and wc_rng_bank_root_rng_init() (or
wc_InitRng() for a standalone root); a successful reinit always clears the
invalidated state. If that too fails, the daemon exits, leaving bank instances
to self-reseed. Outcomes are reported at severities differentiated by default
vs non-default bank (pr_notice/pr_info success, pr_emerg/pr_err failure). The
daemon also now supports a standalone malloc'd root_rng where no bank features
are built, instantiated at startup and freed on exit.
Also:
* wc_linuxkm_drbg_generate_tfm(): retry loop around the invalidation window
replaces the single-shot call; output buffer is zeroized on terminal error.
* wc__get_random_bytes(): honors the recovery window, and zeroizes its
staging buffer both before retry re-entry and on the error exit. An
invalidation may be peculiar to this VM and leave the bytes live in another
VM, so they are wiped when abandoned, as possible CSP elsewhere.
* wc_linuxkm_entropy_daemon(): the registered-leaf recovery pass is now
additionally gated on WC_LINUXKM_HAVE_RNG_REGISTRY, matching its actual
dependency; seed health test failures (ENTROPY_RT_E/ENTROPY_APT_E) on bank
instances are now reported unconditionally at pr_warn_ratelimited severity
("entropy source suspect"), rather than pr_err only under WC_VERBOSE_RNG;
the WC_RNG_DEBUG_STATS dump at daemon exit is removed (was redundant).
* wolfcrypt/test/test.c: SVR access-counter checks now additionally gated on
new WC_SVR_HAVE_FLAGS, matching the configurations that actually maintain
the counters.
wolfcrypt/test/test.c, wolfssl/wolfcrypt/random.h: fixes for a second batch
of static-analysis findings.
* vmgenid fallback poller: search the ACPI IDs the kernel vmgenid driver
matches -- "VMGENCTR" and "VM_GEN_COUNTER" -- rather than the spec's
mixed-case spellings. ACPICA upcases _HID/_CID strings when building
the namespace and acpi_get_devices() matches by strcmp, so the old walk
found QEMU only by its _HID and missed CID-only devices (Hyper-V, VMware).
* wc_linuxkm_drbg_generate(): in non-vector builds, drop local_bh_disable()
around the blockable CAN_WAIT reseed and reinit operations and retake it
after, mirroring the vector arm's release/reacquire bracket; the
checkout's migrate_disable() persists across the sleep, preserving CPU
pinning preemptibly.
* entropy daemon and sysfs stats dumps: gate the next-stir format fragments
and arguments on WC_RNG_HAVE_NEXT_SEED.
* new WC_LKM_BANK_RBGC_FLAG (WC_RNG_BANK_FLAG_RBGC when WC_RNG_HAVE_RBGC,
else WC_RNG_BANK_FLAG_NONE): keep LKCAPI functional without RBGC support
compiled in.
* wc_rng_bank_init_nonce(): use (size_t)(-1) rather than SIZE_MAX in the
allocation overflow check (C90 and NO_STDINT_H builds).
* wc_rng_bank_fini(): pre-scan all instances for WC_RNG_LOCK_HELD before any
mutation, returning BUSY_E (retryable) with refcount untouched, free hook
unfired, and root intact.
* random.h: #error on WC_RNG_DEBUG_STATS without the RNG lock facility.
* wc_RNG_DRBG_Stir_Nonce(): reject nonce == NULL with nonzero nonceSz
(BAD_FUNC_ARG), matching the other nonce-bearing APIs.
* random_bank_test(): hoist held_inst to function scope and check it in
from the shared teardown path, closing a leak on failing assertions.
* wc_RNG_DRBG_NextSeedGenerate_local(): pointer declaration style cleanup.
* in wc_linuxkm_entropy_daemon(), add a top-priority patrol sweep to RBGC-reseed
invalidated RNGs, reducing the global invalidation-induced blackout to <25 ms
with wolfEntropy, and <5 ms with RDSEED (measured on 7960X).
* in wc_linuxkm_rng_bank_init(), pass WC_RNG_BANK_FLAG_AUTO_RECOVER_AND_PROMOTE
to wc_rng_bank_init_nonce(), and pass WC_RNG_BANK_FLAG_RBGC |
WC_RNG_BANK_FLAG_AUTO_RECOVER_AND_PROMOTE to wc_rng_bank_recover_inst();
* in linuxkm_InitRng_DefaultRBGC(), remove !can_sleep condition on
WC_RNG_BANK_FLAG_SPAWN_RECOVER_AND_PROMOTE.
wolfcrypt/src/rng_bank.c, wolfssl/wolfcrypt/rng_bank.h, wolfcrypt/src/random.c:
* rename WC_RNG_BANK_FLAG_SPAWN_RECOVER_AND_PROMOTE to
WC_RNG_BANK_FLAG_AUTO_RECOVER_AND_PROMOTE;
* in wc_RNG_lock_get(), grant lock on invalidated RNG if it can be
inline-recovered from a banked seed;
* in wc_RNG_Pool_Collect2(), fix to return NOT_READY_E if the epoch changed but
isn't yet synchronized (anything written before resync is discarded) -- fixes
futile daemon spinning after invalidation;
* in wc_rng_bank_init_nonce(), when WC_RNG_BANK_FLAG_AUTO_RECOVER_AND_PROMOTE,
pass WC_RNG_INIT_FLAGS_RECOVER_AND_PROMOTE_FROM_NEXT_SEED to
wc_InitRngNonceRBGC() and wc_InitRngNonce_ex2();
* in wc_rng_bank_inst_reinit(), when flags &
WC_RNG_BANK_FLAG_AUTO_RECOVER_AND_PROMOTE, pass
WC_RNG_INIT_FLAGS_RECOVER_AND_PROMOTE_FROM_NEXT_SEED to wc_InitRngNonce_ex2();
* in wc_rng_bank_recover_inst(), allow WC_RNG_BANK_FLAG_RBGC and
WC_RNG_BANK_FLAG_AUTO_RECOVER_AND_PROMOTE flags, and when
WC_RNG_BANK_FLAG_RBGC, try to use wc_RNG_DRBG_ReseedRBGC() for simple reseed
recovery.
refactor WC_RNG_HAVE_POOL facility as a CAS-synchronized-writer FIFO,
preserving lock-free single-reader, while assiduously enforcing entropy
invalidation locally for both readers and writers.
* add error percolation to wc_linuxkm_rng_registry_add_rng() and wc_linuxkm_rng_registry_add_bank(), and treat failures as fatal in wc_linuxkm_rng_bank_init() and linuxkm_InitRng_DefaultRBGC().
* bikeshed wc_mix_pool_bytes() with staggered-startup-offset.
wolfcrypt/src/rng_bank.c:
* add missing backward-compat WC_DRBG_NOT_INIT and WC_DRBG_OK definitions.
* add missing old-old-FIPS wc_RNG_DRBG_Reseed_Now() prototype and wc_RNG_DRBG_Stir() implementation.
wolfssl/wolfcrypt/rng_bank.h: fix sign-clash from WC_RNG_BANK_OFFSET_TO_RNG().
* in struct wc_rng_bank, rename daemon_root to root_rng, and change its gate from WC_RNG_BANK_HAVE_DAEMON_SUPPORT to WC_RNG_HAVE_RBGC || WC_RNG_HAVE_NEXT_SEED || WC_RNG_HAVE_POOL.
* add devId slot to struct wc_rng_bank.
* rename WC_RNG_BANK_FLAG_INIT_RBGC to WC_RNG_BANK_FLAG_RBGC, and support it in wc_rng_bank_reseed_range().
* remove root argument from wc_rng_bank_next_seed_generate_rbgc() (bank->root_rng is now implicit).
* remove wc_rng_bank_daemon_root_set() and wc_rng_bank_daemon_root_get(), and add wc_rng_bank_root_rng_init() and wc_rng_bank_root_rng_get().
* revert wc_rng_bank_inst_lock_get() et al from macros back to inlines, to assure type enforcement, and remove dangerous cast from WC_RNG_BANK_INST_TO_RNG().
* in wc_rng_bank_init_nonce(), use the persistent ctx->root_rng, removing the ephemeral-on-stack "WC_RNG root".
* in wc_rng_bank_fini(), clean up ctx->root_rng.
* in wc_rng_bank_reseed_range(), implement support for WC_RNG_BANK_FLAG_RBGC.
* in wc_rng_bank_invalidate_entropy(), add invalidation of bank->root_rng.
linuxkm/lkcapi_sha_glue.c:
* in wc_linuxkm_rng_state_invalidate(), remove now-obsolete special-case "daemon_root" code, and pass WC_RNG_BANK_FLAG_RBGC to the inline (non-daemon) wc_rng_bank_reseed_range().
* in wc_linuxkm_entropy_daemon(), rename local_root to root_rng, assign it at entry from wc_rng_bank_root_rng_get(bank), and remove the in-daemon cleanup of local_root; move the periodic explicit reseed of the root_rng to precede the pooling pass.
* refactor wc_mix_pool_bytes(), when called with small inputs, to use lockless wc_RNG_DRBG_NextStirStore() to a round-robin-rotated target RNG counted using DEFINE_PER_CPU() and friends.
* fix config-dependent undeclared-variable access (local_root) in wc_linuxkm_entropy_daemon.
* add WC_RNG_BANK_OFFSET_TO_RNG().
The invalidation registry was gated on the FIPS boundary version alone,
but it calls wc_RNG_register_free_hook() and wc_RNG_invalidate_entropy()
unconditionally. WC_RNG_NO_FREE_HOOK and WC_RNG_NO_LOCK remove those
respectively, so either setting broke the build rather than dropping the
feature.
Require WC_RNG_HAVE_FREE_HOOK and WC_RNG_HAVE_LOCK as well, and say so in
the comment that already explains the old-FIPS exclusion.
Reported by Fenrir.
Two related gaps in what callers could supply.
The SP 800-90A personalization string was reachable only as the hardcoded
NULL that _InitRng() passed to Hash_DRBG_Init(). Hash_df() already had
the input; nothing could fill it. Thread it through the instantiate
family -- wc_InitRngNonce_ex2(), wc_InitRngNonceRBGC{,_New}(),
SpawnRngRBGC(), wc_rng_bank_init_nonce() and wc_rng_bank_spawn{,_new}().
Personalization is an instantiate-time input in SP 800-90A, so the reseed
and stir APIs deliberately do not gain it; material of that kind belongs
in their existing additional-input argument.
Separately, the bank-level seed and reseed APIs had no way to pass a nonce
to the per-instance reseed underneath them, so wc_rng_bank_seed{,_range}()
and wc_rng_bank_reseed{,_range}() gain one. The index arguments keep
their positions and the material sits immediately before timeout_secs.
linuxkm uses it to carry a post-event timestamp into the recovery reseeds
issued after a state invalidation, and zeroizes it on every path, matching
the existing uncredited-nonce sites in that file.
appropriately spelled, for clarity and consistency. Stirring is implemented
by Hash_DRBG_StirGenerate() an an SP 800-90A Rev. 1 10.1.1.4 generate, with
the stir material as additional_input and no output requested.