20260907-RNG-extras - #11435
20260907-RNG-extras#11435douzzer wants to merge 100 commits into
Conversation
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11435
Scan targets checked: none
Failed targets: linuxkm-src, linuxkm-bugs, wolfcrypt-src, wolfcrypt-bugs, wolfssl-src, wolfssl-bugs
|
Note the kernel module build failures are expected, and will resolve once #11382 merges. |
|
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11435
Scan targets checked: linuxkm-src, linuxkm-bugs, wolfcrypt-src, wolfcrypt-bugs, wolfssl-src, wolfssl-bugs
Findings: 17
17 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
71f1f6b to
97bdcee
Compare
97bdcee to
0c4cec3
Compare
0c4cec3 to
4893d1c
Compare
* add NO_DEFAULT_FOUND_E "No default object registered for request type". * add missing #include <wolfssl/wolfcrypt/logging.h> in WOLFSSL_DEBUG_TRACE_ERROR_CODES path. * add __func__ to __GNUC__ WC_ERR_TRACE(). wolfcrypt/src/rng_bank.c, wolfssl/wolfcrypt/rng_bank.h, wolfcrypt/test/test.c: * add wc_rng_bank_inst.bank for parent access from the children. * add wc_rng_bank_inst_checkin(). * improve thread safety, error checking, and default bank support in wc_rng_bank_checkout(), wc_local_rng_bank_checkout_for_bankref(), wc_rng_bank_inst_reinit(), wc_rng_bank_seed(), wc_rng_bank_reseed(), and wc_InitRng_BankRef_local(). * orthogonalize common code in wc_InitRng_BankRef() and wc_rng_new_bankref() into wc_InitRng_BankRef_local(). wolfcrypt/test/test.c: * fix typo in PRINT_HEAP_CHECKPOINT(). * add wc_rng_bank_inst_checkin() tests to random_bank_test(), update expected failure codes, and remove obsolete test clauses. * add missing !HAVE_FIPS gates in cryptocb_test(). wolfcrypt/src/random.c: * in WC_RNG_BANK_SUPPORT variant of wc_RNG_GenerateBlock(), use the new wc_rng_bank_inst_checkin(), not wc_rng_bank_checkin(). * tweaks to WOLFSSL_DEBUG_TRACE_ERROR_CODES code wrappers to mollify clang-tidy and -Wconversion. * fix a spelling error in _InitRng(). linuxkm/lkcapi_sha_glue.c: * in wc_linuxkm_drbg_generate(), opportunistically reseed once half way to WC_RESEED_INTERVAL and wc_linuxkm_can_block(). Also properly inhibit the recovery call to wc_rng_bank_inst_reinit() if ! wc_linuxkm_can_block(). * refactor wc_mix_pool_bytes() to use wc_RNG_DRBG_Reseed(), and only on the CPU-local RNG. wolfcrypt/src/asn.c, wolfcrypt/src/curve25519.c, wolfcrypt/src/evp.c, wolfcrypt/src/pkcs7.c, wolfcrypt/src/pkcs12.c, wolfcrypt/src/srp.c: at each existing wc_InitRng(), attempt wc_InitRng_BankRef() if WC_RNG_BANK_DEFAULT_SUPPORT && WC_HAVE_RNG_BANKREF.
…mproved dynamics.
… wolfcrypt/src/pkcs7.c, wolfcrypt/src/pkcs12.c, wolfcrypt/src/srp.c: revert wc_InitRng_BankRef() airdrops.
* supply WC_DRBG_OK for HAVE_FIPS with FIPS_VERSION3 < 5.2.4 or == 6.0.0, for the DRBG health tests in wc_rng_bank_checkout(), wc_rng_bank_seed(), and wc_rng_bank_reseed(); * in rng_inst_matches_bank(), compare integer addresses (wc_ptr_t), and compute the mid-instance alignment check on the integer difference -- the negative tests deliberately supply fabricated pointers, for which pointer relationals and subtraction are undefined (C11 6.5.8p5 / 6.5.6p9), while integer comparisons are defined for any value.
wc_rng_bank checkin and seed edge cases from the 20260820 review batch: duplicate (stale-copy) checkin through both wc_rng_bank_checkin() and wc_rng_bank_inst_checkin(), asserting BAD_STATE_E without bank mutation; seedSz == 0 no-op success for an explicit inited bank and for the default form while a default is set; and seedSz == 0 with no default bank set, asserting NO_DEFAULT_FOUND_E.
blockability into can_wait before the DRBG checkout, and gate the opportunistic reseed and the RNG_FAILURE_E reinit recovery on it -- wc_linuxkm_can_block() is false whenever the affinity lock is held (the lock callback is SAVE_VECTOR_REGISTERS_MAYBE_INHIBIT()), so the previous live-sampled guards were unsatisfiable in every reachable state and both features were dead. For each of the two blocking operations, bracket it to restore preemptibility while keeping the instance checked out: migrate_disable() (CONFIG_SMP && >= 5.11.0 -- on earlier kernels migrate_disable() is absent or maps to preempt_disable(), so migration during the operation is simply tolerated there), then RESTORE_VECTOR_REGISTERS_MAYBE_INHIBITED() keyed on the lock's _AFFINITY_LOCKED/_VEC_OPS_INH bits, then the blocking operation preemptibly (wc_rng_bank_inst_reinit()'s WC_RELAX_LONG_LOOP now sees can_block() true and actually yields), then re-establish the vector state flavor-matched (SAVE_VECTOR_REGISTERS2() for the affinity hold, DISABLE_VECTOR_REGISTERS() for the inhibit hold), then migrate_enable(). If re-establishment fails, clear the corresponding lock bits so checkin doesn't double-restore; the cleared bits also make a failed bracket a valid entry state for the subsequent one. Plain (non-atomic) accesses to drbg->lock are sound across the span: WC_RNG_BANK_INST_LOCK_HELD is invariantly held, and it is the only bit considered by contending threads. (root defect identified in 20260820 review batch; see PR discussion for why the review's proposed fix -- pre-captured blockability alone, without releasing the holds -- would have converted the dead code into sleep-in-atomic / bh-off stalls)
…r message on failed wc_rng_bank_default_checkout(), and rework the error message when wc_linuxkm_drbg_generate() fails.
* 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.
* 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().
…a_glue.c: 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.
WC_CAS_WITH_RETRY_BEGIN_INIT_CUR(), WC_CAS_WITH_RETRY_LOOP_UNTIL(), WC_CAS_WITH_RETRY_LOOP_FOREVER(), and WC_CAS_WITH_RETRY_END(), and port helpers WC_CAS_WITH_RETRY_EXTRA_DECLS, WC_CAS_WITH_RETRY_ITER_CLAUSE, and WC_CAS_WITH_RETRY_FOREVER_CLAUSE. wolfcrypt/src/random.c and wolfcrypt/src/rng_bank.c: refactor CAS loops using WC_CAS_WITH_RETRY_*() macros, except for wc_RNG_lock_put_conditional() and wc_rng_bank_inst_lock_put_conditional(), which have nonconformant code patterns and call the new hooks directly.
…ne it to WC_RELAX_LONG_LOOP().
* 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.
…t/test.c: fixes for old-FIPS compatibility.
…nt overwrite on error return, and add missing _stats_pool_bytes_missed advance.
…_bank.c, linuxkm/lkcapi_sha_glue.c, wolfcrypt/test/test.c: 's/WC_RNG_INIT_FLAGS_/WC_RNG_INIT_FLAG_/g'.
…in linuxkm_InitRng_DefaultRBGC().
…ited nextSeed aperture, and percolate or dispose of all remaining failable results. * wc_RNG_invalidate_entropy() now purges first and latches last, making the latch a provenance marker, and latches or condemns: any error return sets DRBG_FAILED, as the latch is then down and the reseedCtr is subject to lost-update races. wc_RNG_DRBG_NextSeedNow_Nonce() releases its _CONSUMING claim by one-shot CAS; failure proves a purge crossed the consume, so it re-latches, reschedules reseed, and returns NEEDS_RECOVERY_E, with stats and stratum adoption gated behind a successful release. Hash_DRBG_Reseed() takes a new in_bracketed_consume arg exempting the caller's own claim from its invalidated-entry purges. * PoolPurge() and NextSeedPurge() return int (ALREADY_E hand-off), with results percolated at all call sites; * WARN_UNUSED_RESULT on eligible statics; * Explicit dispositions after every WC_CAS_WITH_RETRY loop (bail before side effects, percolate, or DRBG_FAILED where an abort would strand _ENTROPY_RECOVERING); * Hash_DRBG_StirGenerate() now percolates failure from wc_RNG_DRBG_GetReseedCtr() rather than ignoring it; * free_hook and wc_LockMutex results captured and percolated.
sibling-lineage doctrine: bytes a purge abandons here may be consumed by an identical clone/fork sibling there, and consumed-elsewhere is CSP. The events that abandon banked or pooled material (VM clone/resume, fork, credited reseed) are the same events that create sibling lineages holding identical copies, so "abandoned unconsumed" cannot be decided lineage-locally at exactly the purge sites: a sibling whose interleaving differs may consume its twin of the bytes, leaving their literal reseed input or served output at rest in this lineage's memory. Such material is wiped, under ownership only. The one principled exemption: material whose rejection is deterministic on the bytes (RCT/APT health-test failures) is rejected identically in every lineage, can never have a consumed copy, and stays sentinel-only. * NextSeedPurge() takes the seed buffer and wipes it: a READY or parked-fill word is first claimed _CONSUMING (the same CAS a consumer uses; producers claim only non-negative words, so no collision), wiped as owner, and reopened EMPTY. A _CONSUMING holder's material is left to that consumer's burn-before-release, and a _PRODUCING holder's to its unwind; the _CONSUMING repaint semantics (the epoch-crossing detection) are unchanged. * NextSeedProducerRelease() wipes in its unwind arm, before the EMPTY reopen, while the producer still owns the buffer. A failed release remains non-percolating by design -- the unwind is its own compensation -- with the disposition rationale now in a comment at the first (void) call site. * New PoolWipeRetired() wipes the retired span [tail, head) at the three reader-owned sites: the visit-time epoch resync, the mid-extract linearization-point discard, and the fail-closed status arm (which now also resynchronizes tail rather than leaving it stale). Race-free by ownership: the single reader is the only mover of tail; writers write only past head. * The health-test burn arm stays sentinel-only, now with the deterministic-rejection rationale in place of the old house-rule assertion. No architectural change: the aperture claim machinery was already an ownership protocol, so "who may wipe" inherits its answer from "who may write".
contradictory states at their entry points. * wc_RNG_DRBG_Reseed_Nonce(): return RNG_FAILURE_E on a DRBG_FAILED instance -- condemnation's exit is wc_FreeRng()/wc_InitRng(), not an in-place credited resurrection that would reset the counter, purge the pool, and clear quarantine. * random.h: #error on WC_RNG_WANT_NEXT_SEED or WC_RNG_WANT_POOL without WC_RNG_WANT_LOCK in FIPS builds -- pregenerated material requires the invalidation/purge protocol, which rides the lock facility. * Comment fixes: the zero-length stir generate banks a block for the continuous-test hook (no comparison state lives in this file); PoolPurge() purges on credited reseed only when recovering from invalidation.
* in Hash_DRBG_Generate() and Hash512_DRBG_Generate(), if an error occurs after state mutation (step-2 V add), preventing state finalization, set rng->status = DRBG_FAILED (adds a WC_RNG* rng arg to Hash*_DRBG_Generate()); * in Hash_DRBG_StirGenerate(), check rng->status after Hash*_DRBG_Generate() and if DRBG_FAILED, return RNG_FAILURE_E; * in wc_RNG_DRBG_NextStirNow(), if the _CONSUMING cmpxchg fails, code the retval to the cause; * in wc_RNG_GenerateBlock(), abort generation if wc_RNG_DRBG_NextStirNow() returns RNG_FAILURE_E.
…ader_files/rng_bank.h.
a8effff to
9c65ab8
Compare
…_random_whitebox.c: update for new Hash_DRBG_Generate() arity and WUR on Hash512_DRBG_Instantiate() (fixed by collecting and asserting errors).
…ialize seed and lenp to NULL to work around false positive from CI.
….c: fix RNG-extras support for HAVE_INTEL_RDRAND.
kaleb-himes
left a comment
There was a problem hiding this comment.
Approved as is for functionality, there are still some open compliance items we need to discuss with the CSTL but we can address them after we split the v7 branch from the master branch.
Expansion of core RNG facility to add kernel-facing semantics.
The SP 800-90 compliance report is the best introduction to the expansion:
rng-extras-compliance-report (2).pdf
Also expands rng_bank facility with corresponding functionalities, and refactors corresponding portions of
linuxkm/lkcapi_sha_glue.cto follow suit.Tested with full run
wolfssl-multi-test.sh(530 scenarios).Relevant new scenarios:
Note, tested atop #11382, and must merge after #11382 merges.