Skip to content

Random Number Generation

More...

Functions

Name
int wc_InitRng(WC_RNG * rng)
Gets the seed (from OS) and key cipher for rng. rng_>drbg (deterministic random bit generator) allocated (should be deallocated with wc_FreeRng). This is a blocking operation.
int wc_RNG_GenerateBlock(WC_RNG * rng, byte * output, word32 sz)
Copies a sz bytes of pseudorandom data to output. Will reseed rng if needed (blocking).
int wc_RNG_GenerateByte(WC_RNG * rng, byte * b)
Calls wc_RNG_GenerateBlock to copy a byte of pseudorandom data to b. Will reseed rng if needed.
int wc_FreeRng(WC_RNG * rng)
Tears down an RNG instance: zeroizes and releases its DRBG state. The WC_RNG must have come from wc_InitRng*() or be zeroed.
int wc_FreeRng_PreLocked(WC_RNG * rng)
Tears down an RNG instance whose lock the caller already holds.
int wc_RNG_HealthTest(int reseed, const byte * seedA, word32 seedASz, const byte * seedB, word32 seedBSz, byte * output, word32 outputSz)
Creates and tests functionality of drbg.
int wc_GenerateSeed(OS_Seed * os, byte * output, word32 sz)
Generates seed from OS entropy source. Lower-level function used internally by wc_InitRng.
WC_RNG * wc_rng_new(byte * nonce, word32 nonceSz, void * heap)
Allocates and initializes new WC_RNG with optional nonce.
int wc_rng_new_ex(WC_RNG ** rng, byte * nonce, word32 nonceSz, void * heap, int devId)
Allocates and initializes WC_RNG with extended parameters.
void wc_rng_free(WC_RNG * rng)
Frees WC_RNG allocated with wc_rng_new.
int wc_InitRng_ex(WC_RNG * rng, void * heap, int devId)
Initializes WC_RNG with extended parameters.
int wc_InitRngNonce(WC_RNG * rng, const byte * nonce, word32 nonceSz)
Initializes WC_RNG with nonce.
int wc_InitRngNonce_ex(WC_RNG * rng, const byte * nonce, word32 nonceSz, void * heap, int devId)
Initializes WC_RNG with nonce and extended parameters.
int wc_SetSeed_Cb(wc_RngSeed_Cb cb)
Sets callback for custom seed generation.
int wc_RNG_DRBG_Reseed(WC_RNG * rng, const byte * seed, word32 seedSz)
Reseeds DRBG with new entropy. The material is credited: the reseed counter resets.
int wc_RNG_TestSeed(const byte * seed, word32 seedSz)
Tests seed validity for DRBG.
int wc_RNG_HealthTest_ex(int reseed, const byte * nonce, word32 nonceSz, const byte * seedA, word32 seedASz, const byte * seedB, word32 seedBSz, byte * output, word32 outputSz, void * heap, int devId)
RNG health test with extended parameters.
int wc_RNG_HealthTest_SHA512(int reseed, const byte * seedA, word32 seedASz, const byte * seedB, word32 seedBSz, byte * output, word32 outputSz)
Runs the SHA_512 Hash_DRBG Known Answer Test (KAT) per SP 800-90A. Instantiates a SHA-512 DRBG with seedA, optionally reseeds with seedB, generates output, and compares against known test vectors. Available when WOLFSSL_DRBG_SHA512 is defined.
int wc_RNG_HealthTest_SHA512_ex(int reseed, const byte * nonce, word32 nonceSz, const byte * persoString, word32 persoStringSz, const byte * seedA, word32 seedASz, const byte * seedB, word32 seedBSz, const byte * additionalA, word32 additionalASz, const byte * additionalB, word32 additionalBSz, byte * output, word32 outputSz, void * heap, int devId)
Extended SHA-512 Hash_DRBG health test with nonce, personalization string, and additional input support. Suitable for full ACVP / CAVP test vector validation. Available when WOLFSSL_DRBG_SHA512 is defined.
int wc_Sha256Drbg_Disable(void )
Disables the SHA_256 Hash_DRBG in the process_wide runtime setting. The setting decides the DRBG flavor of every WC_RNG whose constructor was not told one explicitly: all of the constructors with no flags argument, and the flags_bearing ones (wc_InitRng_ex2() and the others taking WC_RNG_INIT_FLAG_* flags) when neither WC_RNG_INIT_FLAG_DRBG_SHA256 nor WC_RNG_INIT_FLAG_DRBG_SHA512 is given; either of those flags overrides the setting for that instance. The setting is read once, at instantiation, so instances already alive are unaffected. Both compiled_in flavors start enabled, with SHA_512 preferred where WOLFSSL_DRBG_SHA512 is defined, except that WOLFSSL_NO_SHA256_DRBG starts SHA_256 disabled (still compiled in, and enable_able); after this call the setting is SHA-512 only. The last enabled flavor cannot be disabled.
int wc_Sha256Drbg_Enable(void )
Re_enables the SHA_256 Hash_DRBG in the process_wide runtime setting after a prior call to wc_Sha256Drbg_Disable(). Affects only instances created after the call, and not those whose constructor was given an explicit flavor flag; see wc_Sha256Drbg_Disable() for the setting's scope and concurrency. Requires HAVE_HASHDRBG.
int wc_Sha256Drbg_IsDisabled(void )
Returns whether the SHA_256 Hash_DRBG is currently disabled in the process_wide runtime setting (see wc_Sha256Drbg_Disable()). Says nothing about instances already alive, or about ones whose constructor was given an explicit flavor flag. In a build without SHA-256 it is always 1. Requires HAVE_HASHDRBG.
int wc_Sha512Drbg_Disable(void )
Disables the SHA_512 Hash_DRBG in the process_wide runtime setting, so that instances created after the call without an explicit flavor flag use SHA_256. The setting's scope – that it is read once at instantiation, and that WC_RNG_INIT_FLAG_DRBG_SHA256 / WC_RNG_INIT_FLAG_DRBG_SHA512 override it per instance – and its concurrency are described at wc_Sha256Drbg_Disable(). The last enabled flavor cannot be disabled. Available when WOLFSSL_DRBG_SHA512 is defined. Requires HAVE_HASHDRBG.
int wc_Sha512Drbg_Enable(void )
Re_enables the SHA_512 Hash_DRBG in the process_wide runtime setting after a prior call to wc_Sha512Drbg_Disable(). Affects only instances created after the call, and not those whose constructor was given an explicit flavor flag; see wc_Sha256Drbg_Disable() for the setting's scope and concurrency. Available when WOLFSSL_DRBG_SHA512 is defined. Requires HAVE_HASHDRBG.
int wc_Sha512Drbg_IsDisabled(void )
Returns whether the SHA_512 Hash_DRBG is currently disabled in the process_wide runtime setting (see wc_Sha256Drbg_Disable()). Says nothing about instances already alive, or about ones whose constructor was given an explicit flavor flag. Available when WOLFSSL_DRBG_SHA512 is defined. Requires HAVE_HASHDRBG.
int wc_InitRng_ex2(WC_RNG * rng, void * heap, int devId, word32 flags)
Initialize a WC_RNG with instantiation_time security attributes. Identical to wc_InitRng_ex(), with a flags argument fixing attributes at birth: WC_RNG_INIT_FLAG_LOCK_REQUIRED latches the sticky lock_required policy bit, so there is no reachable state in which the instance serves without its lock policy; WC_RNG_INIT_FLAG_LOCK_INITIALLY constructs into a held lease, to be released with wc_RNG_lock_put(); WC_RNG_INIT_FLAG_USE_FULL_MUTEX layers a blocking wolfSSL_Mutex outermost around the lock latch, for user_mode sharing of one instance among threads (requires WC_RNG_HAVE_LOCK_FULL_MUTEX).
int wc_InitRngNonce_ex2(WC_RNG * rng, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, void * heap, int devId, word32 flags)
Initialize a WC_RNG with a caller_supplied nonce and instantiation_time security attributes. The nonce semantics are those of wc_InitRngNonce_ex(); the flags semantics are those of wc_InitRng_ex2().
int wc_RNG_global_fallback_init(const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, void * heap, int devId, word32 flags)
Instantiate the module_wide fallback RNG from the module's primary seed source (WC_RNG_HAVE_GLOBAL_FALLBACK_RNG). The global fallback is a single, lock_disciplined (WC_RNG_INIT_FLAG_LOCK_REQUIRED), stratum_0 instance that serves as a reseed root of last resort: an RBG_chain member whose retained parent is unavailable reseeds from it on the PollAndReSeed() ladder (under FIPS only when it is a sibling of the parent, per the SP 800_90C closed list of alternative sources), and in the kernel module the entropy daemon keeps it fresh. It is never admitted as a spawn parent (see wc_InitRngNonceRBGC()). The call takes the instance's lock for the duration; _LOCK_REQUIRED and _LOCK_INITIALLY are implied and need not be passed.
int wc_RNG_global_fallback_init_user_seed(const byte * seed, word32 seedSz, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, void * heap, int devId, word32 flags)
The user_seeded form of wc_RNG_global_fallback_init(): the fallback is instantiated from caller_supplied material, with the provenance consequences of wc_InitRngNonce_UserSeed() (stratum WC_RNG_RBGC_USER_SEED_STRATUM, so under FIPS it cannot serve as an alternative source for any module_seeded chain member). For KAT harnesses and deterministic test rigs.
int wc_RNG_global_fallback_get(WC_RNG * rng)
Obtain a pointer to the global fallback RNG, for use as an explicit reseed root (wc_RNG_DRBG_ReseedRBGC(), the next_seed banker) or for maintenance by a daemon. No lock is taken: the instance is lock_required, so every operation on it goes through wc_RNG_lock_get()/wc_RNG_lock_put() as usual. The pointer is refused unless the instance is in service, which is only possible after a successful wc_RNG_global_fallback_init
().
int wc_RNG_global_fallback_free(void )
Tear down the global fallback RNG: wc_FreeRng() on the instance, with that function's contract – BUSY_E leaves it intact for a retry, STILL_REFERENCED_E means chain members still name it as a reseed root and its state has been zeroized. After a successful return it can be instantiated again.
int wc_InitRngNonce_UserSeed(WC_RNG * rng, const byte * seed, word32 seedSz, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, void * heap, int devId, word32 flags)
Initialize a WC_RNG instantiated from caller_supplied seed material, used in place of the module's seed source, with an optional nonce and personalization string. Every other aspect of instantiation is wc_InitRngNonce_ex2()'s. The instance is born at the user_provenance stratum sentinel (WC_RNG_RBGC_USER_SEED_STRATUM).
int wc_RNG_GetStatus(const WC_RNG * rng)
Read_only accessor for the RNG health status. Returns the instance's enum wc_RngHealthState value (WC_DRBG_NOT_INIT, WC_DRBG_OK, WC_DRBG_FAILED, WC_DRBG_CONT_FAILED).
int wc_RNG_Status(const WC_RNG * rng)
The error_code form of wc_RNG_GetStatus(): 0 for an in_service instance, else the code its state maps to – so a caller can gate on an instance, or percolate its state, with one call and no enum switch. A pure status read: no lock is taken and nothing is propagated (contrast wc_RNG_entropy_needs_recovery(), which also delivers a pending epoch event and checks the reseed schedule).
int wc_RNG_DRBG_Present(const WC_RNG * rng)
Returns 1 if rng has an instantiated DRBG, else 0. An in_service WC_RNG can lack one: instantiation bypasses the DRBG when the CPU has RDRAND (HAVE_INTEL_RDRAND). DRBG_specific services (commanded reseed, banked next seeds, RBG chains) are unavailable on such instances.
int wc_RNG_DRBG_ScheduleReseed(WC_RNG * rng)
Mark rng due for reseed: the next generate operation reseeds from the module's built-in or registered seed source before producing output. This can only shorten the current seed's remaining lifetime, never extend it.
int wc_RNG_DRBG_Reseed_Now(WC_RNG * rng, const byte * nonce, word32 nonceSz)
Immediately reseed rng from the module's built-in, registered, or associated seed source, with an optional nonce as additional input. The credited reseed resets the reseed counter.
int wc_RNG_DRBG_Reseed_Now_Primary(WC_RNG * rng, const byte * nonce, word32 nonceSz)
The forced_primary form of wc_RNG_DRBG_Reseed_Now(): reseed rng directly from the module's primary (initial) randomness source, bypassing the chain fallback ladder, with an optional nonce as additional input. This is the SP 800_90A prediction_resistance primitive – a reseed from a live entropy source immediately ahead of generation – and is available to SP 800_90C chain members (RBGC stratum > 0) as well: the initial randomness source is on the SP 800-90C closed list of alternative sources, so the forced reseed is chain-conformant.
int wc_RNG_DRBG_Reseed_Nonce(WC_RNG * rng, const byte * seed, word32 seedSz, const byte * nonce, word32 nonceSz)
Reseed rng's DRBG with caller-supplied seed material and an optional nonce as additional input, folded in a single derivation pass. The material is credited: the reseed counter resets.
int wc_RNG_DRBG_Stir(WC_RNG * rng, const byte * seed, word32 seedSz)
Similar to wc_RNG_DRBG_Reseed(), except the caller-supplied material is mixed through the reseed derivation function without being credited as entropy: the reseed counter is not reset, so only the module's own seed source ever extends the instance's seed lifetime.
int wc_RNG_DRBG_Stir_Nonce(WC_RNG * rng, const byte * seed, word32 seedSz, const byte * nonce, word32 nonceSz)
The nonce_bearing form of wc_RNG_DRBG_Stir(): the nonce is mixed in as a second, separate generate with additional input.
int wc_InitRngRBGC(WC_RNG * child, WC_RNG * parent, word32 flags)
Instantiate child as an SP 800_90C RBG_chain member subordinate to parent, drawing its seed material from parent's generate function in place of the module's seed source. Every other aspect of instantiation is wc_InitRng_ex2()'s. The child is tagged with stratum (parent's stratum + 1), and is relabeled at each credited reseed based on the seed source's stratum unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS); its claimable security strength is capped by parent's, and it has no prediction resistance. The caller must hold exclusive access to parent for the duration of the call; the spawn debits parent's reseed counter by one generate.
int wc_InitRngRBGC_New(WC_RNG ** child, WC_RNG * parent, word32 flags)
The allocating form of wc_InitRngRBGC(): the child is allocated from parent's heap and returned through child. Release with wc_rng_free(). For further details, see wc_InitRngRBGC().
int wc_InitRngNonceRBGC_New(WC_RNG ** child, WC_RNG * parent, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, word32 flags)
The allocating, nonce_bearing form of wc_InitRngRBGC(). For further details, see wc_InitRngRBGC() and wc_InitRngNonceRBGC().
int wc_RNG_DRBG_ReseedRBGC(WC_RNG * rng, WC_RNG * root, const byte * nonce, word32 nonceSz)
Reseed rng from root's generate output – the SP 800_90C chain reseed – with an optional nonce as additional input. The reseed is credited (the reseed counter resets); rng's stratum is updated to root's stratum + 1, unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS). The caller must hold exclusive access to both instances.
int wc_RNG_DRBG_StirRBGC(WC_RNG * rng, WC_RNG * root, const byte * nonce, word32 nonceSz)
The uncredited form of wc_RNG_DRBG_ReseedRBGC(): material from root is mixed in without resetting rng's reseed counter.
int wc_RNG_DRBG_GetRBGCStratum(const WC_RNG * rng)
Report rng's RBG_chain stratum: 0 for a root (never chain_seeded), n for a member seeded from a stratum_(n_1) parent. If built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS), the stratum is sticky for the instance's lifetime, even across subsequent source reseeds; otherwise it follows the stratum of the most recent credited seed source. A user_supplied reseed (wc_RNG_DRBG_Reseed()), where accepted, marks rng with WC_RNG_RBGC_USER_SEED_STRATUM regardless.
int wc_RNG_DRBG_GetNextSeedRBGCStratum(const WC_RNG * rng)
Report the RBG-chain stratum of rng's banked next seed – race-free via the aperture protocol – for provenance-aware consumers.
int wc_RNG_DRBG_NextSeedGenerate(WC_RNG * rng, word32 n)
Bank up to n more bytes of next-seed material, health-testing and publishing the bank when it completes. The fill is incremental and in-boundary; a scheduling daemon may call this without owning the instance – the single-writer fill and the atomic aperture hand-off make it safe alongside a concurrent consumer.
int wc_RNG_DRBG_NextSeedGenerate_Primary(WC_RNG * rng, word32 n)
The forced_primary form of wc_RNG_DRBG_NextSeedGenerate(): the banked material is drawn directly from the module's primary (initial) randomness source, bypassing the chain fallback ladder, and the bank records stratum 0 (primary provenance), observable via wc_RNG_DRBG_GetNextSeedRBGCStratum(). On an SP 800_90C chain member, redemption of the primary_provenance bank is a promotion: the live seed becomes primary_sourced, and the stratum label follows unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS), whereby the birth label is kept while the live seed's provenance is primary. Like the ladder form, the fill is incremental and in-boundary, safe for a scheduling daemon alongside a concurrent consumer.
int wc_RNG_DRBG_NextSeedGenerate_RBGC(WC_RNG * rng, WC_RNG * root, word32 n)
The chain_sourced form of wc_RNG_DRBG_NextSeedGenerate(): the banked material is drawn from root's generate function, and the bank is tagged with root's stratum plus one for provenance-aware consumption.
int wc_RNG_DRBG_NextSeedCurrent(const WC_RNG * rng, WC_ATOMIC_INT_ARG * n)
Report the raw next_seed aperture value: a non_negative banked byte count (filling, with no producer in flight), or one of the sentinels WC_DRBG_NEXT_SEED_PRODUCING (a producer holds the fill claim), WC_DRBG_NEXT_SEED_READY, WC_DRBG_NEXT_SEED_CONSUMING, WC_DRBG_NEXT_SEED_PURGED (an invalidation repainted a live claim; the holder reopens), or WC_DRBG_NEXT_SEED_TORNDOWN (the instance is between teardown and reinitialization, or has no DRBG). The snapshot is racy by design; use it for scheduling and diagnostics, not for hand-off decisions.
int wc_RNG_DRBG_NextSeedNow(WC_RNG * rng)
Claim a ready next_seed bank and perform a source_free credited reseed with it – safe in atomic context. The bank empties (use_once) and the reseed counter resets. The caller must own the instance.
int wc_RNG_DRBG_NextSeedNow_Nonce(WC_RNG * rng, const byte * nonce, word32 nonceSz)
The nonce_bearing form of wc_RNG_DRBG_NextSeedNow(): the nonce is mixed in as uncredited additional input alongside the banked seed.
int wc_RNG_DRBG_NextStirStore(WC_RNG * rng, const byte * nonce, word32 nonceSz)
Bank caller_supplied material (up to WC_RNG_NEXT_STIR_LEN bytes) in the uncredited accumulator beside the banked next seed. Writer_safe without a lease (read_copy_store); if the accumulator is already full, the material is absorbed by xor. Harvested entropy deposited here improves the instance without claiming credit.
int wc_RNG_DRBG_NextStirNow(WC_RNG * rng)
Stir the banked uncredited accumulator into the DRBG as an uncredited, source-free mix-in – safe in atomic context; the reseed counter is not reset. The caller must own the instance.
int wc_RNG_lock_get(WC_RNG * rng, WC_RNG_lock_arg_t extra_bits)
Acquire rng's exclusive-ownership lock latch, spinning on the CAS until acquired, and or the caller's extra bits into the lock word. On an instance without the lock-required policy the call is a successful no-op unless extra bits are supplied.
int wc_RNG_lock_get_conditional(WC_RNG * rng, WC_RNG_lock_arg_t expected_extra_bits, WC_RNG_lock_arg_t want_extra_bits)
The conditional form of wc_RNG_lock_get(): acquire only if the current extra bits equal expected_extra_bits, atomically replacing them with want_extra_bits on success. Non-blocking with respect to the condition: a mismatch fails immediately rather than spinning.
int wc_RNG_lock_put(WC_RNG * rng, WC_RNG_lock_arg_t extra_bits)
Release rng's lock latch, clearing the supplied extra bits atomically with the release.
int wc_RNG_lock_put_conditional(WC_RNG * rng, WC_RNG_lock_arg_t expected_extra_bits, WC_RNG_lock_arg_t want_extra_bits)
The conditional form of wc_RNG_lock_put(): release only if the current extra bits equal expected_extra_bits, atomically replacing them with want_extra_bits on success.
int wc_RNG_lock_read(const WC_RNG * rng, WC_RNG_lock_arg_t * state)
Read rng's lock word: the held/required latch bits, the entropy-invalidated bit, and any caller extra bits. The snapshot is racy by design.
int wc_RNG_lock_set_extra(WC_RNG * rng, WC_RNG_lock_arg_t extra_bits)
Atomically set (or) the supplied caller extra bits in rng's lock word. The caller should hold the latch.
int wc_RNG_lock_add_extra(WC_RNG * rng, WC_RNG_lock_arg_t extra_bits)
Atomically add the supplied value to the caller extra-bits field of rng's lock word – for counters carried above WC_RNG_LOCK_EXTRA_SHIFT.
int wc_RNG_lock_clear_extra(WC_RNG * rng, WC_RNG_lock_arg_t extra_bits)
Atomically clear the supplied caller extra bits in rng's lock word.
int wc_RNG_invalidate_entropy(WC_RNG * rng)
Mark rng's seed material untrusted – for VM fork/resume and similar duplication events: banked and pooled pre_event material is purged and wiped, and then (in builds with instance locking) the entropy_invalidated bit is latched in the lock word, stamping the instance with the delivered entropy epoch and PID so one global event delivers once; in builds without instance locking the reseed schedule is saturated instead, as the only mark available. An invalidated instance refuses service (NEEDS_RECOVERY_E) until recovery-reseeded. Callable without owning the instance.
int wc_RNG_register_free_hook(WC_RNG * rng, wc_RNG_free_hook_cb_t free_hook, void * arg)
Register a callback fired by wc_FreeRng() at teardown – for external registries (e.g. a kernel_module registry that must reach every live RNG on a VM duplication event) that need to drop their reference when the object dies.
int wc_RNG_SetFlags(WC_RNG * rng, word32 flags)
Set runtime policy flags on an instantiated RNG. Only the bits in WC_RNG_FLAGS_SETTABLE may be set this way (WC_RNG_FLAG_FAIL_FAST, WC_RNG_FLAG_ONLY_PRIMARY_SEED, WC_RNG_FLAG_NO_PRIMARY_SEED); the rest are structural, fixed by instantiation or by the module, and are refused. A flag change is a read-modify-write of the instance, so it requires exclusive ownership: in WC_RNG_HAVE_LOCK builds the instance must have been instantiated with WC_RNG_INIT_FLAG_LOCK_REQUIRED and the caller must hold its lease; otherwise only SINGLE_THREADED builds support it. WC_RNG_FLAG_FAIL_FAST makes a generate that would otherwise reseed in-line report instead – NOT_READY_E for an exhausted reseed budget, NEEDS_RECOVERY_E for entropy invalidation – leaving the DRBG in service; explicit reseed APIs are unaffected. The same policy can be fixed at instantiation with WC_RNG_INIT_FLAG_FAIL_FAST.
int wc_RNG_ClearFlags(WC_RNG * rng, word32 flags)
Clear runtime policy flags on an instantiated RNG. Only the bits in WC_RNG_FLAGS_CLEARABLE may be cleared (WC_RNG_FLAG_FAIL_FAST, WC_RNG_FLAG_ONLY_PRIMARY_SEED); WC_RNG_FLAG_NO_PRIMARY_SEED is set_only, since under FIPS it is a provenance commitment. Same ownership precondition as wc_RNG_SetFlags().
int wc_RNG_GetFlags(const WC_RNG * rng, word32 * flags)
Read an instance's runtime flags (WC_RNG_FLAG_*) – the read_only companion of wc_RNG_SetFlags()/wc_RNG_ClearFlags(), so an application can establish an instance's posture (seed_source policy, fail_fast, chain and lock discipline, bank_reference shell) without reaching into the object. A plain load with no ownership precondition, like wc_RNG_Status(): authoritative when the caller holds the instance's lease, otherwise a snapshot. A WC_RNG_FLAG_BANKREF shell reports its own flags, not those of the bank instance a draw through it would resolve to.
int wc_RNG_Pool_Alloc(WC_RNG * rng, word32 size)
Attach a random pool to rng: a buffer of size bytes of pre_generated output, filled by wc_RNG_Pool_Collect() and drained atomic_context_safely by wc_RNG_Pool_Extract(). The pool is released only by wc_FreeRng(), and an instance reinstantiated through wc_FreeRng() comes back poolless, so a collector re_equips it by calling this again – the call is idempotent (ALREADY_E on a live ring) and needs no lease: the ring's lifecycle is arbitrated by an atomic aperture word, so it is safe against a concurrent wc_FreeRng() or wc_RNG_Pool_Collect2() on the same instance.
int wc_RNG_Pool_Collect(WC_RNG * rng, word32 n)
Generate up to n bytes into rng's pool from rng itself. Equivalent to wc_RNG_Pool_Collect2(rng, rng, n); see there for the contract.
int wc_RNG_Pool_Collect2(WC_RNG * rng_dest, WC_RNG * rng_src, word32 n)
The two_instance form of wc_RNG_Pool_Collect(): fill rng_dest's pool with output drawn from rng_src – so a service instance's pool can be topped up by a daemon_owned generator. No lease on rng_dest is needed: the collector claims the ring through its atomic aperture word for the duration of the generate (collectors are mutually exclusive; a second one gets BUSY_E at once), and the claim is what makes a concurrent wc_FreeRng() on rng_dest refuse with BUSY_E rather than free a buffer being written. The generate runs with WC_RNG_FLAG_FAIL_FAST on rng_src (set transiently if rng_src does not carry it), so the claim is held for one bounded generate and never across an in_line reseed: this call never reseeds its source, and a source whose budget is exhausted or which requires recovery is reported, not serviced – source upkeep belongs to the source's owner. On a lock_required rng_src the caller must hold its lease. Under WC_RNG_HAVE_RBGC, rng_src may not sit deeper in the RBG chain than rng_dest (SP 800_90C sect. 7.3.1 item 16). In FIPS builds the eligibility rule is narrower still: rng_src must be rng_dest itself, or (under WC_RNG_HAVE_RBGC) rng_dest's direct RBGC parent – the two relationships under which rng_src's output is already sanctioned to reach rng_dest. Any other source is refused with WRONG_TYPE_OBJECT_E before any other processing, the n = 0 no-op included.
int wc_RNG_Pool_Extract(WC_RNG * rng, byte * out, word32 * n)
Drain up to n bytes from rng's pool into out – atomic-context-safe. On success n reports the bytes actually delivered; on any error return *n is left unmodified.
int wc_RNG_Pool_Current(const WC_RNG * rng, word32 * n)
Report the pool's current fill in bytes (0 when rng has no pool, or a purge is pending the reader's acknowledgement). The snapshot is racy by design, and needs no lease.
int wc_rng_debug_stats_snap(struct wc_rng_debug_stats_snapshot * s, const WC_RNG * rng)
Snapshot rng's debug counters (WC_RNG_DEBUG_STATS) – seeds and reseeds by provenance, generates, lock traffic, pool and bank traffic – into s, for later delta accounting with wc_rng_debug_stats_sum(). The counters are per instance.
int wc_rng_debug_stats_restore(const struct wc_rng_debug_stats_snapshot * s, WC_RNG * rng)
Restore rng's debug counters from a snapshot – so a test can unwind its own accounting.
int wc_rng_debug_stats_sum(struct wc_rng_debug_stats_snapshot * s, const WC_RNG * rng)
Accumulate rng's current debug counters into s – combined with a prior wc_rng_debug_stats_snap(), a delta accounting of the interval's activity, or across instances, a bank-wide total.
WC_ATOMIC_UINT_ARG wc_RNG_global_invalidate_entropy(void )
Advances the process-global entropy epoch, marking every RNG instance's entropy as predating the current environment.
WC_ATOMIC_UINT_ARG wc_RNG_get_global_entropy_epoch(void )
Read the process_global entropy epoch: the count of wc_RNG_global_invalidate_entropy() events so far. An instance whose stamp differs from this value has an undelivered event pending (see wc_RNG_entropy_needs_recovery(), which delivers it). A relaxed snapshot, for diagnostics and for callers that want to notice an event without touching any instance; nothing is propagated.
int wc_InitRngNonceRBGC(WC_RNG * child, WC_RNG * parent, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, word32 flags)
Initializes an RNG instance seeded from a parent RNG, as an SP 800-90C RBG chain member, with an optional nonce and personalization string.
int wc_RNG_entropy_needs_recovery(WC_RNG * rng)
Reports whether an RNG instance has a standing obligation to acquire fresh entropy before further use.
int wc_rng_bank_new(struct wc_rng_bank * ctx, int n_rngs, word32 flags, int timeout_secs, void * heap, int devId)
Allocate and initialize a bank of n_rngs pre_instantiated WC_RNG instances, checked out and back in by consumers (wc_rng_bank_checkout() et al.). The bank is allocated from heap; release with wc_rng_bank_free(). Bank_level flags (WC_RNG_BANK_FLAG_
) fix the bank's posture at initialization: e.g. _CAN_WAIT admits sleeping, _QUIET suppresses seeding-degradation warnings, _NO_CHECKOUT_REFCOUNTING suppresses per-checkout refcount traffic for container-guaranteed lifetimes, _PREDICTION_RESISTANCE imposes a bank-wide fresh-reseed posture on every sleepable lease.
int wc_rng_bank_init(struct wc_rng_bank * ctx, int n_rngs, word32 flags, int timeout_secs, void * heap, int devId)
Initialize a caller_provided bank object. Semantics of wc_rng_bank_new(), without the allocation; release with wc_rng_bank_fini().
int wc_rng_bank_init_nonce(struct wc_rng_bank * ctx, int n_rngs, word32 flags, int timeout_secs, void * heap, int devId, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz)
The nonce_bearing form of wc_rng_bank_init(): the nonce is used as additional instantiation input for each instance.
int wc_rng_bank_first_failover_inst_set(struct wc_rng_bank * ctx, int first_failover_inst)
Designate the first instance of the failover pool: checkouts without a targeted preference rotate through instances at and above first_failover_inst, reserving the lower offsets for targeted (affinity or daemon) use.
int wc_rng_bank_set_affinity_handlers(struct wc_rng_bank * ctx, wc_affinity_lock_fn_t affinity_lock_cb, wc_affinity_get_id_fn_t affinity_get_id_cb, wc_affinity_unlock_fn_t affinity_unlock_cb, void * cb_arg)
Install affinity handlers: callbacks that pin the caller to an execution context (e.g. disable preemption or migration), report its id for instance affinity, and unpin. With handlers installed, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST checkouts prefer the instance matching the caller's affinity id, and WC_RNG_BANK_FLAG_AFFINITY_LOCK holds the pin across the lease.
int wc_rng_bank_fini(struct wc_rng_bank * ctx)
Tear down a bank initialized with wc_rng_bank_init(): once the refcount and per-instance lease gates pass, fires any registered free hook and frees every instance. Never waits: a referenced or leased bank is refused with BUSY_E, and the caller quiesces its consumers and retries.
int wc_rng_bank_free(struct wc_rng_bank ** ctx)
Tear down and release a bank allocated with wc_rng_bank_new().
int wc_rng_bank_default_set(struct wc_rng_bank * bank)
Register bank as the process_default bank, retrievable with wc_rng_bank_default_checkout().
int wc_rng_bank_default_checkout(struct wc_rng_bank ** bank)
Take a reference on the process-default bank.
int wc_rng_bank_default_checkin(struct wc_rng_bank ** bank)
Release a reference taken with wc_rng_bank_default_checkout().
int wc_rng_bank_default_clear(struct wc_rng_bank * bank)
Unregister the process-default bank.
int wc_rng_bank_checkout(struct wc_rng_bank * bank, struct wc_rng_bank_inst ** rng_inst, int preferred_inst_offset, int timeout_secs, word32 flags)
Lease an in_service instance from the bank: either the preferred (or affinity_matched) instance, or – with WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST – the first available failover instance. On success the caller owns the instance's lock; access the WC_RNG with WC_RNG_BANK_INST_TO_RNG() and return the lease with wc_rng_bank_inst_checkin(). WC_RNG_BANK_FLAG_CONSUME_NEXT_SEED consumes a ready banked next seed in an immediate source_free credited reseed before returning; WC_RNG_BANK_FLAG_PREDICTION_RESISTANCE (per_call, requires _CAN_WAIT) freshly credited_reseeds the lease from the primary source (wc_RNG_DRBG_Reseed_Now_Primary()) before the caller's first draw. On a bank whose members are RBG_chain children of a root (WC_RNG_BANK_FLAG_RBGC) in a WC_RNG_RBGC_STRATUM_IMMUTABLE build, that reseed is conformant but the lease's output carries no SP 800_90C prediction_resistance claim – a chain member is not a DRBG with direct access to its entropy source (see wc_RNG_DRBG_Reseed_Now_Primary()).
int wc_rng_bank_checkin(struct wc_rng_bank * bank, struct wc_rng_bank_inst ** rng_inst)
Return a lease through the bank object, validating that rng_inst belongs to bank. Prefer wc_rng_bank_inst_checkin() when only the instance pointer is at hand.
int wc_rng_bank_inst_checkin(struct wc_rng_bank_inst ** rng_inst)
Return a lease by instance pointer alone.
int wc_rng_bank_get_inst_id(struct wc_rng_bank_inst * rng_inst)
Report the instance's offset within its bank.
int wc_rng_bank_next_seed_generate(struct wc_rng_bank * bank, int inst_offset, word32 n)
Bank next_seed material for the instance at inst_offset –wc_RNG_DRBG_NextSeedGenerate() through the bank, without taking the instance lock; the daemon-side serialization word arbitrates against concurrent whole-instance reinitialization.
int wc_rng_bank_next_seed_generate_rbgc(struct wc_rng_bank * bank, int inst_offset, word32 n)
The chain_sourced form of wc_rng_bank_next_seed_generate(): the banked material is drawn from root's generate function and tagged with its provenance.
int wc_rng_bank_inst_reinit(struct wc_rng_bank * bank, struct wc_rng_bank_inst * rng_inst, int timeout_secs, word32 flags)
Free and reinstantiate a leased instance in place. The caller must hold the lease; the daemon-side serialization word excludes concurrent lockless banking during the cycle.
int wc_rng_bank_recover_inst(struct wc_rng_bank * bank, int inst_offset, int timeout_secs, word32 flags)
Patrol helper: check out the instance at inst_offset with WC_RNG_BANK_FLAG_FOR_RECOVERY, recover it iff it needs recovery, and check it back in. Two recovery arms: an out_of_service instance (wc_RNG_GetStatus() != WC_DRBG_OK) is reinitialized in place; an in_service but entropy_invalidated (quarantined) instance takes one credited reseed, which clears the quarantine while preserving instance identity. A healthy instance is a success no-op, so callers can invoke this unconditionally on state observed locklessly.
int wc_rng_bank_spawn(struct wc_rng_bank * bank, WC_RNG * child_rng, byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, int preferred_inst_offset, int timeout_secs, word32 flags)
Spawn an SP 800_90C chain RNG from a bank instance: check out a parent instance (honoring the usual selection flags), instantiate child_rng as its chain child (wc_InitRngNonceRBGC()), and check the parent back in. The child's lifetime is thereafter decoupled from the parent and its bank; release it with wc_FreeRng() (or wc_rng_free() for the heap form, wc_rng_bank_spawn_new()). The child's RBGC stratum is one plus the parent's stratum at instantiation.
int wc_rng_bank_spawn_new(struct wc_rng_bank * bank, WC_RNG ** child_rng, byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, int preferred_inst_offset, int timeout_secs, word32 flags)
The allocating form of wc_rng_bank_spawn(): the child is allocated from the bank's heap and returned through child_rng; release with wc_rng_free().
int wc_rng_bank_seed(struct wc_rng_bank * bank, const byte * seed, word32 seedSz, const byte * nonce, word32 nonceSz, int timeout_secs, word32 flags)
Reseed every instance with caller-supplied seed material. WC_RNG_BANK_FLAG_STIR mixes the material in without crediting it.
int wc_rng_bank_seed_range(struct wc_rng_bank * bank, int first_inst, int last_inst, const byte * seed, word32 seedSz, const byte * nonce, word32 nonceSz, int timeout_secs, word32 flags)
The range form of wc_rng_bank_seed(): seed instances first_inst through last_inst inclusive.
int wc_rng_bank_reseed(struct wc_rng_bank * bank, const byte * nonce, word32 nonceSz, int timeout_secs, word32 flags)
Reseed every instance from the module's seed source. Same contract as wc_rng_bank_reseed_range() over the whole bank.
int wc_rng_bank_reseed_range(struct wc_rng_bank * bank, int first_inst, int last_inst, const byte * nonce, word32 nonceSz, int timeout_secs, word32 flags)
The range form of wc_rng_bank_reseed(). A failed reseed does not stop the walk: the instance is marked due for reseed, the next entropy_capable generate on it retries in_boundary, and the walk carries on to the remaining instances – but the first such failure is the return value, so the caller knows the range was not reseeded here and now. A code that stops the walk (WC_TIMEOUT_E, INTERRUPTED_E, a checkout failure) outranks it: the instances past that point were not visited and are not marked due. A transient per_instance code (WC_RNG_ERR_IS_TRANSIENT()) means that instance's reseed is a pass away from resolving on its own; for the rest, see wc_RNG_DRBG_Reseed_Now().
int wc_rng_bank_invalidate_entropy(struct wc_rng_bank * bank, word32 flags)
Set the entropy_invalidated latch on every instance (see wc_RNG_invalidate_entropy()): cached entropy products are discarded, and each instance is forced through a credited reseed before its next generate serves output. Lock_free and constant_time per instance; safe from a state_invalidation event context (VM fork/resume).
int wc_rng_bank_daemon_reserve(struct wc_rng_bank * bank, WC_ATOMIC_UINT_ARG magic)
Reserve the bank's daemon slot with a caller-chosen nonzero magic word, admitting exactly one scheduling daemon per bank. The lifecycle is strictly ordered: _reserve, then _register, then _unregister, then _release.
int wc_rng_bank_daemon_register(struct wc_rng_bank * bank, void * daemon, WC_ATOMIC_UINT_ARG magic)
Register the daemon object in a slot reserved with the same magic word.
int wc_rng_bank_daemon_unregister(struct wc_rng_bank * bank, void ** daemon, WC_ATOMIC_UINT_ARG magic)
Unregister the daemon object, returning it through daemon.
int wc_rng_bank_daemon_release(struct wc_rng_bank * bank, WC_ATOMIC_UINT_ARG magic)
Release the daemon slot claimed with magic, returning it to the free sentinel.
int wc_rng_bank_register_free_hook(struct wc_rng_bank * bank, wc_rng_bank_free_hook_cb_t free_hook, void * arg)
Register a callback fired by wc_rng_bank_fini() once its refcount and leak gates pass – i.e. once teardown is committed – for external registries that must drop their reference when the bank dies. One-shot: the hook is cleared before firing. A null free_hook unregisters.
int wc_InitRng_BankRef(struct wc_rng_bank * bank, WC_RNG * rng)
Initialize rng as a bank reference: a WC_RNG with no DRBG of its own, whose wc_RNG_GenerateBlock() transparently checks an instance out of bank, generates, and checks it back in. Release with wc_FreeRng().
int wc_BankRef_Release(WC_RNG * rng)
Release a bank reference. wc_FreeRng() calls this automatically for bank references; direct use is rarely needed.
int wc_rng_new_bankref(struct wc_rng_bank * bank, WC_RNG ** rng)
The allocating form of wc_InitRng_BankRef(): the reference is allocated from the bank's heap; release with wc_rng_free().
int wc_rng_bank_debug_stats_snap(struct wc_rng_debug_stats_snapshot * s, struct wc_rng_bank * bank)
Snapshot the RNG debug counters (WC_RNG_DEBUG_STATS) with bank-level context.

Detailed Description

Makes the unguessable numbers used for keys and other secrets. It takes a little true randomness from an entropy source and stretches it into as much output as you ask for.

When that source is wolfEntropy, see Entropy Source - wolfEntropy (MemUse).

Functions Documentation

function wc_InitRng

int wc_InitRng(
    WC_RNG * rng
)

Gets the seed (from OS) and key cipher for rng. rng->drbg (deterministic random bit generator) allocated (should be deallocated with wc_FreeRng). This is a blocking operation.

Parameters:

  • rng random number generator to be initialized for use with a seed and key cipher

See:

Return:

  • 0 on success.
  • MEMORY_E XMALLOC or the fork handler registration failed
  • WINCRYPT_E wc_GenerateSeed: failed to acquire context
  • CRYPTGEN_E wc_GenerateSeed: failed to get random
  • BAD_FUNC_ARG wc_RNG_GenerateBlock input is null or sz exceeds MAX_REQUEST_LEN
  • DRBG_CONT_FIPS_E wc_RNG_GenerateBlock: Hash_gen returned DRBG_CONT_FAILURE
  • ENTROPY_RT_E or ENTROPY_APT_E wc_InitRng: the SP 800-90B seed health test rejected the entropy gathered to instantiate
  • RAN_BLOCK_E, NOT_READY_E, or BUSY_E wc_InitRng: the seed source had nothing to give yet; retryable, like the two above (see WC_RNG_ERR_IS_TRANSIENT()). Any other seed source failure is reported as RNG_FAILURE_E.
  • RNG_FAILURE_E wc_RNG_GenerateBlock: Default error. rng’s status originally not ok, or set to DRBG_FAILED
  • BAD_MUTEX_E the lock that lets threads share this rng could not be created; define WC_RNG_NO_AUTO_LOCK to build without it

One WC_RNG may be shared between threads for generating and reseeding: wc_RNG_GenerateBlock(), wc_RNG_DRBG_Reseed(), wc_RNG_DRBG_Reseed_Nonce() and wc_RNG_DRBG_Reseed_Now() each hold the instance lock. So do the DRBG management calls: wc_RNG_DRBG_Stir(), wc_RNG_DRBG_Stir_Nonce() and wc_RNG_DRBG_ScheduleReseed(), and in –enable_rng_extras builds wc_RNG_DRBG_NextStirNow(), wc_RNG_DRBG_NextSeedNow() and wc_RNG_DRBG_NextSeedNow_Nonce(). The generate path calls their internal cores, which already run under the lock.

wc_RNG_DRBG_ReseedRBGC() and wc_RNG_DRBG_StirRBGC() are the exception: they draw from a second instance, so locking both would put two instance locks in play at once, and two threads reseeding each other from the other could then wait on each other for good. A caller that needs them on a shared instance stops the other threads first.

WC_RNG_NO_AUTO_LOCK (configure –disable-rng-autolock) leaves the lock out; CMSIS-RTOS v1 builds have none, its mutex pool holds ten. Every backend but a crypto callback runs with the lock held; a callback answers first, so it may fall back to the same instance. A seed callback runs with the lock held and must not use the RNG API. wc_InitRng*() and wc_FreeRng() do not lock; initialize only a new or freed WC_RNG, with no other thread using it.

POSIX lets a forked child of a threaded process only exec. Where the build has pthread_atfork(), unnamed POSIX semaphores and the dladdr() pin, fork handlers let the child keep using its WC_RNG: the parent holds every lock across fork() and the child releases them and reseeds, so each fork() waits for every live instance's generate in flight. The child should use an instance it already has: wc_InitRng() there still waits on a mutex the handlers do not cover. –disable_rng_autofork leaves them out; a user_settings build defines WC_RNG_AUTOFORK to turn them on. The child's reseed uses the configured allocator and seed source, which must therefore work after fork(). wolfCrypt_Init() or the first wc_InitRng() registers them; they can never be unregistered, so the library pins itself against dlclose(). They cover WC_RNG locks only, not clone(), vfork() or _Fork(). A fork() from inside a seed or hash callback works: that thread holds the lock, so the handler leaves it alone and the child frees it as usual. A fork() called from a signal handler can hang the caller, if the signal caught a thread part_way through taking or releasing a lock; POSIX does not allow fork() from a signal handler with handlers like these anyway. Values stay safe either way, with or without the handlers: the child reseeds on its pid change.

Builds without the handlers, macOS among them, leave a forked child only exec(): a child that calls the RNG instead blocks for good if any thread held the instance lock at fork() time. A fork() from a single threaded process is unaffected, since no lock can be held by a thread the child does not have.

Example

RNG  rng;
int ret;

#ifdef HAVE_CAVIUM
ret = wc_InitRngCavium(&rng, CAVIUM_DEV_ID);
if (ret != 0){
    printf(“RNG Nitrox init for device: %d failed”, CAVIUM_DEV_ID);
    return -1;
}
#endif
ret = wc_InitRng(&rng);
if (ret != 0){
    printf(“RNG init failed”);
    return -1;
}

function wc_RNG_GenerateBlock

int wc_RNG_GenerateBlock(
    WC_RNG * rng,
    byte * output,
    word32 sz
)

Copies a sz bytes of pseudorandom data to output. Will reseed rng if needed (blocking).

Parameters:

  • rng random number generator initialized with wc_InitRng
  • output buffer to which the block is copied
  • sz size of output in bytes

See:

Return:

  • 0 on success
  • BAD_FUNC_ARG an input is null or sz exceeds MAX_REQUEST_LEN
  • DRBG_CONT_FIPS_E Hash_gen returned DRBG_CONT_FAILURE
  • ENTROPY_RT_E or ENTROPY_APT_E the SP 800-90B seed health test rejected the entropy gathered for a reseed
  • NOT_READY_E a recovery reseed failed retryably with reseed runway remaining; the instance is not condemned and the call may be retried
  • NEEDS_RECOVERY_E the instance carries a recovery obligation (invalidated, stale entropy epoch, or PID change) and is WC_RNG_FLAG_FAIL_FAST, so no reseed was attempted; see wc_RNG_entropy_needs_recovery()
  • BUSY_E the reseed could not proceed without waiting (a contended seed source in a non-blockable context); retryable
  • MEMORY_E an allocation on the reseed path failed (in a non-blockable context, a transient refusal by the allocator); retryable, and like BUSY_E never a condemnation, even with no reseed runway left
  • OBJECT_NOT_LOCKED_E the instance requires its lock and the caller does not hold it
  • RNG_FAILURE_E Default error. rng’s status originally not ok, or set to DRBG_FAILED
  • BAD_MUTEX_E the rng's lock could not be taken

Example

RNG  rng;
int  sz = 32;
byte block[sz];

int ret = wc_InitRng(&rng);
if (ret != 0) {
    return -1; //init of rng failed!
}

ret = wc_RNG_GenerateBlock(&rng, block, sz);
if (ret != 0) {
    return -1; //generating block failed!
}

function wc_RNG_GenerateByte

int wc_RNG_GenerateByte(
    WC_RNG * rng,
    byte * b
)

Calls wc_RNG_GenerateBlock to copy a byte of pseudorandom data to b. Will reseed rng if needed.

Parameters:

  • rng random number generator initialized with wc_InitRng
  • b one byte buffer to which the block is copied

See:

Return:

  • 0 on success
  • BAD_FUNC_ARG an input is null or sz exceeds MAX_REQUEST_LEN
  • DRBG_CONT_FIPS_E Hash_gen returned DRBG_CONT_FAILURE
  • RNG_FAILURE_E Default error. rng’s status originally not ok, or set to DRBG_FAILED
  • BAD_MUTEX_E the rng's lock could not be taken
  • other as for wc_RNG_GenerateBlock()

Example

RNG  rng;
int  sz = 32;
byte b[1];

int ret = wc_InitRng(&rng);
if (ret != 0) {
    return -1; //init of rng failed!
}

ret = wc_RNG_GenerateByte(&rng, b);
if (ret != 0) {
    return -1; //generating block failed!
}

function wc_FreeRng

int wc_FreeRng(
    WC_RNG * rng
)

Tears down an RNG instance: zeroizes and releases its DRBG state. The WC_RNG must have come from wc_InitRng*() or be zeroed.

Parameters:

  • rng random number generator initialized with wc_InitRng

See:

Return:

  • 0 on success
  • BAD_FUNC_ARG rng is NULL
  • BUSY_E the instance lock is held, or a pool collector holds the ring (WC_RNG_HAVE_POOL); nothing was done
  • STILL_REFERENCED_E sensitive state was zeroized, but spawned children still reference the instance; retry after they are freed
  • RNG_FAILURE_E state teardown failed

wc_FreeRng() is a lock_protocol participant, not a lock_protocol client: it acquires the instance lock internally with destruction_specific semantics, and callers must not hold the lock across the call (never bracket wc_FreeRng() with wc_RNG_lock_get()/wc_RNG_lock_put() – a caller already holding the lock uses wc_FreeRng_PreLocked() instead). BUSY_E reports a live lease – or, with WC_RNG_HAVE_POOL, a pool collector holding the ring's claim (wc_RNG_Pool_Collect2() mid_generate, or wc_RNG_Pool_Alloc() mid_attach): nothing was changed, and the call can be retried once the instance quiesces; the collector's hold is bounded (one generate, no in_line reseed). STILL_REFERENCED_E reports that spawned RBGC children still reference the instance as their reseed parent: all cryptographically sensitive state has already been zeroized and the instance's status returns to the uninitialized state, but the object's memory must remain valid until the last child is freed, after which retrying wc_FreeRng() completes the teardown. Reinitializing an instance after a nonzero return, other than through the documented preserve-flagged in-place reinit under a held lock, is forbidden.

Example

RNG  rng;
int ret = wc_InitRng(&rng);
if (ret != 0) {
    return -1; //init of rng failed!
}

int ret = wc_FreeRng(&rng);
if (ret != 0) {
    return -1; //free of rng failed!
}

function wc_FreeRng_PreLocked

int wc_FreeRng_PreLocked(
    WC_RNG * rng
)

Tears down an RNG instance whose lock the caller already holds.

Parameters:

  • rng random number generator initialized with wc_InitRng*(), with the instance lock held by the caller

See:

Return:

  • 0 on success
  • BAD_FUNC_ARG rng is NULL
  • OBJECT_NOT_LOCKED_E the instance requires locking and the caller does not hold the lock
  • BUSY_E a pool collector holds the ring; nothing was done
  • STILL_REFERENCED_E sensitive state was zeroized, but spawned children still reference the instance; retry after they are freed
  • RNG_FAILURE_E state teardown failed

The core of wc_FreeRng() for callers inside a held_lock bracket (a lease from wc_RNG_lock_get(), or a bank checkout): that the lock is held is verified on entry (the word cannot say by whom – holding it is the caller's contract), no lock acquisition or release is performed, and the lock remains held on return, ready for an in_place reinitialization with the WC_RNG_INIT_FLAG_PRESERVE_LOCK semantics or for release by the caller. BUSY_E is returned only for a pool collector holding the ring's claim (WC_RNG_HAVE_POOL; see wc_FreeRng()): it is a try_once refusal, never a wait, so it is safe from atomic context, and nothing was torn down – the instance is intact for a retry. STILL_REFERENCED_E has the same semantics as for wc_FreeRng(), and a retry while still holding the lock converges without a re-acquisition race.

function wc_RNG_HealthTest

int wc_RNG_HealthTest(
    int reseed,
    const byte * seedA,
    word32 seedASz,
    const byte * seedB,
    word32 seedBSz,
    byte * output,
    word32 outputSz
)

Creates and tests functionality of drbg.

Parameters:

  • int reseed: if set, will test reseed functionality
  • seedA seed to instantiate drgb with
  • seedASz size of seedA in bytes
  • seedB If reseed set, drbg will be reseeded with seedB
  • seedBSz size of seedB in bytes
  • output initialized to random data seeded with seedB if seedrandom is set, and seedA otherwise
  • outputSz length of output in bytes

See:

Return:

  • 0 on success
  • BAD_FUNC_ARG seedA and output must not be null. If reseed set seedB must not be null
  • -1 test failed

Example

byte output[SHA256_DIGEST_SIZE * 4];
const byte test1EntropyB[] = ....; // test input for reseed false
const byte test1Output[] = ....;   // testvector: expected output of
                               // reseed false
ret = wc_RNG_HealthTest(0, test1Entropy, sizeof(test1Entropy), NULL, 0,
                    output, sizeof(output));
if (ret != 0)
    return -1;//healthtest without reseed failed

if (XMEMCMP(test1Output, output, sizeof(output)) != 0)
    return -1; //compare to testvector failed: unexpected output

const byte test2EntropyB[] = ....; // test input for reseed
const byte test2Output[] = ....;   // testvector expected output of reseed
ret = wc_RNG_HealthTest(1, test2EntropyA, sizeof(test2EntropyA),
                    test2EntropyB, sizeof(test2EntropyB),
                    output, sizeof(output));

if (XMEMCMP(test2Output, output, sizeof(output)) != 0)
    return -1; //compare to testvector failed

function wc_GenerateSeed

int wc_GenerateSeed(
    OS_Seed * os,
    byte * output,
    word32 sz
)

Generates seed from OS entropy source. Lower-level function used internally by wc_InitRng.

Parameters:

  • os Pointer to OS_Seed structure
  • output Buffer to store seed
  • sz Size of seed in bytes

See: wc_InitRng

Return:

  • 0 On success
  • WINCRYPT_E Failed to acquire context (Windows)
  • CRYPTGEN_E Failed to generate random (Windows)
  • RNG_FAILURE_E Failed to read entropy

Example

OS_Seed os;
byte seed[32];
int ret = wc_GenerateSeed(&os, seed, sizeof(seed));

function wc_rng_new

WC_RNG * wc_rng_new(
    byte * nonce,
    word32 nonceSz,
    void * heap
)

Allocates and initializes new WC_RNG with optional nonce.

Parameters:

  • nonce Nonce buffer (can be NULL)
  • nonceSz Nonce size
  • heap Heap hint (can be NULL)

See: wc_rng_free

Return:

  • Pointer to WC_RNG on success
  • NULL on failure

Example

WC_RNG* rng = wc_rng_new(NULL, 0, NULL);
wc_rng_free(rng);

function wc_rng_new_ex

int wc_rng_new_ex(
    WC_RNG ** rng,
    byte * nonce,
    word32 nonceSz,
    void * heap,
    int devId
)

Allocates and initializes WC_RNG with extended parameters.

Parameters:

  • rng Pointer to store WC_RNG pointer
  • nonce Nonce buffer (can be NULL)
  • nonceSz Nonce size
  • heap Heap hint (can be NULL)
  • devId Device ID (INVALID_DEVID for software)

See: wc_rng_new

Return:

  • 0 On success
  • BAD_FUNC_ARG If rng is NULL
  • MEMORY_E Memory allocation failed
  • BAD_MUTEX_E the lock that lets threads share this rng could not be created

Example

WC_RNG* rng;
int ret = wc_rng_new_ex(&rng, NULL, 0, NULL, INVALID_DEVID);
wc_rng_free(rng);

function wc_rng_free

void wc_rng_free(
    WC_RNG * rng
)

Frees WC_RNG allocated with wc_rng_new.

Parameters:

  • rng WC_RNG to free

See: wc_rng_new

Example

WC_RNG* rng = wc_rng_new(NULL, 0, NULL);
wc_rng_free(rng);

function wc_InitRng_ex

int wc_InitRng_ex(
    WC_RNG * rng,
    void * heap,
    int devId
)

Initializes WC_RNG with extended parameters.

Parameters:

  • rng WC_RNG to initialize
  • heap Heap hint (can be NULL)
  • devId Device ID (INVALID_DEVID for software)

See: wc_InitRng

Return:

  • 0 On success
  • BAD_FUNC_ARG If rng is NULL
  • RNG_FAILURE_E Initialization failed
  • BAD_MUTEX_E the lock that lets threads share this rng could not be created
  • MEMORY_E the fork handlers could not be registered

Example

WC_RNG rng;
int ret = wc_InitRng_ex(&rng, NULL, INVALID_DEVID);
wc_FreeRng(&rng);

function wc_InitRngNonce

int wc_InitRngNonce(
    WC_RNG * rng,
    const byte * nonce,
    word32 nonceSz
)

Initializes WC_RNG with nonce.

Parameters:

  • rng WC_RNG to initialize
  • nonce Nonce buffer
  • nonceSz Nonce size

See: wc_InitRng

Return:

  • 0 On success
  • BAD_FUNC_ARG If rng is NULL
  • RNG_FAILURE_E Initialization failed
  • BAD_MUTEX_E the lock that lets threads share this rng could not be created
  • MEMORY_E the fork handlers could not be registered

Example

WC_RNG rng;
byte nonce[16];
int ret = wc_InitRngNonce(&rng, nonce, sizeof(nonce));
wc_FreeRng(&rng);

function wc_InitRngNonce_ex

int wc_InitRngNonce_ex(
    WC_RNG * rng,
    const byte * nonce,
    word32 nonceSz,
    void * heap,
    int devId
)

Initializes WC_RNG with nonce and extended parameters.

Parameters:

  • rng WC_RNG to initialize
  • nonce Nonce buffer
  • nonceSz Nonce size
  • heap Heap hint (can be NULL)
  • devId Device ID (INVALID_DEVID for software)

See: wc_InitRngNonce

Return:

  • 0 On success
  • BAD_FUNC_ARG If rng is NULL
  • RNG_FAILURE_E Initialization failed
  • BAD_MUTEX_E the lock that lets threads share this rng could not be created
  • MEMORY_E the fork handlers could not be registered

Example

WC_RNG rng;
byte nonce[16];
int ret = wc_InitRngNonce_ex(&rng, nonce, sizeof(nonce), NULL,
                             INVALID_DEVID);
wc_FreeRng(&rng);

function wc_SetSeed_Cb

int wc_SetSeed_Cb(
    wc_RngSeed_Cb cb
)

Sets callback for custom seed generation.

Parameters:

  • cb Seed callback function

See: wc_GenerateSeed

Return:

  • 0 On success
  • BAD_FUNC_ARG If cb is NULL

Example

int my_cb(OS_Seed* os, byte* out, word32 sz) { return 0; }
wc_SetSeed_Cb(my_cb);

function wc_RNG_DRBG_Reseed

int wc_RNG_DRBG_Reseed(
    WC_RNG * rng,
    const byte * seed,
    word32 seedSz
)

Reseeds DRBG with new entropy. The material is credited: the reseed counter resets.

Parameters:

  • rng WC_RNG to reseed
  • seed Seed buffer
  • seedSz Seed size

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) reports success without action; wc_RNG_DRBG_Present() disambiguates. (Refusals below take precedence.)
  • BAD_FUNC_ARG If rng or seed is NULL
  • RNG_FAILURE_E Reseed failed, or rng is condemned (see
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • BAD_MUTEX_E the rng's lock could not be taken
  • BAD_LENGTH_E seed is undersized while a reseed obligation stands (see
  • WRONG_TYPE_OBJECT_E rng is below the user-provenance sentinel (every primary-seeded, chain-seeded, or RDRAND instance) and the build is WC_RNG_RBGC_STRATUM_IMMUTABLE (see
  • NEEDS_RECOVERY_E The reseed succeeded, but a global entropy event (epoch increment or PID change) landed during it, so the obligation stands and the instance must not serve until recovered.

In RBG-chain builds, a successful user-supplied reseed marks rng with the user-provenance stratum sentinel (WC_RNG_RBGC_USER_SEED_STRATUM). When built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS), the stratum is never lowered, keeping instances whose credited seeding is of unknown provenance permanently distinguishable from ESV-seeded lineage, and a credited user-class reseed of any instance below the sentinel – a primary-seeded root or an RBG-chain member alike – is refused with WRONG_TYPE_OBJECT_E: the credited reseed would reset the reseed counter on unknown-provenance entropy while the immutable stratum continued to advertise vetted-provenance seeding. Uncredited stirs (wc_RNG_DRBG_Stir()) remain available precisely because they claim nothing; in such builds only instances instantiated with wc_InitRngNonce_UserSeed() accept user_class reseeds. The seed is not evaluated by wc_RNG_TestSeed()– deliberately, so KAT harnesses can inject fixed vectors; calling it beforehand is the caller's responsibility. While a reseed obligation stands (the reseed counter at its interval, or the entropy invalidated), a seed shorter than WC_DRBG_SEED_SZ is refused with BAD_LENGTH_E rather than allowed to clear the obligation. A condemned instance (DRBG_FAILED) refuses with RNG_FAILURE_E: recovery is wc_FreeRng() then wc_InitRng*(), not in-place resurrection.

) ). ). Example

WC_RNG rng;
byte seed[32];
wc_InitRng(&rng);
int ret = wc_RNG_DRBG_Reseed(&rng, seed, sizeof(seed));

function wc_RNG_TestSeed

int wc_RNG_TestSeed(
    const byte * seed,
    word32 seedSz
)

Tests seed validity for DRBG.

Parameters:

  • seed Seed to test
  • seedSz Seed size

See: wc_InitRng

Return:

  • 0 If valid
  • BAD_FUNC_ARG If seed is NULL
  • ENTROPY_RT_E || ENTROPY_APT_E Validation failed
  • ENTROPY_APT_E The adaptive proportion test failed.

Example

byte seed[32];
int ret = wc_RNG_TestSeed(seed, sizeof(seed));

function wc_RNG_HealthTest_ex

int wc_RNG_HealthTest_ex(
    int reseed,
    const byte * nonce,
    word32 nonceSz,
    const byte * seedA,
    word32 seedASz,
    const byte * seedB,
    word32 seedBSz,
    byte * output,
    word32 outputSz,
    void * heap,
    int devId
)

RNG health test with extended parameters.

Parameters:

  • reseed Non-zero to test reseeding
  • nonce Nonce buffer (can be NULL)
  • nonceSz Nonce size
  • seedA Initial seed
  • seedASz Initial seed size
  • seedB Reseed buffer (required if reseed set)
  • seedBSz Reseed size
  • output Output buffer
  • outputSz Output size
  • heap Heap hint (can be NULL)
  • devId Device ID (INVALID_DEVID for software)

See: wc_RNG_HealthTest

Return:

  • 0 On success
  • BAD_FUNC_ARG If required params NULL
  • -1 Test failed

Example

byte seedA[32], seedB[32], out[64];
int ret = wc_RNG_HealthTest_ex(1, NULL, 0, seedA, 32, seedB, 32,
                               out, 64, NULL, INVALID_DEVID);

function wc_RNG_HealthTest_SHA512

int wc_RNG_HealthTest_SHA512(
    int reseed,
    const byte * seedA,
    word32 seedASz,
    const byte * seedB,
    word32 seedBSz,
    byte * output,
    word32 outputSz
)

Runs the SHA-512 Hash_DRBG Known Answer Test (KAT) per SP 800-90A. Instantiates a SHA-512 DRBG with seedA, optionally reseeds with seedB, generates output, and compares against known test vectors. Available when WOLFSSL_DRBG_SHA512 is defined.

Parameters:

  • reseed Non-zero to test reseeding
  • seedA Initial entropy seed
  • seedASz Size of seedA in bytes
  • seedB Reseed entropy (required if reseed is set)
  • seedBSz Size of seedB in bytes
  • output Buffer to receive generated output
  • outputSz Size of output in bytes

See:

Return:

  • 0 On success
  • BAD_FUNC_ARG If seedA or output is NULL, or if reseed is set and seedB is NULL
  • -1 Test failed

Example

byte output[WC_SHA512_DIGEST_SIZE * 4];
const byte seedA[] = { ... };
const byte seedB[] = { ... };

ret = wc_RNG_HealthTest_SHA512(0, seedA, sizeof(seedA), NULL, 0,
                               output, sizeof(output));
if (ret != 0)
    return -1;

ret = wc_RNG_HealthTest_SHA512(1, seedA, sizeof(seedA),
                               seedB, sizeof(seedB),
                               output, sizeof(output));
if (ret != 0)
    return -1;

function wc_RNG_HealthTest_SHA512_ex

int wc_RNG_HealthTest_SHA512_ex(
    int reseed,
    const byte * nonce,
    word32 nonceSz,
    const byte * persoString,
    word32 persoStringSz,
    const byte * seedA,
    word32 seedASz,
    const byte * seedB,
    word32 seedBSz,
    const byte * additionalA,
    word32 additionalASz,
    const byte * additionalB,
    word32 additionalBSz,
    byte * output,
    word32 outputSz,
    void * heap,
    int devId
)

Extended SHA-512 Hash_DRBG health test with nonce, personalization string, and additional input support. Suitable for full ACVP / CAVP test vector validation. Available when WOLFSSL_DRBG_SHA512 is defined.

Parameters:

  • reseed Non-zero to test reseeding
  • nonce Nonce buffer (can be NULL)
  • nonceSz Nonce size
  • persoString Personalization string (can be NULL)
  • persoStringSz Personalization string size
  • seedA Initial entropy seed
  • seedASz Initial seed size
  • seedB Reseed entropy (required if reseed is set)
  • seedBSz Reseed size
  • additionalA Additional input for first generate (can be NULL)
  • additionalASz Additional input A size
  • additionalB Additional input for second generate (can be NULL)
  • additionalBSz Additional input B size
  • output Output buffer
  • outputSz Output size
  • heap Heap hint (can be NULL)
  • devId Device ID (INVALID_DEVID for software)

See:

Return:

  • 0 On success
  • BAD_FUNC_ARG If required params are NULL
  • -1 Test failed

Example

byte output[WC_SHA512_DIGEST_SIZE * 4];
const byte seedA[] = { ... };
const byte nonce[] = { ... };

int ret = wc_RNG_HealthTest_SHA512_ex(0, nonce, sizeof(nonce),
                                      NULL, 0,
                                      seedA, sizeof(seedA),
                                      NULL, 0,
                                      NULL, 0, NULL, 0,
                                      output, sizeof(output),
                                      NULL, INVALID_DEVID);

function wc_Sha256Drbg_Disable

int wc_Sha256Drbg_Disable(
    void 
)

Disables the SHA-256 Hash_DRBG in the process-wide runtime setting. The setting decides the DRBG flavor of every WC_RNG whose constructor was not told one explicitly: all of the constructors with no flags argument, and the flags-bearing ones (wc_InitRng_ex2() and the others taking WC_RNG_INIT_FLAG_* flags) when neither WC_RNG_INIT_FLAG_DRBG_SHA256 nor WC_RNG_INIT_FLAG_DRBG_SHA512 is given; either of those flags overrides the setting for that instance. The setting is read once, at instantiation, so instances already alive are unaffected. Both compiled-in flavors start enabled, with SHA-512 preferred where WOLFSSL_DRBG_SHA512 is defined, except that WOLFSSL_NO_SHA256_DRBG starts SHA-256 disabled (still compiled in, and enable-able); after this call the setting is SHA-512 only. The last enabled flavor cannot be disabled.

See:

Return:

  • 0 On success
  • BAD_STATE_E SHA-256 is the only enabled flavor, so it stays enabled.
  • NOT_COMPILED_IN WOLFSSL_DRBG_SHA512 is not defined, so there is no other flavor to leave enabled.

The setting is an atomic word, and the enable/disable calls update it by compare-and-swap, so concurrent calls serialize: the guard against disabling the last enabled flavor is evaluated against the value the update replaces, never a stale one, and no call's effect can be lost to another's. A constructor reads the setting once, at instantiation, so a change made while another thread is constructing an instance applies to that instance or not according to which happened first; nothing orders the two. Requires HAVE_HASHDRBG.

Example

wc_Sha256Drbg_Disable();
// New instances without an explicit flavor flag now use SHA-512 ...
WC_RNG rng;
wc_InitRng(&rng);
// ... unless the constructor is told otherwise.
WC_RNG rng2;
wc_InitRng_ex2(&rng2, NULL, INVALID_DEVID, WC_RNG_INIT_FLAG_DRBG_SHA256);

function wc_Sha256Drbg_Enable

int wc_Sha256Drbg_Enable(
    void 
)

Re-enables the SHA-256 Hash_DRBG in the process-wide runtime setting after a prior call to wc_Sha256Drbg_Disable(). Affects only instances created after the call, and not those whose constructor was given an explicit flavor flag; see wc_Sha256Drbg_Disable() for the setting's scope and concurrency. Requires HAVE_HASHDRBG.

See:

Return: 0 On success

Example

wc_Sha256Drbg_Disable();
// ... use SHA-512 DRBG only ...
wc_Sha256Drbg_Enable();
// New WC_RNG instances can use SHA-256 DRBG again

function wc_Sha256Drbg_IsDisabled

int wc_Sha256Drbg_IsDisabled(
    void 
)

Returns whether the SHA-256 Hash_DRBG is currently disabled in the process-wide runtime setting (see wc_Sha256Drbg_Disable()). Says nothing about instances already alive, or about ones whose constructor was given an explicit flavor flag. In a build without SHA-256 it is always 1. Requires HAVE_HASHDRBG.

See:

Return:

  • 1 SHA-256 DRBG is disabled
  • 0 SHA-256 DRBG is enabled (not disabled)

Example

if (wc_Sha256Drbg_IsDisabled()) {
    printf("SHA-256 DRBG is off\n");
}

function wc_Sha512Drbg_Disable

int wc_Sha512Drbg_Disable(
    void 
)

Disables the SHA-512 Hash_DRBG in the process-wide runtime setting, so that instances created after the call without an explicit flavor flag use SHA-256. The setting's scope – that it is read once at instantiation, and that WC_RNG_INIT_FLAG_DRBG_SHA256 / WC_RNG_INIT_FLAG_DRBG_SHA512 override it per instance – and its concurrency are described at wc_Sha256Drbg_Disable(). The last enabled flavor cannot be disabled. Available when WOLFSSL_DRBG_SHA512 is defined. Requires HAVE_HASHDRBG.

See:

Return:

  • 0 On success
  • BAD_STATE_E SHA-512 is the only enabled flavor, so it stays enabled.
  • NOT_COMPILED_IN NO_SHA256 is defined, so there is no other flavor to leave enabled.

Example

wc_Sha512Drbg_Disable();
// New WC_RNG instances will now use SHA-256 DRBG
WC_RNG rng;
wc_InitRng(&rng);

function wc_Sha512Drbg_Enable

int wc_Sha512Drbg_Enable(
    void 
)

Re-enables the SHA-512 Hash_DRBG in the process-wide runtime setting after a prior call to wc_Sha512Drbg_Disable(). Affects only instances created after the call, and not those whose constructor was given an explicit flavor flag; see wc_Sha256Drbg_Disable() for the setting's scope and concurrency. Available when WOLFSSL_DRBG_SHA512 is defined. Requires HAVE_HASHDRBG.

See:

Return: 0 On success

Example

wc_Sha512Drbg_Disable();
// ... use SHA-256 DRBG only ...
wc_Sha512Drbg_Enable();
// New WC_RNG instances can use SHA-512 DRBG again

function wc_Sha512Drbg_IsDisabled

int wc_Sha512Drbg_IsDisabled(
    void 
)

Returns whether the SHA-512 Hash_DRBG is currently disabled in the process-wide runtime setting (see wc_Sha256Drbg_Disable()). Says nothing about instances already alive, or about ones whose constructor was given an explicit flavor flag. Available when WOLFSSL_DRBG_SHA512 is defined. Requires HAVE_HASHDRBG.

See:

Return:

  • 1 SHA-512 DRBG is disabled
  • 0 SHA-512 DRBG is enabled (not disabled)

Example

if (wc_Sha512Drbg_IsDisabled()) {
    printf("SHA-512 DRBG is off\n");
}

function wc_InitRng_ex2

int wc_InitRng_ex2(
    WC_RNG * rng,
    void * heap,
    int devId,
    word32 flags
)

Initialize a WC_RNG with instantiation-time security attributes. Identical to wc_InitRng_ex(), with a flags argument fixing attributes at birth: WC_RNG_INIT_FLAG_LOCK_REQUIRED latches the sticky lock_required policy bit, so there is no reachable state in which the instance serves without its lock policy; WC_RNG_INIT_FLAG_LOCK_INITIALLY constructs into a held lease, to be released with wc_RNG_lock_put(); WC_RNG_INIT_FLAG_USE_FULL_MUTEX layers a blocking wolfSSL_Mutex outermost around the lock latch, for user_mode sharing of one instance among threads (requires WC_RNG_HAVE_LOCK_FULL_MUTEX).

Parameters:

  • rng The RNG object to initialize.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null, or the flags contradict each other, or WC_RNG_INIT_FLAG_TEST_USER_SEED with no user seed, or both DRBG flavor flags.
  • NOT_COMPILED_IN A requested flag is not compiled in, including a DRBG flavor flag for a flavor the build lacks.
  • BAD_STATE_E No DRBG flavor flag was given and the runtime setting has none enabled.
  • OBJECT_NOT_LOCKED_E WC_RNG_INIT_FLAG_PRESERVE_LOCK with WC_RNG_INIT_FLAG_LOCK_REQUIRED, but the lock is not held.
  • UNEXPECTED_STATE_E WC_RNG_INIT_FLAG_PRESERVE_LOCK, but the lock word's WC_RNG_LOCK_REQUIRED disagrees with the flags.

WC_RNG_INIT_FLAG_USE_AUTO_LOCK and WC_RNG_INIT_FLAG_NO_AUTO_LOCK decide, for this instance alone, whether the automatic per-call lock is created, whatever –enable-rng-autolock settled for the build. Use the first when the instance will be shared between threads: a build without that lock refuses with NOT_COMPILED_IN rather than returning an instance the caller would wrongly believe is serialized. Use the second to drop the per-call cost on an instance one thread owns; such an instance behaves as it does with the lock left out of the build, so sharing it between threads is a data race and, where the fork handlers exist, it is not fork covered. Setting both, or the first alongside WC_RNG_INIT_FLAG_USE_FULL_MUTEX, is BAD_FUNC_ARG in every build.

Naming neither leaves it to the build: on by default, or off where –disable-rng-autolock-default (WC_RNG_AUTO_LOCK_DEFAULT_OFF) built the lock in without switching it on. In such a build only the two flag forms, wc_InitRng_ex2() and wc_InitRngNonce_ex2(), can ask for the lock; wc_InitRng(), wc_InitRng_ex(), wc_rng_new() and wc_rng_new_ex() take no flags, so their instances go unlocked and cannot opt in.

By default nothing in the supplied WC_RNG is assumed valid: the arbitration words – the lock word and, with RBGC, the spawned-child reference count – are initialized along with the rest of the instance, so a first birth needs no preparation of the storage. WC_RNG_INIT_FLAG_PRESERVE_LOCK narrows that for an in-place reinitialization of an instance whose arbitration words are already live, and it is mandatory for one that other code can still reach – a bank slot, a registered instance, anything a lease-free invalidation walk can visit, any RBGC parent whose spawned children survive it – because reinitializing the words would erase a latch a walker may have set (or set between the teardown and the rebirth), or a reference a child will still release. The caller holds the lease (typically from wc_FreeRng_PreLocked(), which leaves it held), and both words are left exactly as found: the hold stays live across the initialization, for the holder's own wc_RNG_lock_put(), and the reference count still balances the children's eventual release (the STILL_REFERENCED_E teardown is the normal prelude). An inherited invalidation latch is the one exception: it is discharged by CAS at entry (the previous incarnation's obligation does not carry into a fresh seed), and if that CAS is aborted the call refuses with the lock's error, having altered nothing but the status. The flag requires self_consistency with the declared policy: with WC_RNG_INIT_FLAG_LOCK_REQUIRED, the word must be held (OBJECT_NOT_LOCKED_E otherwise) and must already carry WC_RNG_LOCK_REQUIRED (UNEXPECTED_STATE_E otherwise), and a word that carries it cannot be preserved without the flag (UNEXPECTED_STATE_E). Preserving contradicts constructing: WC_RNG_INIT_FLAG_LOCK_INITIALLY alongside it is BAD_FUNC_ARG, and so is WC_RNG_INIT_FLAG_USE_FULL_MUTEX, because the mutex would be born unlocked under a preserved hold and the holder's release would unlock a mutex it never took. The first birth of a reachable instance therefore uses WC_RNG_INIT_FLAG_LOCK_INITIALLY, and every later one WC_RNG_INIT_FLAG_PRESERVE_LOCK.

Three flags fix the instance's seeding posture rather than its locking. WC_RNG_INIT_FLAG_NO_PRIMARY_SEED forbids the module's primary seed source after instantiation: a reseed that would fall through to it is deferred and reported (NEEDS_RECOVERY_E) rather than drawn, for chain members that must stay chain-fed (see wc_RNG_DRBG_Reseed_Now()). WC_RNG_INIT_FLAG_UPGRADE_FROM_NEXT_SEED has each generate consume a banked next seed whenever that betters the instance's standing: recovery from a latched invalidation (any provenance beats a latched seed), or promotion of a chain_backed instance to a primary seed – the live seed becomes primary_sourced, and the stratum label follows only without WC_RNG_RBGC_STRATUM_IMMUTABLE (under it the label stays put, so the instance remains promotable and consumes primary seeds as fast as they are banked – the feeder sets the cadence). For externally_refreshed, long_lived instances, e.g. the kernel module's registered RBGC leaves. WC_RNG_INIT_FLAG_FAIL_FAST sets WC_RNG_FLAG_FAIL_FAST at birth: a generate that would otherwise reseed in_line reports instead – NOT_READY_E for an exhausted reseed budget, NEEDS_RECOVERY_E for a latched invalidation or a stale entropy epoch – leaving the DRBG in service, uncondemned, for an explicit reseed (the explicit reseed APIs are unaffected; see wc_RNG_SetFlags() for the runtime form). WC_RNG_INIT_FLAG_TEST_USER_SEED qualifies caller_supplied seed material only (see wc_InitRngNonce_UserSeed()); here, with none, it is refused.

Two flags fix the Hash_DRBG flavor for this instance: WC_RNG_INIT_FLAG_DRBG_SHA512 selects the SHA-512 DRBG (WOLFSSL_DRBG_SHA512) and WC_RNG_INIT_FLAG_DRBG_SHA256 the SHA-256 DRBG, each overriding the process-wide runtime setting for this instance alone, whatever any thread has done to the setting with wc_Sha256Drbg_Disable() or wc_Sha512Drbg_Disable(). Naming neither leaves the choice to that setting, exactly as every constructor did before these flags existed: SHA_512 where it is compiled in and enabled, SHA_256 otherwise, and BAD_STATE_E if nothing is enabled. The override reaches any compiled_in flavor, including one the setting has disabled – by a runtime call, or initially by WOLFSSL_NO_SHA256_DRBG, which starts SHA_256 disabled but still builds it. Naming both is BAD_FUNC_ARG, and naming a flavor the build lacks (NO_SHA256, or no WOLFSSL_DRBG_SHA512) is NOT_COMPILED_IN.

Example

WC_RNG rng;
if (wc_InitRng_ex2(&rng, NULL, INVALID_DEVID,
                   WC_RNG_INIT_FLAG_LOCK_REQUIRED |
                   WC_RNG_INIT_FLAG_LOCK_INITIALLY) != 0) {
    // error handling
}
// caller holds the lease from birth

function wc_InitRngNonce_ex2

int wc_InitRngNonce_ex2(
    WC_RNG * rng,
    const byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    void * heap,
    int devId,
    word32 flags
)

Initialize a WC_RNG with a caller-supplied nonce and instantiation-time security attributes. The nonce semantics are those of wc_InitRngNonce_ex(); the flags semantics are those of wc_InitRng_ex2().

Parameters:

  • rng The RNG object to initialize.
  • nonce Optional nonce used as additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.
  • perso Optional personalization string (may be null).
  • persoSz Length of perso in bytes.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.
  • NOT_COMPILED_IN A requested flag is not compiled in.

function wc_RNG_global_fallback_init

int wc_RNG_global_fallback_init(
    const byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    void * heap,
    int devId,
    word32 flags
)

Instantiate the module-wide fallback RNG from the module's primary seed source (WC_RNG_HAVE_GLOBAL_FALLBACK_RNG). The global fallback is a single, lock-disciplined (WC_RNG_INIT_FLAG_LOCK_REQUIRED), stratum-0 instance that serves as a reseed root of last resort: an RBG-chain member whose retained parent is unavailable reseeds from it on the PollAndReSeed() ladder (under FIPS only when it is a sibling of the parent, per the SP 800-90C closed list of alternative sources), and in the kernel module the entropy daemon keeps it fresh. It is never admitted as a spawn parent (see wc_InitRngNonceRBGC()). The call takes the instance's lock for the duration; _LOCK_REQUIRED and _LOCK_INITIALLY are implied and need not be passed.

Parameters:

  • nonce Optional nonce used as additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • perso Optional personalization string (may be null).
  • persoSz Length of perso in bytes.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes.

See:

Return:

  • 0 Success
  • ALREADY_E Already instantiated.
  • RNG_FAILURE_E, DRBG_CONT_FIPS_E The instance is condemned; release it with wc_RNG_global_fallback_free() before reinstantiating.
  • BUSY_E, BAD_MUTEX_E The instance's lock could not be taken.
  • Any error from wc_InitRngNonce_ex2().

function wc_RNG_global_fallback_init_user_seed

int wc_RNG_global_fallback_init_user_seed(
    const byte * seed,
    word32 seedSz,
    const byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    void * heap,
    int devId,
    word32 flags
)

The user-seeded form of wc_RNG_global_fallback_init(): the fallback is instantiated from caller_supplied material, with the provenance consequences of wc_InitRngNonce_UserSeed() (stratum WC_RNG_RBGC_USER_SEED_STRATUM, so under FIPS it cannot serve as an alternative source for any module_seeded chain member). For KAT harnesses and deterministic test rigs.

Parameters:

  • seed Caller-supplied seed material, credited in place of the module's seed source.
  • seedSz Length of seed in bytes; at least WC_DRBG_SEED_SZ (plus SEED_BLOCK_SZ under WC_RNG_INIT_FLAG_TEST_USER_SEED where the test block is excluded).
  • nonce Optional nonce used as additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • perso Optional personalization string (may be null).
  • persoSz Length of perso in bytes.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes.

See:

Return:

function wc_RNG_global_fallback_get

int wc_RNG_global_fallback_get(
    WC_RNG ** rng
)

Obtain a pointer to the global fallback RNG, for use as an explicit reseed root (wc_RNG_DRBG_ReseedRBGC(), the next-seed banker) or for maintenance by a daemon. No lock is taken: the instance is lock-required, so every operation on it goes through wc_RNG_lock_get()/wc_RNG_lock_put() as usual. The pointer is refused unless the instance is in service, which is only possible after a successful wc_RNG_global_fallback_init*().

Parameters:

  • rng Receives the instance pointer.

See:

Return:

  • 0 Success; *rng points at the instance.
  • BAD_FUNC_ARG rng is null.
  • NOT_READY_E, RNG_FAILURE_E, DRBG_CONT_FIPS_E The instance is not in service (as for wc_RNG_Status()).

function wc_RNG_global_fallback_free

int wc_RNG_global_fallback_free(
    void 
)

Tear down the global fallback RNG: wc_FreeRng() on the instance, with that function's contract – BUSY_E leaves it intact for a retry, STILL_REFERENCED_E means chain members still name it as a reseed root and its state has been zeroized. After a successful return it can be instantiated again.

See:

Return: As for wc_FreeRng().

function wc_InitRngNonce_UserSeed

int wc_InitRngNonce_UserSeed(
    WC_RNG * rng,
    const byte * seed,
    word32 seedSz,
    const byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    void * heap,
    int devId,
    word32 flags
)

Initialize a WC_RNG instantiated from caller-supplied seed material, used in place of the module's seed source, with an optional nonce and personalization string. Every other aspect of instantiation is wc_InitRngNonce_ex2()'s. The instance is born at the user_provenance stratum sentinel (WC_RNG_RBGC_USER_SEED_STRATUM).

Parameters:

  • rng The RNG object to initialize.
  • seed Caller-supplied seed material, credited in place of the module's seed source.
  • seedSz Length of seed in bytes; at least WC_DRBG_SEED_SZ (see BAD_LENGTH_E).
  • nonce Optional nonce used as additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • perso Optional personalization string (may be null).
  • persoSz Length of perso in bytes.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng or seed is null; or nonce or perso is null with its length nonzero; or the flags contradict each other.
  • BAD_LENGTH_E seedSz is below WC_DRBG_SEED_SZ (plus SEED_BLOCK_SZ under WC_RNG_INIT_FLAG_TEST_USER_SEED where the test block is excluded).
  • ENTROPY_RT_E / ENTROPY_APT_E WC_RNG_INIT_FLAG_TEST_USER_SEED, and the seed failed the repetition count / adaptive proportion test.
  • WRONG_TYPE_OBJECT_E The host bypasses the DRBG (RDRAND et al.), so there is nothing for the seed to feed; nothing is instantiated.
  • NOT_COMPILED_IN The build lacks WC_RNG_HAVE_RBGC, or a requested flag is not compiled in.

The instance's credited seeding is of unknown provenance, permanently distinguishing it from ESV-seeded lineage; when built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS) the marking is irrevocable. Under FIPS 140-3, seeding from caller material is not an approved entropy path; this function exists for KAT and ACVP-style harnesses that must inject fixed vectors, and for legacy interoperation. By default the seed is deliberately exempt from the FIPS 140-3 IG 10.3.A / SP 800-90B health tests applied to module-gathered seed material: wc_RNG_TestSeed() is not called on it, so fixed KAT vectors are not rejected as non_random; calling wc_RNG_TestSeed() beforehand is the caller's responsibility where vetting is wanted. WC_RNG_INIT_FLAG_TEST_USER_SEED reverses that: the material is then treated exactly as the module's own would be – health tested (ENTROPY_RT_E / ENTROPY_APT_E on failure), and laid out with its leading SEED_BLOCK_SZ bytes as the test block, which is checked but does not reach the DRBG (FIPS and non_FULL_SEED builds); see the instantiation_input paragraph below. A null seed is refused with BAD_FUNC_ARG, and an undersized seed (seedSz below WC_DRBG_SEED_SZ – plus SEED_BLOCK_SZ under WC_RNG_INIT_FLAG_TEST_USER_SEED where the test block is excluded – including zero) with BAD_LENGTH_E: an argument mistake must not mint a primary_class (stratum_0) instance the caller believes is user_seeded, and the DRBG's share must be whole. Builds without WC_RNG_HAVE_RBGC refuse with NOT_COMPILED_IN – the stratum bookkeeping that quarantines user provenance lives in the RBG_chain apparatus. A host whose instantiations bypass the DRBG (HAVE_INTEL_RDRAND on an RDRAND_capable CPU, where generation reads the instruction directly) refuses with WRONG_TYPE_OBJECT_E, the instance left uninstantiated: there is no DRBG for the material to feed, and a stratum_0 RDRAND instance must not be minted under a user_seeded name. wc_InitRng() and the other primary-seeded constructors remain available on such a host.

The exact instantiation input, for KAT harnesses: the Hash_DRBG entropy_input is seed truncated, or zero-padded, to WC_DRBG_SEED_SZ bytes when a nonce is supplied, and to WC_DRBG_SEED_SZ + WC_DRBG_SEED_SZ/2 bytes when nonceSz is 0 (the SP 800-90A entropy-plus-nonce form, the nonce half drawn from the same material); nonce (if any) and perso follow as for wc_InitRngNonce_ex2(). Material beyond that length is never consumed. (Non_FIPS builds with WOLFSSL_RNG_USE_FULL_SEED use WC_DRBG_SEED_SZ and WC_DRBG_MAX_SEED_SZ respectively.) Under WC_RNG_INIT_FLAG_TEST_USER_SEED there is no padding – the supplied length is the instantiation length – and the entropy_input is seed less its leading SEED_BLOCK_SZ bytes, capped at WC_DRBG_SEED_SZ bytes with a nonce and WC_DRBG_SEED_SZ + WC_DRBG_SEED_SZ/2 without (non_FIPS WOLFSSL_RNG_USE_FULL_SEED builds: the whole seed, test block included, capped at WC_DRBG_SEED_SZ and WC_DRBG_MAX_SEED_SZ).

Example

WC_RNG rng;
const byte katSeed[WC_DRBG_SEED_SZ] = { ... };
if (wc_InitRngNonce_UserSeed(&rng, katSeed, sizeof(katSeed),
                             NULL, 0, NULL, 0,
                             NULL, INVALID_DEVID,
                             WC_RNG_INIT_FLAG_NONE) != 0) {
    // error handling
}
// rng reports WC_RNG_RBGC_USER_SEED_STRATUM via
// wc_RNG_DRBG_GetRBGCStratum()

function wc_RNG_GetStatus

int wc_RNG_GetStatus(
    const WC_RNG * rng
)

Read-only accessor for the RNG health status. Returns the instance's enum wc_RngHealthState value (WC_DRBG_NOT_INIT, WC_DRBG_OK, WC_DRBG_FAILED, WC_DRBG_CONT_FAILED).

Parameters:

  • rng The RNG object to interrogate.

See: wc_RNG_DRBG_Present

Return:

  • WC_DRBG_OK The instance is in service.
  • BAD_FUNC_ARG rng is null.

Example

if (wc_RNG_GetStatus(&rng) != WC_DRBG_OK) {
    // instance is not serviceable
}

function wc_RNG_Status

int wc_RNG_Status(
    const WC_RNG * rng
)

The error-code form of wc_RNG_GetStatus(): 0 for an in_service instance, else the code its state maps to – so a caller can gate on an instance, or percolate its state, with one call and no enum switch. A pure status read: no lock is taken and nothing is propagated (contrast wc_RNG_entropy_needs_recovery(), which also delivers a pending epoch event and checks the reseed schedule).

Parameters:

  • rng The RNG object to interrogate.

See:

Return:

  • 0 In service (WC_DRBG_OK).
  • NOT_READY_E Not instantiated, or torn down by wc_FreeRng() (WC_DRBG_NOT_INIT).
  • RNG_FAILURE_E Condemned (WC_DRBG_FAILED): recovery is wc_FreeRng() then wc_InitRng*().
  • DRBG_CONT_FIPS_E Failed a continuous test (WC_DRBG_CONT_FAILED).
  • BAD_FUNC_ARG rng is null, or its state is not a known value.

function wc_RNG_DRBG_Present

int wc_RNG_DRBG_Present(
    const WC_RNG * rng
)

Returns 1 if rng has an instantiated DRBG, else 0. An in-service WC_RNG can lack one: instantiation bypasses the DRBG when the CPU has RDRAND (HAVE_INTEL_RDRAND). DRBG-specific services (commanded reseed, banked next seeds, RBG chains) are unavailable on such instances.

Parameters:

  • rng The RNG object to interrogate.

See:

Return:

  • 1 rng has a live DRBG.
  • 0 rng is null or has no DRBG.

function wc_RNG_DRBG_ScheduleReseed

int wc_RNG_DRBG_ScheduleReseed(
    WC_RNG * rng
)

Mark rng due for reseed: the next generate operation reseeds from the module's built-in or registered seed source before producing output. This can only shorten the current seed's remaining lifetime, never extend it.

Parameters:

  • rng The RNG object to schedule.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) reports success without action; wc_RNG_DRBG_Present() disambiguates.
  • BAD_FUNC_ARG rng is null.
  • BAD_MUTEX_E The rng's lock could not be taken.
  • NOT_READY_E, RNG_FAILURE_E, DRBG_CONT_FIPS_E rng is not in service (see wc_RNG_Status()).

function wc_RNG_DRBG_Reseed_Now

int wc_RNG_DRBG_Reseed_Now(
    WC_RNG * rng,
    const byte * nonce,
    word32 nonceSz
)

Immediately reseed rng from the module's built-in, registered, or associated seed source, with an optional nonce as additional input. The credited reseed resets the reseed counter.

Parameters:

  • rng The RNG object to reseed.
  • nonce Optional additional input.
  • nonceSz Length of nonce in bytes.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) reports success without action; wc_RNG_DRBG_Present() disambiguates.
  • BAD_FUNC_ARG rng is null, or nonce is null with nonceSz nonzero.
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • BAD_MUTEX_E The rng's lock could not be taken.
  • DRBG_CONT_FIPS_E The continuous test failed; the DRBG is out of service.
  • NOT_READY_E The reseed failed retryably with reseed runway remaining; the counter is not reset and the instance remains in service.
  • NEEDS_RECOVERY_E The reseed was deferred under WC_RNG_INIT_FLAG_NO_PRIMARY_SEED (no chain source was available) with reseed runway remaining; the obligation stands.
  • BUSY_E The seed source was contended and the caller cannot wait; retryable.
  • RNG_FAILURE_E The DRBG is out of service, or the reseed failed with no reseed runway remaining; the instance is condemned.
  • ENTROPY_RT_E or ENTROPY_APT_E The SP 800-90B seed health test rejected the gathered seed; the reseed did not happen and the instance remains usable until its reseed interval is reached.

For an SP 800-90C chain member (RBGC stratum > 0, in builds with instance locking), the seed source is found by a fallback ladder: the retained parent is tried first (nonblocking acquisition); if the parent is unavailable, the global fallback instance (under FIPS, only when it qualifies as a sibling of the parent – both primary-seeded); and only then the module's primary seed source – or, for an instance initialized with WC_RNG_INIT_FLAG_NO_PRIMARY_SEED, the reseed is deferred instead and the call reports the deferral. For a root (stratum 0), the module's seed source serves directly.

function wc_RNG_DRBG_Reseed_Now_Primary

int wc_RNG_DRBG_Reseed_Now_Primary(
    WC_RNG * rng,
    const byte * nonce,
    word32 nonceSz
)

The forced-primary form of wc_RNG_DRBG_Reseed_Now(): reseed rng directly from the module's primary (initial) randomness source, bypassing the chain fallback ladder, with an optional nonce as additional input. This is the SP 800_90A prediction_resistance primitive – a reseed from a live entropy source immediately ahead of generation – and is available to SP 800_90C chain members (RBGC stratum > 0) as well: the initial randomness source is on the SP 800-90C closed list of alternative sources, so the forced reseed is chain-conformant.

Parameters:

  • rng The RNG object to reseed; in builds with instance locking it must assert WC_RNG_LOCK_REQUIRED and be held by the caller.
  • nonce Optional additional input.
  • nonceSz Length of nonce in bytes.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null, or nonce is null with nonceSz nonzero.
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • WRONG_TYPE_OBJECT_E The instance does not assert WC_RNG_LOCK_REQUIRED (in builds with instance locking), or was initialized with WC_RNG_INIT_FLAG_NO_PRIMARY_SEED.
  • NOT_COMPILED_IN Multithreaded build without the locking facility.
  • BUSY_E The seed acquisition was refused in a non-blockable context; the instance remains in service.
  • NOT_READY_E, NEEDS_RECOVERY_E, RNG_FAILURE_E, DRBG_CONT_FIPS_E, ENTROPY_RT_E, ENTROPY_APT_E, BAD_MUTEX_E As for wc_RNG_DRBG_Reseed_Now(), including the no_op success for an instance with no DRBG (wc_RNG_DRBG_Present() disambiguates).

Prediction resistance is a property of an atomic reseed-then-generate sequence, not of the reseed alone, so in builds with instance locking the instance must assert WC_RNG_LOCK_REQUIRED and the caller must hold its lock: take the lock, call this function, call wc_RNG_GenerateBlock(), and only then release. Output generated outside that bracket carries no prediction_resistance claim. Multithreaded builds without the locking facility cannot provide the bracket (nor a safe flags update) and refuse with NOT_COMPILED_IN; single_threaded builds proceed, their atomicity being trivial. In WC_RNG_RBGC_STRATUM_IMMUTABLE builds (required for FIPS) the stratum label keeps its birth value – the label records the chain construction – while the live seed's provenance becomes primary; other builds relabel the instance stratum 0. The prediction_resistance claim follows the label, not the seed: SP 800_90C (Table 1) reserves prediction resistance to a DRBG whose entropy source is accessed directly, which an RBG_chain member (stratum > 0) by construction is not, so under WC_RNG_RBGC_STRATUM_IMMUTABLE a chain member's output after this call is a conformant reseed-from-the-initial-source but carries no prediction-resistance claim; only a stratum-0 instance's does. In relabeling builds the stratum-0 relabel is what the claim rides on. The call performs a full inline seed acquisition, which with a slow entropy source can take tens of milliseconds; in kernel builds a non-blockable calling context is refused with BUSY_E, leaving the instance unharmed and the call retryable from a blockable context.

Example

// prediction-resistant request: reseed and generate under one hold
ret = wc_RNG_lock_get(rng, 0);
if (ret == 0) {
    ret = wc_RNG_DRBG_Reseed_Now_Primary(rng, NULL, 0);
    if (ret == 0)
        ret = wc_RNG_GenerateBlock(rng, out_buf, out_len);
    (void)wc_RNG_lock_put(rng, 0);
}

function wc_RNG_DRBG_Reseed_Nonce

int wc_RNG_DRBG_Reseed_Nonce(
    WC_RNG * rng,
    const byte * seed,
    word32 seedSz,
    const byte * nonce,
    word32 nonceSz
)

Reseed rng's DRBG with caller-supplied seed material and an optional nonce as additional input, folded in a single derivation pass. The material is credited: the reseed counter resets.

Parameters:

  • rng The RNG object to reseed.
  • seed Seed material.
  • seedSz Length of seed in bytes.
  • nonce Optional additional input.
  • nonceSz Length of nonce in bytes.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) reports success without action; wc_RNG_DRBG_Present() disambiguates. (Refusals below take precedence.)
  • RNG_FAILURE_E rng is condemned (status DRBG_FAILED): a condemned instance does not accept a credited reseed; recover with wc_FreeRng() then wc_InitRng*(). Also, the reseed itself failed.
  • BAD_FUNC_ARG rng or seed is null, or nonce is null with nonceSz nonzero.
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • BAD_MUTEX_E the rng's lock could not be taken.
  • BAD_LENGTH_E seed is undersized while a reseed obligation stands.
  • WRONG_TYPE_OBJECT_E rng is below the user-provenance sentinel (every primary-seeded, chain-seeded, or RDRAND instance) and the build is WC_RNG_RBGC_STRATUM_IMMUTABLE.
  • NEEDS_RECOVERY_E The reseed succeeded, but a global entropy event (epoch increment or PID change) landed during it, so the obligation stands and the instance must not serve until recovered.

The single pass is one reseed operation over both inputs, not a reseed followed by a stir. For refusal, sizing, provenance-sentinel, and wc_RNG_TestSeed() semantics, see wc_RNG_DRBG_Reseed().

function wc_RNG_DRBG_Stir

int wc_RNG_DRBG_Stir(
    WC_RNG * rng,
    const byte * seed,
    word32 seedSz
)

Similar to wc_RNG_DRBG_Reseed(), except the caller-supplied material is mixed through the reseed derivation function without being credited as entropy: the reseed counter is not reset, so only the module's own seed source ever extends the instance's seed lifetime.

Parameters:

  • rng The RNG object to stir.
  • seed Material to mix in.
  • seedSz Length of seed in bytes.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) drops the material and reports success; wc_RNG_DRBG_Present() disambiguates.
  • BAD_FUNC_ARG rng or seed is null.
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • NEEDS_RECOVERY_E A recovery obligation stands (entropy invalidated, entropy epoch advanced, PID changed, or reseed due); recover with a credited reseed first.
  • NOT_READY_E The reseed interval was reached within the call: a stir is a generate, and is not the credited reseed that clears it.
  • RNG_FAILURE_E The instance is out of service (failed or continuous-test failed), has no DRBG and is not RDRAND, or the stir itself failed.
  • BAD_MUTEX_E The rng's lock could not be taken.

A standing recovery obligation refuses the stir: nothing mutates an entropy-invalidated or reseed-due DRBG except recovery. In builds with instance locking, the obligation check also delivers any pending global epoch event into the instance (see wc_RNG_entropy_needs_recovery()).

function wc_RNG_DRBG_Stir_Nonce

int wc_RNG_DRBG_Stir_Nonce(
    WC_RNG * rng,
    const byte * seed,
    word32 seedSz,
    const byte * nonce,
    word32 nonceSz
)

The nonce-bearing form of wc_RNG_DRBG_Stir(): the nonce is mixed in as a second, separate generate with additional input.

Parameters:

  • rng The RNG object to stir.
  • seed Material to mix in.
  • seedSz Length of seed in bytes.
  • nonce Optional additional input.
  • nonceSz Length of nonce in bytes.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) reports success without action; wc_RNG_DRBG_Present() disambiguates.
  • BAD_FUNC_ARG rng or seed is null, or nonce is null with nonceSz nonzero.
  • OBJECT_NOT_LOCKED_E, NEEDS_RECOVERY_E, NOT_READY_E, RNG_FAILURE_E, BAD_MUTEX_E As for wc_RNG_DRBG_Stir().

function wc_InitRngRBGC

int wc_InitRngRBGC(
    WC_RNG * child,
    WC_RNG * parent,
    word32 flags
)

Instantiate child as an SP 800-90C RBG-chain member subordinate to parent, drawing its seed material from parent's generate function in place of the module's seed source. Every other aspect of instantiation is wc_InitRng_ex2()'s. The child is tagged with stratum (parent's stratum + 1), and is relabeled at each credited reseed based on the seed source's stratum unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS); its claimable security strength is capped by parent's, and it has no prediction resistance. The caller must hold exclusive access to parent for the duration of the call; the spawn debits parent's reseed counter by one generate.

Parameters:

  • child The caller-provided WC_RNG to instantiate (uninitialized).
  • parent The chain parent to draw seed material from.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes for the child.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG child or parent is null, or child equals parent.
  • SEQ_OVERFLOW_E parent's stratum is at the representable maximum.

RNGs instantiated by [wc_InitRng()](group__Random.md#function-wc_initrng) or [wc_InitRng_ex2()](group__Random.md#function_wc_initrng_ex2) are root RNGs corresponding to SP 800_90C Sec. 7.2.1.1; RNGs instantiated by [wc_InitRngRBGC()](group__Random.md#function_wc_initrngrbgc) or [wc_InitRngNonceRBGC()](group__Random.md#function_wc_initrngnoncerbgc) from a root or from any deeper member correspond to the construction in Sec. 7.2.1.2.

Example

WC_RNG root, child;
wc_InitRng(&root);
if (wc_InitRngRBGC(&child, &root, WC_RNG_INIT_FLAG_NONE) == 0) {
    // child serves independently; release with wc_FreeRng(&child)
}

function wc_InitRngRBGC_New

int wc_InitRngRBGC_New(
    WC_RNG ** child,
    WC_RNG * parent,
    word32 flags
)

The allocating form of wc_InitRngRBGC(): the child is allocated from parent's heap and returned through child. Release with wc_rng_free(). For further details, see wc_InitRngRBGC().

Parameters:

  • child Receives the allocated, instantiated WC_RNG.
  • parent The chain parent to draw seed material from.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes for the child.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG child or parent is null.
  • MEMORY_E Allocation failed.
  • SEQ_OVERFLOW_E parent's stratum is at the representable maximum.

function wc_InitRngNonceRBGC_New

int wc_InitRngNonceRBGC_New(
    WC_RNG ** child,
    WC_RNG * parent,
    const byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    word32 flags
)

The allocating, nonce-bearing form of wc_InitRngRBGC(). For further details, see wc_InitRngRBGC() and wc_InitRngNonceRBGC().

Parameters:

  • child Receives the allocated, instantiated WC_RNG.
  • parent The chain parent to draw seed material from.
  • nonce Additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • perso Optional personalization string.
  • persoSz Length of perso in bytes.
  • flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes for the child.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG child or parent is null, or nonce (or perso) is null with its length nonzero.
  • MEMORY_E Allocation failed.
  • SEQ_OVERFLOW_E parent's stratum is at the representable maximum.

function wc_RNG_DRBG_ReseedRBGC

int wc_RNG_DRBG_ReseedRBGC(
    WC_RNG * rng,
    WC_RNG * root,
    const byte * nonce,
    word32 nonceSz
)

Reseed rng from root's generate output – the SP 800-90C chain reseed – with an optional nonce as additional input. The reseed is credited (the reseed counter resets); rng's stratum is updated to root's stratum + 1, unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS). The caller must hold exclusive access to both instances.

Parameters:

  • rng The chain member to reseed.
  • root The chain parent to draw seed material from.
  • nonce Optional additional input.
  • nonceSz Length of nonce in bytes.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) reports success without action; wc_RNG_DRBG_Present() disambiguates. (Refusals below take precedence.)
  • BAD_FUNC_ARG rng or root is null, rng equals root, nonce is null with nonceSz nonzero, or the no-downgrade rule refuses root as a chain parent (see
  • WRONG_TYPE_OBJECT_E rng is primary-class (stratum 0) and the build is WC_RNG_RBGC_STRATUM_IMMUTABLE, or (under FIPS) root is neither rng's retained parent nor a primary-seeded sibling of it (see
  • OBJECT_NOT_LOCKED_E rng or root requires its lock and the caller does not hold it.
  • SEQ_OVERFLOW_E root's stratum is at the representable maximum.
  • NEEDS_RECOVERY_E A global entropy event landed during the reseed, so rng's obligation stands; or delivery of a pending event into rng failed and rng was condemned (see wc_RNG_Status()).
  • RNG_FAILURE_E, DRBG_CONT_FIPS_E rng or root is out of service, or the reseed itself failed.
  • other Codes from root's generate (see wc_RNG_GenerateBlock()).

Credited chain reseeds obey a no-downgrade rule: a primary-seeded (stratum-0) root is always accepted, and a chained (stratum > 0) root is accepted only when its stratum is strictly less than rng's – with strata sticky from init, credited seed material can only flow rootward-to-leafward, so reseed cycles are impossible by construction, consistent with SP 800-90C 7.1.2.2. Lateral (equal-stratum) and downgrading reseeds are refused with BAD_FUNC_ARG. A successful credited reseed re-tags rng with the source's stratum plus one (or zero, for a primary source reseed) unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS). When built with WC_RNG_RBGC_STRATUM_IMMUTABLE, a credited chain reseed into a primary-class (stratum-0) target is refused with WRONG_TYPE_OBJECT_E – chain-fed state must never wear the primary-class label. Building WC_RNG_NO_RBGC_RESEED restricts credited chain reseeds to primary-seeded roots. Uncredited chain stirs (wc_RNG_DRBG_StirRBGC()) are exempt from all of this: they are stirs, claim nothing, and leave rng's stratum untouched.

This is the per-call form of chain maintenance: the root serves this one reseed and no relationship is retained, so it is the maintenance path for instances without a retained parent (including all instances in builds without instance locking) and the required path for externally orchestrated chains. The global fallback instance is a legitimate root for this call, though it is forbidden as a retained parent.

). ).

function wc_RNG_DRBG_StirRBGC

int wc_RNG_DRBG_StirRBGC(
    WC_RNG * rng,
    WC_RNG * root,
    const byte * nonce,
    word32 nonceSz
)

The uncredited form of wc_RNG_DRBG_ReseedRBGC(): material from root is mixed in without resetting rng's reseed counter.

Parameters:

  • rng The chain member to stir.
  • root The chain parent to draw material from.
  • nonce Optional additional input.
  • nonceSz Length of nonce in bytes.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) reports success without action; wc_RNG_DRBG_Present() disambiguates.
  • BAD_FUNC_ARG rng or root is null, rng equals root, or nonce is null with nonceSz nonzero.
  • OBJECT_NOT_LOCKED_E rng or root requires its lock and the caller does not hold it.
  • NEEDS_RECOVERY_E A recovery obligation stands on rng; see wc_RNG_DRBG_Stir().
  • NOT_READY_E, RNG_FAILURE_E As for wc_RNG_DRBG_Stir().
  • other Codes from root's generate (see wc_RNG_GenerateBlock()).

Unrestricted by the credited no-downgrade rule: any source stratum is accepted, and rng's reseed counter, stratum, and entropy-invalidated state are all left untouched – an uncredited chain reseed is a stir, and a stir must never masquerade as recovery or promotion. Conversely, a standing recovery obligation on rng refuses the stir outright (NEEDS_RECOVERY_E): nothing mutates an invalidated or reseed-due DRBG except recovery.

function wc_RNG_DRBG_GetRBGCStratum

int wc_RNG_DRBG_GetRBGCStratum(
    const WC_RNG * rng
)

Report rng's RBG-chain stratum: 0 for a root (never chain-seeded), n for a member seeded from a stratum-(n-1) parent. If built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS), the stratum is sticky for the instance's lifetime, even across subsequent source reseeds; otherwise it follows the stratum of the most recent credited seed source. A user-supplied reseed (wc_RNG_DRBG_Reseed()), where accepted, marks rng with WC_RNG_RBGC_USER_SEED_STRATUM regardless.

Parameters:

  • rng The RNG object to interrogate.

See:

Return:

  • 0 rng is a chain root.
  • n The stratum, positive for a chain member.
  • BAD_FUNC_ARG rng is null.

function wc_RNG_DRBG_GetNextSeedRBGCStratum

int wc_RNG_DRBG_GetNextSeedRBGCStratum(
    const WC_RNG * rng
)

Report the RBG-chain stratum of rng's banked next seed – race-free via the aperture protocol – for provenance-aware consumers.

Parameters:

  • rng The RNG object to interrogate.

See:

Return:

  • 0 The banked seed has root (source) provenance.
  • n The banked seed's stratum, positive for chain provenance.
  • BAD_FUNC_ARG rng is null.
  • WRONG_TYPE_OBJECT_E rng has no DRBG (RDRAND et al.).
  • RNG_FAILURE_E, DRBG_CONT_FIPS_E rng is out of service (see wc_RNG_Status()).
  • NOT_READY_E No banked seed is ready.

function wc_RNG_DRBG_NextSeedGenerate

int wc_RNG_DRBG_NextSeedGenerate(
    WC_RNG * rng,
    word32 n
)

Bank up to n more bytes of next-seed material, health-testing and publishing the bank when it completes. The fill is incremental and in-boundary; a scheduling daemon may call this without owning the instance – the single-writer fill and the atomic aperture hand-off make it safe alongside a concurrent consumer.

Parameters:

  • rng The RNG object whose bank to fill.
  • n Maximum bytes to bank this call (clamped to space remaining).

See:

Return:

  • 0 Bytes were banked (bank may or may not yet be complete).
  • ALREADY_E The bank is ready or being consumed.
  • BUSY_E A competing producer holds the fill claim, or the instance is between teardown and reinitialization; retryable on a later cycle.
  • NEEDS_RECOVERY_E The banked fill crossed a source invalidation event and was retired, or (under WC_RNG_INIT_FLAG_NO_PRIMARY_SEED) no chain source was available this cycle.
  • ENTROPY_RT_E or ENTROPY_APT_E The SP 800-90B seed health test rejected the banked material, which is burned.
  • BAD_FUNC_ARG rng is null or n is 0.
  • WRONG_TYPE_OBJECT_E rng has no DRBG (RDRAND et al.).

For an SP 800-90C chain member (RBGC stratum > 0, in builds with instance locking), the material is drawn by the same fallback ladder as wc_RNG_DRBG_Reseed_Now(): the retained parent first (nonblocking acquisition), then the global fallback instance (under FIPS, only when it qualifies as a sibling of the parent), then the module's primary seed source – skipped for an instance initialized with WC_RNG_INIT_FLAG_NO_PRIMARY_SEED. Chain_drawn material is banked with the source's stratum plus one, as by wc_RNG_DRBG_NextSeedGenerate_RBGC(). A fill whose source crossed an entropy_invalidation event mid_draw is retired (the bank is purged) rather than published. For a root (stratum 0), the module's seed source serves directly.

Example

// scheduling daemon: fill incrementally until published
int ret = wc_RNG_DRBG_NextSeedGenerate(rng, 16);
if (ret == ALREADY_E) {
    // bank is ready; nothing to do until a consumer claims it
}

function wc_RNG_DRBG_NextSeedGenerate_Primary

int wc_RNG_DRBG_NextSeedGenerate_Primary(
    WC_RNG * rng,
    word32 n
)

The forced-primary form of wc_RNG_DRBG_NextSeedGenerate(): the banked material is drawn directly from the module's primary (initial) randomness source, bypassing the chain fallback ladder, and the bank records stratum 0 (primary provenance), observable via wc_RNG_DRBG_GetNextSeedRBGCStratum(). On an SP 800_90C chain member, redemption of the primary_provenance bank is a promotion: the live seed becomes primary_sourced, and the stratum label follows unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS), whereby the birth label is kept while the live seed's provenance is primary. Like the ladder form, the fill is incremental and in-boundary, safe for a scheduling daemon alongside a concurrent consumer.

Parameters:

  • rng The RNG object whose bank to fill.
  • n Maximum bytes to bank this call (clamped to space remaining).

See:

Return:

  • 0 Bytes were banked (bank may or may not yet be complete).
  • ALREADY_E The bank is ready or being consumed.
  • BUSY_E A competing producer holds the fill claim, or (in kernel builds) the primary seed acquisition was refused in a non-blockable context; retryable.
  • NEEDS_RECOVERY_E The banked fill crossed a source invalidation event and was retired (the bank is purged).
  • WRONG_TYPE_OBJECT_E rng was initialized with WC_RNG_INIT_FLAG_NO_PRIMARY_SEED.
  • ENTROPY_RT_E or ENTROPY_APT_E The SP 800-90B seed health test rejected the banked material, which is burned.
  • BAD_FUNC_ARG rng is null or n is 0.
  • WRONG_TYPE_OBJECT_E rng has no DRBG (RDRAND et al.).

function wc_RNG_DRBG_NextSeedGenerate_RBGC

int wc_RNG_DRBG_NextSeedGenerate_RBGC(
    WC_RNG * rng,
    WC_RNG * root,
    word32 n
)

The chain-sourced form of wc_RNG_DRBG_NextSeedGenerate(): the banked material is drawn from root's generate function, and the bank is tagged with root's stratum plus one for provenance-aware consumption.

Parameters:

  • rng The RNG object whose bank to fill.
  • root The chain parent to draw material from.
  • n Maximum bytes to bank this call.

See:

Return:

  • 0 Bytes were banked.
  • ALREADY_E The bank is ready or being consumed.
  • ENTROPY_RT_E or ENTROPY_APT_E The SP 800-90B seed health test rejected the banked material, which is burned.
  • BAD_FUNC_ARG rng or root is null, or n is 0.
  • WRONG_TYPE_OBJECT_E rng has no DRBG (RDRAND et al.), or rng is primary-class (stratum 0) and the build is WC_RNG_RBGC_STRATUM_IMMUTABLE (see
  • SEQ_OVERFLOW_E root's stratum is at the representable maximum.

). Banking is bound for credited redemption, so the credited no-downgrade rule applies at bank time: a primary-seeded (stratum-0) root is always accepted, and a chained root only when its stratum is strictly less than rng's – banking whose redemption would raise rng's stratum is refused with BAD_FUNC_ARG. The banked material records root's stratum plus one, observable via wc_RNG_DRBG_GetNextSeedRBGCStratum(); redemption (wc_RNG_DRBG_NextSeedNow()) imparts the recorded stratum to the rng, unless built with WC_RNG_RBGC_STRATUM_IMMUTABLE (required for FIPS). When built with WC_RNG_RBGC_STRATUM_IMMUTABLE, chain banking into a primary_class (stratum_0) target is likewise refused, with WRONG_TYPE_OBJECT_E.

function wc_RNG_DRBG_NextSeedCurrent

int wc_RNG_DRBG_NextSeedCurrent(
    const WC_RNG * rng,
    WC_ATOMIC_INT_ARG * n
)

Report the raw next-seed aperture value: a non-negative banked byte count (filling, with no producer in flight), or one of the sentinels WC_DRBG_NEXT_SEED_PRODUCING (a producer holds the fill claim), WC_DRBG_NEXT_SEED_READY, WC_DRBG_NEXT_SEED_CONSUMING, WC_DRBG_NEXT_SEED_PURGED (an invalidation repainted a live claim; the holder reopens), or WC_DRBG_NEXT_SEED_TORNDOWN (the instance is between teardown and reinitialization, or has no DRBG). The snapshot is racy by design; use it for scheduling and diagnostics, not for hand-off decisions.

Parameters:

  • rng The RNG object to interrogate.
  • n Receives the aperture value.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng or n is null.

function wc_RNG_DRBG_NextSeedNow

int wc_RNG_DRBG_NextSeedNow(
    WC_RNG * rng
)

Claim a ready next-seed bank and perform a source-free credited reseed with it – safe in atomic context. The bank empties (use-once) and the reseed counter resets. The caller must own the instance.

Parameters:

  • rng The RNG object to reseed.

See:

Return:

  • 0 Success
  • NOT_READY_E No bank is ready.
  • NEEDS_RECOVERY_E A pending global epoch event was delivered into the instance (pre-event banked material purged, latch asserted); recover with a credited reseed, then re-bank. A bank found READY under an already-delivered latch is post-event and redeems normally – that redemption is the banked recovery path.
  • BAD_FUNC_ARG rng is null.
  • WRONG_TYPE_OBJECT_E rng has no DRBG (RDRAND et al.): its seed aperture never opens, so this is a refusal rather than a not-yet.
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • BAD_MUTEX_E The rng's lock could not be taken.
  • RNG_FAILURE_E The DRBG is out of service, or the reseed failed with no reseed runway remaining; the instance is condemned.
  • DRBG_CONT_FIPS_E The continuous test failed; the DRBG is out of service. (The banked material was health-tested at bank time, so ENTROPY_RT_E / ENTROPY_APT_E do not arise here.)

Example

// atomic-context consumer
if (wc_RNG_DRBG_NextSeedNow(rng) == 0) {
    // freshly reseeded without touching the seed source
}

function wc_RNG_DRBG_NextSeedNow_Nonce

int wc_RNG_DRBG_NextSeedNow_Nonce(
    WC_RNG * rng,
    const byte * nonce,
    word32 nonceSz
)

The nonce-bearing form of wc_RNG_DRBG_NextSeedNow(): the nonce is mixed in as uncredited additional input alongside the banked seed.

Parameters:

  • rng The RNG object to reseed.
  • nonce Additional input.
  • nonceSz Length of nonce in bytes.

See: wc_RNG_DRBG_NextSeedNow

Return:

  • 0 Success
  • NEEDS_RECOVERY_E Either a pending global epoch event was delivered before the claim (pre-event banked material purged, latch asserted – see wc_RNG_DRBG_NextSeedNow()), or a purge crossed the consume: no material is adopted, the entropy_invalidated latch is (re_)asserted, and a recovery reseed is scheduled.
  • NOT_READY_E No bank is ready, or the reseed failed retryably with reseed runway remaining.
  • BAD_FUNC_ARG rng is null, or nonce is null with nonceSz nonzero.
  • WRONG_TYPE_OBJECT_E, OBJECT_NOT_LOCKED_E, BAD_MUTEX_E, RNG_FAILURE_E, DRBG_CONT_FIPS_E As for wc_RNG_DRBG_NextSeedNow().

function wc_RNG_DRBG_NextStirStore

int wc_RNG_DRBG_NextStirStore(
    WC_RNG * rng,
    const byte * nonce,
    word32 nonceSz
)

Bank caller-supplied material (up to WC_RNG_NEXT_STIR_LEN bytes) in the uncredited accumulator beside the banked next seed. Writer-safe without a lease (read-copy-store); if the accumulator is already full, the material is absorbed by xor. Harvested entropy deposited here improves the instance without claiming credit.

Parameters:

  • rng The RNG object whose accumulator to feed.
  • nonce Material to bank.
  • nonceSz Length of nonce in bytes.

See:

Return:

  • 0 Success (an instance with no DRBG accumulates too; the stir that consumes it is then a no-op –wc_RNG_DRBG_Present() disambiguates).
  • BAD_FUNC_ARG rng or nonce is null, or nonceSz is 0.

function wc_RNG_DRBG_NextStirNow

int wc_RNG_DRBG_NextStirNow(
    WC_RNG * rng
)

Stir the banked uncredited accumulator into the DRBG as an uncredited, source-free mix-in – safe in atomic context; the reseed counter is not reset. The caller must own the instance.

Parameters:

  • rng The RNG object to stir.

See:

Return:

  • 0 Success – or no-op: an instance with no DRBG (RDRAND et al.) consumes and drops the accumulator; wc_RNG_DRBG_Present() disambiguates.
  • NOT_READY_E The accumulator is empty or still accumulating (also NOT_READY_E for an instance not yet initialized), or the reseed interval was reached within the call.
  • NEEDS_RECOVERY_E A recovery obligation stands (reseed due, entropy invalidated, entropy epoch advanced, or PID changed); nothing mutates a recovery-due DRBG except recovery. See wc_RNG_DRBG_Stir().
  • BUSY_E The accumulator was claimed by a racing consumer – the stir is happening by another hand – or the instance is between teardown and reinitialization.
  • BAD_FUNC_ARG rng is null.
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • BAD_MUTEX_E The rng's lock could not be taken.
  • DRBG_CONT_FIPS_E The instance failed a continuous test.
  • RNG_FAILURE_E The DRBG is out of service, has no DRBG and is not RDRAND, or its hash failed mid-stir; the accumulator is consumed either way (use-once).

function wc_RNG_lock_get

int wc_RNG_lock_get(
    WC_RNG * rng,
    WC_RNG_lock_arg_t extra_bits
)

Acquire rng's exclusive-ownership lock latch, spinning on the CAS until acquired, and or the caller's extra bits into the lock word. On an instance without the lock-required policy the call is a successful no-op unless extra bits are supplied.

Parameters:

  • rng The RNG object to lock.
  • extra_bits Caller-defined bits (above WC_RNG_LOCK_EXTRA_SHIFT) to set atomically with the acquisition, or 0.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.
  • BUSY_E The lock is held.
  • NEEDS_RECOVERY_E The instance's entropy is invalidated (see wc_RNG_invalidate_entropy()); recover with a credited reseed before use.
  • OBJECT_ORPHANED_E The lock is held by a lease from before a fork() (the word carries WC_RNG_LOCK_ORPHANED, or is stamped with another process's pid, in which case this call marks it and applies the invalidation). The holder is absent in this process – a thread of the parent, or the forking thread, which must neither use nor release a lease it held across the fork. Sticky until the instance's owner adopts the lease, with wc_FreeRng_PreLocked() and then wc_InitRng_ex2() with WC_RNG_INIT_FLAG_PRESERVE_LOCK; any other caller treats it as BUSY_E with no expectation that the hold will clear. (A post_fork acquirer that has not yet restamped the pid can draw the verdict too; its first use recovers inline and clears the mark, at no extra cost.) Never returned without getpid().
  • BAD_MUTEX_E (WC_RNG_HAVE_LOCK_FULL_MUTEX) The outer mutex failed.
  • UNEXPECTED_STATE_E Spurious acquisition failure; retry.

Example

if (wc_RNG_lock_get(rng, 0) == 0) {
    ret = wc_RNG_GenerateBlock(rng, out, sizeof(out));
    wc_RNG_lock_put(rng, 0);
}

function wc_RNG_lock_get_conditional

int wc_RNG_lock_get_conditional(
    WC_RNG * rng,
    WC_RNG_lock_arg_t expected_extra_bits,
    WC_RNG_lock_arg_t want_extra_bits
)

The conditional form of wc_RNG_lock_get(): acquire only if the current extra bits equal expected_extra_bits, atomically replacing them with want_extra_bits on success. Non-blocking with respect to the condition: a mismatch fails immediately rather than spinning.

Parameters:

  • rng The RNG object to lock.
  • expected_extra_bits The extra bits required for acquisition.
  • want_extra_bits The extra bits to install on acquisition.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.
  • BUSY_E The lock is held, or the extra bits do not match
  • OBJECT_ORPHANED_E As for wc_RNG_lock_get(). expected_extra_bits.
  • NEEDS_RECOVERY_E Entropy-invalidated and WC_RNG_LOCK_ENTROPY_INVALIDATED is not in expected_extra_bits.
  • BAD_MUTEX_E (WC_RNG_HAVE_LOCK_FULL_MUTEX) The outer mutex failed.
  • UNEXPECTED_STATE_E Spurious acquisition failure; retry.

function wc_RNG_lock_put

int wc_RNG_lock_put(
    WC_RNG * rng,
    WC_RNG_lock_arg_t extra_bits
)

Release rng's lock latch, clearing the supplied extra bits atomically with the release.

Parameters:

  • rng The RNG object to unlock.
  • extra_bits Caller-defined bits to clear with the release, or 0.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.
  • OBJECT_NOT_LOCKED_E The latch is not held.
  • NEEDS_RECOVERY_E Released successfully; informational notice that the instance is entropy-invalidated, or that a global entropy epoch increment has not yet been delivered into it – either way, the operation just completed may have straddled the event.

function wc_RNG_lock_put_conditional

int wc_RNG_lock_put_conditional(
    WC_RNG * rng,
    WC_RNG_lock_arg_t expected_extra_bits,
    WC_RNG_lock_arg_t want_extra_bits
)

The conditional form of wc_RNG_lock_put(): release only if the current extra bits equal expected_extra_bits, atomically replacing them with want_extra_bits on success.

Parameters:

  • rng The RNG object to unlock.
  • expected_extra_bits The extra bits required for release.
  • want_extra_bits The extra bits to install on release.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.
  • OBJECT_NOT_LOCKED_E The latch is not held.
  • NEEDS_RECOVERY_E Released successfully; informational notice as for wc_RNG_lock_put().
  • UNEXPECTED_STATE_E The extra bits (or WC_RNG_LOCK_REQUIRED) did not match expected_extra_bits; the caller still holds the lease, at both layers. Changes to the transient latch bits alone never cause this.

function wc_RNG_lock_read

int wc_RNG_lock_read(
    const WC_RNG * rng,
    WC_RNG_lock_arg_t * state
)

Read rng's lock word: the held/required latch bits, the entropy-invalidated bit, and any caller extra bits. The snapshot is racy by design.

Parameters:

  • rng The RNG object to interrogate.
  • state Receives the lock word.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng or state is null.

function wc_RNG_lock_set_extra

int wc_RNG_lock_set_extra(
    WC_RNG * rng,
    WC_RNG_lock_arg_t extra_bits
)

Atomically set (or) the supplied caller extra bits in rng's lock word. The caller should hold the latch.

Parameters:

  • rng The RNG object to modify.
  • extra_bits The bits to set.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.

function wc_RNG_lock_add_extra

int wc_RNG_lock_add_extra(
    WC_RNG * rng,
    WC_RNG_lock_arg_t extra_bits
)

Atomically add the supplied value to the caller extra-bits field of rng's lock word – for counters carried above WC_RNG_LOCK_EXTRA_SHIFT.

Parameters:

  • rng The RNG object to modify.
  • extra_bits The value to add.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.

function wc_RNG_lock_clear_extra

int wc_RNG_lock_clear_extra(
    WC_RNG * rng,
    WC_RNG_lock_arg_t extra_bits
)

Atomically clear the supplied caller extra bits in rng's lock word.

Parameters:

  • rng The RNG object to modify.
  • extra_bits The bits to clear.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.

function wc_RNG_invalidate_entropy

int wc_RNG_invalidate_entropy(
    WC_RNG * rng
)

Mark rng's seed material untrusted – for VM fork/resume and similar duplication events: banked and pooled pre-event material is purged and wiped, and then (in builds with instance locking) the entropy-invalidated bit is latched in the lock word, stamping the instance with the delivered entropy epoch and PID so one global event delivers once; in builds without instance locking the reseed schedule is saturated instead, as the only mark available. An invalidated instance refuses service (NEEDS_RECOVERY_E) until recovery-reseeded. Callable without owning the instance.

Parameters:

  • rng The RNG object to invalidate.

See:

Return:

  • 0 Success: purges complete, latch asserted (where built).
  • BAD_FUNC_ARG rng is null.
  • RNG_FAILURE_E (or other nonzero) A purge or the latch failed; the latch disposition is as described in

Latch or condemn: if the latch itself cannot be asserted, the instance is condemned (status DRBG_FAILED) – the latch is the only race-free quarantine mark, so its failure has no softer disposition. A nonzero return from a purge step leaves the latch asserted and the instance quarantined, not condemned. In builds without instance locking there is no latch; delivery is the purges plus the saturated reseed schedule, which the next generate honors. A condemned bank instance is retired and recovered by the entropy daemon; a condemned leaf gets no daemon rescue – its owner sees RNG_FAILURE_E from subsequent operations and recovers it with wc_FreeRng() then wc_InitRng*().

Example

// VM-resume handler
(void)wc_RNG_invalidate_entropy(rng);
// subsequent wc_RNG_lock_get() returns NEEDS_RECOVERY_E until recovery

function wc_RNG_register_free_hook

int wc_RNG_register_free_hook(
    WC_RNG * rng,
    wc_RNG_free_hook_cb_t free_hook,
    void * arg
)

Register a callback fired by wc_FreeRng() at teardown – for external registries (e.g. a kernel_module registry that must reach every live RNG on a VM duplication event) that need to drop their reference when the object dies.

Parameters:

  • rng The RNG object to hook.
  • free_hook The callback; NULL unregisters.
  • arg Opaque argument passed to the callback.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null.

function wc_RNG_SetFlags

int wc_RNG_SetFlags(
    WC_RNG * rng,
    word32 flags
)

Set runtime policy flags on an instantiated RNG. Only the bits in WC_RNG_FLAGS_SETTABLE may be set this way (WC_RNG_FLAG_FAIL_FAST, WC_RNG_FLAG_ONLY_PRIMARY_SEED, WC_RNG_FLAG_NO_PRIMARY_SEED); the rest are structural, fixed by instantiation or by the module, and are refused. A flag change is a read-modify-write of the instance, so it requires exclusive ownership: in WC_RNG_HAVE_LOCK builds the instance must have been instantiated with WC_RNG_INIT_FLAG_LOCK_REQUIRED and the caller must hold its lease; otherwise only SINGLE_THREADED builds support it. WC_RNG_FLAG_FAIL_FAST makes a generate that would otherwise reseed in-line report instead – NOT_READY_E for an exhausted reseed budget, NEEDS_RECOVERY_E for entropy invalidation – leaving the DRBG in service; explicit reseed APIs are unaffected. The same policy can be fixed at instantiation with WC_RNG_INIT_FLAG_FAIL_FAST.

Parameters:

  • rng The RNG object.
  • flags The bits to set.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null, flags is 0 or includes a bit that is not settable, or flags would combine WC_RNG_FLAG_NO_PRIMARY_SEED with WC_RNG_FLAG_ONLY_PRIMARY_SEED.
  • OBJECT_NOT_LOCKED_E rng requires a lease and the caller holds none.
  • WRONG_TYPE_OBJECT_E rng is not lock-required (WC_RNG_HAVE_LOCK).
  • NOT_COMPILED_IN No exclusivity facility (multithreaded build without WC_RNG_HAVE_LOCK), or WC_RNG_FLAG_NO_PRIMARY_SEED without WC_RNG_HAVE_RBGC.
  • MISSING_RNG_E WC_RNG_FLAG_NO_PRIMARY_SEED on an instance with no chain parent to defer to.

function wc_RNG_ClearFlags

int wc_RNG_ClearFlags(
    WC_RNG * rng,
    word32 flags
)

Clear runtime policy flags on an instantiated RNG. Only the bits in WC_RNG_FLAGS_CLEARABLE may be cleared (WC_RNG_FLAG_FAIL_FAST, WC_RNG_FLAG_ONLY_PRIMARY_SEED); WC_RNG_FLAG_NO_PRIMARY_SEED is set-only, since under FIPS it is a provenance commitment. Same ownership precondition as wc_RNG_SetFlags().

Parameters:

  • rng The RNG object.
  • flags The bits to clear.

See: wc_RNG_SetFlags

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null, flags is 0 or includes a bit that is not clearable.
  • OBJECT_NOT_LOCKED_E rng requires a lease and the caller holds none.
  • WRONG_TYPE_OBJECT_E rng is not lock-required (WC_RNG_HAVE_LOCK).
  • NOT_COMPILED_IN No exclusivity facility.

function wc_RNG_GetFlags

int wc_RNG_GetFlags(
    const WC_RNG * rng,
    word32 * flags
)

Read an instance's runtime flags (WC_RNG_FLAG_*) – the read-only companion of wc_RNG_SetFlags()/wc_RNG_ClearFlags(), so an application can establish an instance's posture (seed_source policy, fail_fast, chain and lock discipline, bank_reference shell) without reaching into the object. A plain load with no ownership precondition, like wc_RNG_Status(): authoritative when the caller holds the instance's lease, otherwise a snapshot. A WC_RNG_FLAG_BANKREF shell reports its own flags, not those of the bank instance a draw through it would resolve to.

Parameters:

  • rng The RNG object to interrogate.
  • flags Receives the flags.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng or flags is null.

function wc_RNG_Pool_Alloc

int wc_RNG_Pool_Alloc(
    WC_RNG * rng,
    word32 size
)

Attach a random pool to rng: a buffer of size bytes of pre-generated output, filled by wc_RNG_Pool_Collect() and drained atomic-context-safely by wc_RNG_Pool_Extract(). The pool is released only by wc_FreeRng(), and an instance reinstantiated through wc_FreeRng() comes back poolless, so a collector re_equips it by calling this again – the call is idempotent (ALREADY_E on a live ring) and needs no lease: the ring's lifecycle is arbitrated by an atomic aperture word, so it is safe against a concurrent wc_FreeRng() or wc_RNG_Pool_Collect2() on the same instance.

Parameters:

  • rng The RNG object to equip.
  • size Pool capacity in bytes.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null, or size is less than 2 or greater than 32767.
  • MEMORY_E Allocation failed.
  • ALREADY_E A pool is already attached (or being attached, or a collector is active on it).
  • BAD_STATE_E The pool was released by wc_FreeRng() and the instance has not been reinstantiated since.

Example

wc_RNG_Pool_Alloc(rng, 256);
wc_RNG_Pool_Collect(rng, 256);      // sleepable context
word32 n = 16;
if (wc_RNG_Pool_Extract(rng, out, &n) == 0) {
    // n bytes delivered, atomic-context-safe
}

function wc_RNG_Pool_Collect

int wc_RNG_Pool_Collect(
    WC_RNG * rng,
    word32 n
)

Generate up to n bytes into rng's pool from rng itself. Equivalent to wc_RNG_Pool_Collect2(rng, rng, n); see there for the contract.

Parameters:

  • rng The RNG object whose pool to fill.
  • n Maximum bytes to collect this call.

See:

Return:

  • 0 Success, including the no-op cases: n is 0, or the pool is already full.
  • BAD_FUNC_ARG rng is null.
  • BAD_STATE_E No pool is attached.
  • OBJECT_NOT_LOCKED_E rng requires a lease and the caller holds none.
  • BUSY_E Another collector holds the ring, or a purge landed during the generate.
  • NOT_READY_E A purge is pending the reader's acknowledgement (its next wc_RNG_Pool_Extract()), or the instance's own reseed budget is exhausted (this call never reseeds its source; see wc_RNG_Pool_Collect2()).
  • NEEDS_RECOVERY_E The instance requires entropy recovery.

function wc_RNG_Pool_Collect2

int wc_RNG_Pool_Collect2(
    WC_RNG * rng_dest,
    WC_RNG * rng_src,
    word32 n
)

The two-instance form of wc_RNG_Pool_Collect(): fill rng_dest's pool with output drawn from rng_src – so a service instance's pool can be topped up by a daemon_owned generator. No lease on rng_dest is needed: the collector claims the ring through its atomic aperture word for the duration of the generate (collectors are mutually exclusive; a second one gets BUSY_E at once), and the claim is what makes a concurrent wc_FreeRng() on rng_dest refuse with BUSY_E rather than free a buffer being written. The generate runs with WC_RNG_FLAG_FAIL_FAST on rng_src (set transiently if rng_src does not carry it), so the claim is held for one bounded generate and never across an in_line reseed: this call never reseeds its source, and a source whose budget is exhausted or which requires recovery is reported, not serviced – source upkeep belongs to the source's owner. On a lock_required rng_src the caller must hold its lease. Under WC_RNG_HAVE_RBGC, rng_src may not sit deeper in the RBG chain than rng_dest (SP 800_90C sect. 7.3.1 item 16). In FIPS builds the eligibility rule is narrower still: rng_src must be rng_dest itself, or (under WC_RNG_HAVE_RBGC) rng_dest's direct RBGC parent – the two relationships under which rng_src's output is already sanctioned to reach rng_dest. Any other source is refused with WRONG_TYPE_OBJECT_E before any other processing, the n = 0 no-op included.

Parameters:

  • rng_dest The RNG object whose pool to fill.
  • rng_src The RNG object to draw output from.
  • n Maximum bytes to collect this call.

See: wc_RNG_Pool_Collect

Return:

  • 0 Success, including the no-op cases: n is 0, or the pool is already full.
  • BAD_FUNC_ARG rng_dest or rng_src is null, or rng_src's RBGC stratum is deeper than rng_dest's.
  • WRONG_TYPE_OBJECT_E In FIPS builds, rng_src is neither rng_dest nor rng_dest's direct RBGC parent (a source-eligibility refusal, as distinct from the stratum gate's BAD_FUNC_ARG).
  • BAD_STATE_E rng_dest has no pool attached.
  • OBJECT_NOT_LOCKED_E rng_src requires a lease and the caller holds none.
  • BUSY_E Another collector (or an allocator) holds the ring, or a purge landed during the generate.
  • NOT_READY_E A purge is pending the reader's acknowledgement (its next wc_RNG_Pool_Extract()), or rng_src's reseed budget is exhausted.
  • NEEDS_RECOVERY_E rng_src requires entropy recovery.
  • Any other error from wc_RNG_GenerateBlock() on rng_src.

function wc_RNG_Pool_Extract

int wc_RNG_Pool_Extract(
    WC_RNG * rng,
    byte * out,
    word32 * n
)

Drain up to n bytes from rng's pool into out – atomic-context-safe. On success n reports the bytes actually delivered; on any error return *n is left unmodified.

Parameters:

  • rng The RNG object whose pool to drain.
  • out Receives the output.
  • n In: bytes requested; out: bytes delivered.

See:

Return:

  • 0 Success
  • NOT_READY_E The pool is empty or being filled.
  • NEEDS_RECOVERY_E A pending global epoch event was delivered into the instance before serving: pre-event pooled output is purged, and the instance requires a credited reseed before further service.
  • BAD_FUNC_ARG rng, out, or n is null.
  • OBJECT_NOT_LOCKED_E The instance requires its lock and the caller does not hold it.
  • BAD_STATE_E The pool is not allocated, or is being allocated, purged, or torn down.
  • BUSY_E A purge landed during the read (the pool epoch moved): the bytes read predate the event and are discarded; retryable.
  • RNG_FAILURE_E The instance is out of service: its pooled output is purged and wiped (fail closed), and nothing is delivered.

function wc_RNG_Pool_Current

int wc_RNG_Pool_Current(
    const WC_RNG * rng,
    word32 * n
)

Report the pool's current fill in bytes (0 when rng has no pool, or a purge is pending the reader's acknowledgement). The snapshot is racy by design, and needs no lease.

Parameters:

  • rng The RNG object to interrogate.
  • n Receives the fill.

See: wc_RNG_Pool_Extract

Return:

  • 0 Success
  • BAD_FUNC_ARG rng or n is null.

function wc_rng_debug_stats_snap

int wc_rng_debug_stats_snap(
    struct wc_rng_debug_stats_snapshot * s,
    const WC_RNG * rng
)

Snapshot rng's debug counters (WC_RNG_DEBUG_STATS) – seeds and reseeds by provenance, generates, lock traffic, pool and bank traffic – into s, for later delta accounting with wc_rng_debug_stats_sum(). The counters are per instance.

Parameters:

  • s Receives the snapshot.
  • rng The instance whose counters to snapshot.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG s or rng is null.

function wc_rng_debug_stats_restore

int wc_rng_debug_stats_restore(
    const struct wc_rng_debug_stats_snapshot * s,
    WC_RNG * rng
)

Restore rng's debug counters from a snapshot – so a test can unwind its own accounting.

Parameters:

  • s The snapshot to restore from.
  • rng The instance whose counters to restore.

See: wc_rng_debug_stats_snap

Return:

  • 0 Success
  • BAD_FUNC_ARG s or rng is null.

function wc_rng_debug_stats_sum

int wc_rng_debug_stats_sum(
    struct wc_rng_debug_stats_snapshot * s,
    const WC_RNG * rng
)

Accumulate rng's current debug counters into s – combined with a prior wc_rng_debug_stats_snap(), a delta accounting of the interval's activity, or across instances, a bank-wide total.

Parameters:

  • s The snapshot to accumulate into.
  • rng The instance whose counters to add.

See: wc_rng_debug_stats_snap

Return:

  • 0 Success
  • BAD_FUNC_ARG s or rng is null.

function wc_RNG_global_invalidate_entropy

WC_ATOMIC_UINT_ARG wc_RNG_global_invalidate_entropy(
    void 
)

Advances the process-global entropy epoch, marking every RNG instance's entropy as predating the current environment.

See:

Return: The new (post-increment) global entropy epoch.

The broadcast half of entropy invalidation, for events that invalidate all accumulated entropy at once (a VM fork or resume, a snapshot restore). Each instance captures the global epoch when it acquires seed material; after the epoch advances, every instance reports NEEDS_RECOVERY_E from wc_RNG_entropy_needs_recovery() until its next credited reseed, which wc_RNG_GenerateBlock() performs inline on its next call. The pending event is delivered into each instance – purging its banked and pooled pre_event material via wc_RNG_invalidate_entropy()– at the instance's next detection point: a generate, a recovery query, a banked-seed redemption, or a pool extraction. The call is lock-free and safe from any context that may call the atomic-increment primitive.

function wc_RNG_get_global_entropy_epoch

WC_ATOMIC_UINT_ARG wc_RNG_get_global_entropy_epoch(
    void 
)

Read the process-global entropy epoch: the count of wc_RNG_global_invalidate_entropy() events so far. An instance whose stamp differs from this value has an undelivered event pending (see wc_RNG_entropy_needs_recovery(), which delivers it). A relaxed snapshot, for diagnostics and for callers that want to notice an event without touching any instance; nothing is propagated.

See:

Return: The current global epoch.

function wc_InitRngNonceRBGC

int wc_InitRngNonceRBGC(
    WC_RNG * child,
    WC_RNG * parent,
    const byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    word32 flags
)

Initializes an RNG instance seeded from a parent RNG, as an SP 800-90C RBG chain member, with an optional nonce and personalization string.

Parameters:

  • child the instance to initialize
  • parent the seed-source instance
  • nonce optional nonce buffer, NULL if unused
  • nonceSz length of nonce in bytes
  • perso optional personalization string, NULL if unused
  • persoSz length of perso in bytes
  • flags WC_RNG_INIT_FLAG_* values for the child; not inherited from the parent

See:

Return:

  • 0 on success
  • BAD_FUNC_ARG a pointer argument is invalid, or parent is the global fallback instance
  • WRONG_TYPE_OBJECT_E under FIPS, parent is not a lock-disciplined instance
  • SEQ_OVERFLOW_E the parent's stratum cannot be incremented

The child is labeled with the parent's RBGC stratum plus one, recording its chain provenance. In builds with instance locking, when the parent is a lock-disciplined instance (initialized with WC_RNG_INIT_FLAG_LOCK_REQUIRED) and the caller holds the parent's lock across the call, the child retains the parent for the instance's lifetime and reseeds from it automatically; the parent cannot complete teardown while retaining children (see wc_FreeRng()). Otherwise the seeding is a one_time pull: the child is born chain_fed and correctly labeled, and ongoing chain maintenance – scheduling credited reseeds against an appropriate root with wc_RNG_DRBG_ReseedRBGC()– is the caller's responsibility. Instances created by the wc_rng_new*() family are never retained as parents: their void destructor cannot report a still-pinned shell, so retention from them degrades to the one-time pull. Under FIPS the retained relationship is required, not optional: the parent must be lock-disciplined and retainable, and a spawn from any other instance is refused. The global fallback instance is forbidden as a parent in all configurations; its role as an explicit reseed root is unaffected.

function wc_RNG_entropy_needs_recovery

int wc_RNG_entropy_needs_recovery(
    WC_RNG * rng
)

Reports whether an RNG instance has a standing obligation to acquire fresh entropy before further use.

Parameters:

  • rng the instance to query

See:

Return:

  • 0 no recovery is needed
  • NEEDS_RECOVERY_E a credited reseed is required before the next generate (wc_RNG_GenerateBlock() performs this recovery inline)
  • BAD_FUNC_ARG rng is NULL
  • RNG_FAILURE_E the instance is in a failed state
  • DRBG_CONT_FIPS_E the instance failed a continuous test

Checks the instance's health, its entropy epoch against the process-global epoch (see wc_RNG_global_invalidate_entropy()), its stamped PID against the process's (a fork is an entropy event), its entropy_invalidation latch, and its reseed schedule. Detection is also delivery: in builds with instance locking, a stale epoch or PID is propagated into the instance on the spot, via wc_RNG_invalidate_entropy()– pre_event banked and pooled material purged, latch asserted, epoch and PID stamped – so a nonzero verdict means the instance's apertures are already post_purge and the latch carries the recovery obligation from then on; without instance locking the mismatch is reported without delivery, and the next generate recovers inline (the other state_touching entry points deliver it themselves on entry). The result is an unlocked snapshot: callers that do not otherwise pin the instance (by lease, lock, or gate) must treat the verdict as advisory, and the operating APIs re-establish it authoritatively under the instance lock. An instance with no DRBG state, including one not yet initialized, vacuously needs no recovery.

function wc_rng_bank_new

int wc_rng_bank_new(
    struct wc_rng_bank ** ctx,
    int n_rngs,
    word32 flags,
    int timeout_secs,
    void * heap,
    int devId
)

Allocate and initialize a bank of n_rngs pre-instantiated WC_RNG instances, checked out and back in by consumers (wc_rng_bank_checkout() et al.). The bank is allocated from heap; release with wc_rng_bank_free(). Bank-level flags (WC_RNG_BANK_FLAG_*) fix the bank's posture at initialization: e.g. _CAN_WAIT admits sleeping, _QUIET suppresses seeding-degradation warnings, _NO_CHECKOUT_REFCOUNTING suppresses per-checkout refcount traffic for container-guaranteed lifetimes, _PREDICTION_RESISTANCE imposes a bank-wide fresh-reseed posture on every sleepable lease.

Parameters:

  • ctx Receives the allocated bank.
  • n_rngs Number of instances.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* bank-posture flags.
  • timeout_secs Seeding timeout budget.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG ctx is null or n_rngs is out of range.
  • MEMORY_E Allocation failed.
  • RNG_FAILURE_E No instance could be seeded within timeout_secs.

Example

struct wc_rng_bank *bank = NULL;
if (wc_rng_bank_new(&bank, 4, WC_RNG_BANK_FLAG_CAN_WAIT, 10,
                    NULL, INVALID_DEVID) == 0) {
    // ... checkout/checkin traffic ...
    wc_rng_bank_free(&bank);
}

function wc_rng_bank_init

int wc_rng_bank_init(
    struct wc_rng_bank * ctx,
    int n_rngs,
    word32 flags,
    int timeout_secs,
    void * heap,
    int devId
)

Initialize a caller-provided bank object. Semantics of wc_rng_bank_new(), without the allocation; release with wc_rng_bank_fini().

Parameters:

  • ctx The bank object to initialize.
  • n_rngs Number of instances.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* bank-posture flags.
  • timeout_secs Seeding timeout budget.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG ctx is null or n_rngs is out of range.
  • BAD_LENGTH_E n_rngs exceeds the static capacity (WC_RNG_BANK_STATIC builds).
  • RNG_FAILURE_E No instance could be seeded within timeout_secs.

function wc_rng_bank_init_nonce

int wc_rng_bank_init_nonce(
    struct wc_rng_bank * ctx,
    int n_rngs,
    word32 flags,
    int timeout_secs,
    void * heap,
    int devId,
    const byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz
)

The nonce-bearing form of wc_rng_bank_init(): the nonce is used as additional instantiation input for each instance.

Parameters:

  • ctx The bank object to initialize.
  • n_rngs Number of instances.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* bank-posture flags.
  • timeout_secs Seeding timeout budget.
  • heap Heap hint for dynamic allocation.
  • devId Device id, or INVALID_DEVID.
  • nonce Additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • perso Optional personalization string (may be null).
  • persoSz Length of perso in bytes.

See: wc_rng_bank_init

Return:

  • 0 Success
  • BAD_FUNC_ARG ctx is null, n_rngs is out of range, or nonce is null with nonceSz nonzero.
  • RNG_FAILURE_E No instance could be seeded within timeout_secs.
  • BAD_LENGTH_E nonceSz exceeds the supported maximum.
  • MEMORY_E Allocation failed.
  • WC_TIMEOUT_E Instance seeding exceeded timeout_secs.

function wc_rng_bank_first_failover_inst_set

int wc_rng_bank_first_failover_inst_set(
    struct wc_rng_bank * ctx,
    int first_failover_inst
)

Designate the first instance of the failover pool: checkouts without a targeted preference rotate through instances at and above first_failover_inst, reserving the lower offsets for targeted (affinity or daemon) use.

Parameters:

  • ctx The bank to configure.
  • first_failover_inst The first failover-eligible instance offset.

See: wc_rng_bank_checkout

Return:

  • 0 Success
  • BAD_FUNC_ARG ctx is null or first_failover_inst is out of range.

function wc_rng_bank_set_affinity_handlers

int wc_rng_bank_set_affinity_handlers(
    struct wc_rng_bank * ctx,
    wc_affinity_lock_fn_t affinity_lock_cb,
    wc_affinity_get_id_fn_t affinity_get_id_cb,
    wc_affinity_unlock_fn_t affinity_unlock_cb,
    void * cb_arg
)

Install affinity handlers: callbacks that pin the caller to an execution context (e.g. disable preemption or migration), report its id for instance affinity, and unpin. With handlers installed, WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST checkouts prefer the instance matching the caller's affinity id, and WC_RNG_BANK_FLAG_AFFINITY_LOCK holds the pin across the lease.

Parameters:

  • ctx The bank to configure.
  • affinity_lock_cb Pin the caller; may be null.
  • affinity_get_id_cb Report the caller's affinity id.
  • affinity_unlock_cb Unpin the caller; may be null.
  • cb_arg Opaque argument passed to the callbacks.

See: wc_rng_bank_checkout

Return:

  • 0 Success
  • BAD_FUNC_ARG ctx is null.
  • BUSY_E The bank is in service; handlers must be set before use.

function wc_rng_bank_fini

int wc_rng_bank_fini(
    struct wc_rng_bank * ctx
)

Tear down a bank initialized with wc_rng_bank_init(): once the refcount and per-instance lease gates pass, fires any registered free hook and frees every instance. Never waits: a referenced or leased bank is refused with BUSY_E, and the caller quiesces its consumers and retries.

Parameters:

  • ctx The bank to tear down.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG ctx is null.
  • BUSY_E The bank is still referenced, or an instance lease is outstanding.
  • BAD_STATE_E The refcount is below its initialization baseline (teardown of an uninitialized or corrupted bank).

function wc_rng_bank_free

int wc_rng_bank_free(
    struct wc_rng_bank ** ctx
)

Tear down and release a bank allocated with wc_rng_bank_new().

Parameters:

  • ctx The bank to release; nulled on success.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG ctx or *ctx is null.
  • BAD_STATE_E The bank is still referenced.

function wc_rng_bank_default_set

int wc_rng_bank_default_set(
    struct wc_rng_bank * bank
)

Register bank as the process-default bank, retrievable with wc_rng_bank_default_checkout().

Parameters:

  • bank The bank to register.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank is null.
  • BAD_STATE_E A default bank is already registered.
  • BUSY_E Registration is contended; retry.

function wc_rng_bank_default_checkout

int wc_rng_bank_default_checkout(
    struct wc_rng_bank ** bank
)

Take a reference on the process-default bank.

Parameters:

  • bank Receives the default bank.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank is null.
  • BAD_STATE_E No default bank is registered.
  • NO_DEFAULT_FOUND_E No default bank is registered.

function wc_rng_bank_default_checkin

int wc_rng_bank_default_checkin(
    struct wc_rng_bank ** bank
)

Release a reference taken with wc_rng_bank_default_checkout().

Parameters:

  • bank The reference to release; nulled on success.

See: wc_rng_bank_default_checkout

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or *bank is null.

function wc_rng_bank_default_clear

int wc_rng_bank_default_clear(
    struct wc_rng_bank * bank
)

Unregister the process-default bank.

Parameters:

  • bank The bank to unregister.

See: wc_rng_bank_default_set

Return:

  • 0 Success
  • BAD_FUNC_ARG bank is null or is not the registered default.
  • BUSY_E Unregistration is contended; retry.

function wc_rng_bank_checkout

int wc_rng_bank_checkout(
    struct wc_rng_bank * bank,
    struct wc_rng_bank_inst ** rng_inst,
    int preferred_inst_offset,
    int timeout_secs,
    word32 flags
)

Lease an in-service instance from the bank: either the preferred (or affinity-matched) instance, or – with WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST – the first available failover instance. On success the caller owns the instance's lock; access the WC_RNG with WC_RNG_BANK_INST_TO_RNG() and return the lease with wc_rng_bank_inst_checkin(). WC_RNG_BANK_FLAG_CONSUME_NEXT_SEED consumes a ready banked next seed in an immediate source-free credited reseed before returning; WC_RNG_BANK_FLAG_PREDICTION_RESISTANCE (per-call, requires _CAN_WAIT) freshly credited-reseeds the lease from the primary source (wc_RNG_DRBG_Reseed_Now_Primary()) before the caller's first draw. On a bank whose members are RBG_chain children of a root (WC_RNG_BANK_FLAG_RBGC) in a WC_RNG_RBGC_STRATUM_IMMUTABLE build, that reseed is conformant but the lease's output carries no SP 800_90C prediction_resistance claim – a chain member is not a DRBG with direct access to its entropy source (see wc_RNG_DRBG_Reseed_Now_Primary()).

Parameters:

  • bank The bank to lease from.
  • rng_inst Receives the leased instance.
  • preferred_inst_offset The preferred instance, or 0.
  • timeout_secs Wait budget (with _CAN_WAIT).
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* per-call flags.

See:

Return:

  • 0 Success; *rng_inst holds the lease.
  • BAD_FUNC_ARG bank or rng_inst is null, or the flags are contradictory.
  • NEEDS_RECOVERY_E Quarantined: refused without a lease (ordinary checkout), or lease held with recovery owed (_MAYBE_FOR_RECOVERY; see
  • BAD_STATE_E (_ERROR_ON_RNG_FAILED) only out-of-service instances were found.
  • WC_TIMEOUT_E The wait budget expired.
  • RNG_FAILURE_E No serviceable instance.
  • BAD_INDEX_E preferred_inst_offset is out of range.
  • BUSY_E The selected instance is contended (without _CAN_WAIT).

Out-of-service instances: a targeted (non-failover) checkout admits them; failover checkouts divert around them. WC_RNG_BANK_FLAG_FOR_RECOVERY makes the targeted admission explicit and interaction-safe (recovery machinery and patrols): out-of-service status is expected, the _CONSUME_NEXT_SEED arm is suppressed (a consume would fail on exactly the instances recovery targets), and failover and affinity selection are rejected in combination. WC_RNG_BANK_FLAG_ERROR_ON_RNG_FAILED gives the opposite guarantee: either a lease on an in-service instance, or an error with no lease – never a lease on an out-of-service instance; under _CAN_WAIT an out-of-service instance is retried within the timeout budget (allowing a patrol to restore it), and the distinguished error for a lap or wait that found only out-of-service instances is BAD_STATE_E.

Entropy-invalidated (quarantined) instances refuse ordinary leases with NEEDS_RECOVERY_E, with two admissions. First, when the quarantined instance holds a READY banked next seed, any claimant is admitted and the consume-at-checkout reseed runs unconditionally: the invalidation purge guarantees READY banked material post-dates the invalidation event, so admitting the claimant is completing the recovery. Second, WC_RNG_BANK_FLAG_MAYBE_FOR_RECOVERY admits the caller to a quarantined instance with no banked material, transferring the recovery obligation: checkout then returns NEEDS_RECOVERY_E with the checkout otherwise complete – *rng_inst set; instance lock, affinity locks, and any vector-inhibit state held. This is the robust-mutex (EOWNERDEAD) pattern: an error return with the acquisition complete and persistent, because "this resource needs consistency recovery" is only safely reportable to a caller that already holds it. The caller must either recover the instance (a credited reseed, e.g. wc_RNG_DRBG_Reseed_Now(), clears the quarantine) or check it back in. Ordinary consumers that cannot complete a recovery must not pass this flag.

). Example

struct wc_rng_bank_inst *inst = NULL;
if (wc_rng_bank_checkout(bank, &inst, 0, 10,
                         WC_RNG_BANK_FLAG_CAN_WAIT |
                         WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST) == 0) {
    ret = wc_RNG_GenerateBlock(WC_RNG_BANK_INST_TO_RNG(inst),
                               out, sizeof(out));
    wc_rng_bank_inst_checkin(&inst);
}

function wc_rng_bank_checkin

int wc_rng_bank_checkin(
    struct wc_rng_bank * bank,
    struct wc_rng_bank_inst ** rng_inst
)

Return a lease through the bank object, validating that rng_inst belongs to bank. Prefer wc_rng_bank_inst_checkin() when only the instance pointer is at hand.

Parameters:

  • bank The bank the instance belongs to.
  • rng_inst The lease to return; nulled on success.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or rng_inst is null, or the instance does not belong to bank.
  • OBJECT_NOT_LOCKED_E The instance's lease is not held (e.g. a stale duplicate check-in).
  • NEEDS_RECOVERY_E Checked in successfully; informational notice that the instance is entropy-invalidated.

function wc_rng_bank_inst_checkin

int wc_rng_bank_inst_checkin(
    struct wc_rng_bank_inst ** rng_inst
)

Return a lease by instance pointer alone.

Parameters:

  • rng_inst The lease to return; nulled on success.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG rng_inst or *rng_inst is null.
  • OBJECT_NOT_LOCKED_E The instance's lease is not held.
  • NEEDS_RECOVERY_E Checked in successfully; informational notice that the instance is entropy-invalidated.

function wc_rng_bank_get_inst_id

int wc_rng_bank_get_inst_id(
    struct wc_rng_bank_inst * rng_inst
)

Report the instance's offset within its bank.

Parameters:

  • rng_inst The instance to interrogate.

See: wc_rng_bank_checkout

Return:

  • n The instance offset, non-negative.
  • BAD_FUNC_ARG rng_inst is null.

function wc_rng_bank_next_seed_generate

int wc_rng_bank_next_seed_generate(
    struct wc_rng_bank * bank,
    int inst_offset,
    word32 n
)

Bank next-seed material for the instance at inst_offset –wc_RNG_DRBG_NextSeedGenerate() through the bank, without taking the instance lock; the daemon-side serialization word arbitrates against concurrent whole-instance reinitialization.

Parameters:

  • bank The bank.
  • inst_offset The instance to bank for.
  • n Maximum bytes to bank this call.

See:

Return:

  • 0 Bytes were banked.
  • ALREADY_E The instance's bank is ready or being consumed.
  • ENTROPY_RT_E or ENTROPY_APT_E The SP 800-90B seed health test rejected the banked material, which is burned.
  • BAD_FUNC_ARG bank is null, inst_offset is out of range, or n is 0.

The daemon-side serialization word (not the instance lock) excludes a concurrent wc_rng_bank_inst_reinit() from freeing the DRBG out from under the gather; lease_holders never consult it, since instance_lock exclusion already covers every lease_holder interaction. The caller must hold a bank reference (e.g. per the daemon association) for the duration of the call. Return taxonomy for a banking rotation: BUSY_E, the gate is held by a reinit – skip this turn; ALREADY_E, sleep until the bank is consumed; WRONG_TYPE_OBJECT_E, the instance has no DRBG – permanently (RDRAND et al.), retire it from the rotation, or because it is out of service pending reinstantiation; the other transient codes (WC_RNG_ERR_IS_TRANSIENT()) are gather or health-test failures – skip the turn, and alarm if persistent.

function wc_rng_bank_next_seed_generate_rbgc

int wc_rng_bank_next_seed_generate_rbgc(
    struct wc_rng_bank * bank,
    int inst_offset,
    word32 n
)

The chain-sourced form of wc_rng_bank_next_seed_generate(): the banked material is drawn from root's generate function and tagged with its provenance.

Parameters:

  • bank The bank.
  • inst_offset The instance to bank for.
  • n Maximum bytes to bank this call.

See:

Return:

  • 0 Bytes were banked.
  • ALREADY_E The instance's bank is ready or being consumed.
  • ENTROPY_RT_E or ENTROPY_APT_E The SP 800-90B seed health test rejected the banked material, which is burned.
  • BAD_FUNC_ARG bank or root is null, inst_offset is out of range, or n is 0.

function wc_rng_bank_inst_reinit

int wc_rng_bank_inst_reinit(
    struct wc_rng_bank * bank,
    struct wc_rng_bank_inst * rng_inst,
    int timeout_secs,
    word32 flags
)

Free and reinstantiate a leased instance in place. The caller must hold the lease; the daemon-side serialization word excludes concurrent lockless banking during the cycle.

Parameters:

  • bank The bank the instance belongs to.
  • rng_inst The leased instance to reinitialize.
  • timeout_secs Seeding timeout budget.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* flags.

See: wc_rng_bank_recover_inst

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or rng_inst is null.
  • RNG_FAILURE_E Reinstantiation could not be seeded within timeout_secs.
  • BUSY_E The whole-instance-operation gate is held (daemon banking in progress); retry.

function wc_rng_bank_recover_inst

int wc_rng_bank_recover_inst(
    struct wc_rng_bank * bank,
    int inst_offset,
    int timeout_secs,
    word32 flags
)

Patrol helper: check out the instance at inst_offset with WC_RNG_BANK_FLAG_FOR_RECOVERY, recover it iff it needs recovery, and check it back in. Two recovery arms: an out-of-service instance (wc_RNG_GetStatus() != WC_DRBG_OK) is reinitialized in place; an in_service but entropy_invalidated (quarantined) instance takes one credited reseed, which clears the quarantine while preserving instance identity. A healthy instance is a success no-op, so callers can invoke this unconditionally on state observed locklessly.

Parameters:

  • bank The bank.
  • inst_offset The instance to patrol.
  • timeout_secs Seeding timeout budget.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* flags.

See:

Return:

  • 0 Success (recovered, or nothing to recover).
  • BAD_FUNC_ARG bank is null, inst_offset is out of range, or the flags are contradictory.
  • RNG_FAILURE_E Recovery could not be seeded within timeout_secs.
  • BUSY_E The instance lock or whole-instance-operation gate is contended; retry on a later patrol turn.

Example

// after a VM duplication event has invalidated the bank:
for (i = 0; i < n_rngs; i++)
    (void)wc_rng_bank_recover_inst(bank, i, 10,
                                   WC_RNG_BANK_FLAG_CAN_WAIT);

A stale lockless status observation costs one harmless round trip. BUSY_E reports contention on the instance lock or the whole-instance-operation gate: retry on a later patrol turn. flags may include WC_RNG_BANK_FLAG_CAN_WAIT and WC_RNG_BANK_FLAG_AFFINITY_LOCK, which are passed through.

function wc_rng_bank_spawn

int wc_rng_bank_spawn(
    struct wc_rng_bank * bank,
    WC_RNG * child_rng,
    byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    int preferred_inst_offset,
    int timeout_secs,
    word32 flags
)

Spawn an SP 800-90C chain RNG from a bank instance: check out a parent instance (honoring the usual selection flags), instantiate child_rng as its chain child (wc_InitRngNonceRBGC()), and check the parent back in. The child's lifetime is thereafter decoupled from the parent and its bank; release it with wc_FreeRng() (or wc_rng_free() for the heap form, wc_rng_bank_spawn_new()). The child's RBGC stratum is one plus the parent's stratum at instantiation.

Parameters:

  • bank The bank to spawn from.
  • child_rng The caller-provided WC_RNG to instantiate.
  • nonce Optional additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • perso Optional personalization string (may be null).
  • persoSz Length of perso in bytes.
  • preferred_inst_offset The preferred parent instance, or 0.
  • timeout_secs Wait budget (with _CAN_WAIT).
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* per-call flags.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or child_rng is null, or the flags are contradictory (uncredited or recovery seeding contradict a spawn).
  • RNG_FAILURE_E No serviceable parent within the timeout budget.

A recommended nonce, when available, is a racy read of a high-resolution timer (e.g. Linux kernel random_get_entropy()). WC_RNG_BANK_FLAG_CONSUME_NEXT_SEED composes: a ready banked seed is redeemed on the parent before the spawn draw. WC_RNG_BANK_FLAG_STIR and WC_RNG_BANK_FLAG_FOR_RECOVERY are rejected. WC_RNG_BANK_FLAG_ERROR_ON_RNG_FAILED is implied: the parent is guaranteed in-service, or an error is returned with no lease and no child.

function wc_rng_bank_spawn_new

int wc_rng_bank_spawn_new(
    struct wc_rng_bank * bank,
    WC_RNG ** child_rng,
    byte * nonce,
    word32 nonceSz,
    const byte * perso,
    word32 persoSz,
    int preferred_inst_offset,
    int timeout_secs,
    word32 flags
)

The allocating form of wc_rng_bank_spawn(): the child is allocated from the bank's heap and returned through child_rng; release with wc_rng_free().

Parameters:

  • bank The bank to spawn from.
  • child_rng Receives the allocated, instantiated WC_RNG.
  • nonce Optional additional instantiation input.
  • nonceSz Length of nonce in bytes.
  • perso Optional personalization string (may be null).
  • persoSz Length of perso in bytes.
  • preferred_inst_offset The preferred parent instance, or 0.
  • timeout_secs Wait budget (with _CAN_WAIT).
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* per-call flags.

See: wc_rng_bank_spawn

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or child_rng is null.
  • MEMORY_E Allocation failed.
  • RNG_FAILURE_E No serviceable parent within the timeout budget.

function wc_rng_bank_seed

int wc_rng_bank_seed(
    struct wc_rng_bank * bank,
    const byte * seed,
    word32 seedSz,
    const byte * nonce,
    word32 nonceSz,
    int timeout_secs,
    word32 flags
)

Reseed every instance with caller-supplied seed material. WC_RNG_BANK_FLAG_STIR mixes the material in without crediting it.

Parameters:

  • bank The bank to seed.
  • seed Seed material.
  • seedSz Length of seed in bytes.
  • nonce Optional per-instance nonce material (may be null).
  • nonceSz Length of nonce in bytes.
  • timeout_secs Wait budget per instance.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* flags.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or seed is null.
  • RNG_FAILURE_E An instance could not be reseeded within timeout_secs.

function wc_rng_bank_seed_range

int wc_rng_bank_seed_range(
    struct wc_rng_bank * bank,
    int first_inst,
    int last_inst,
    const byte * seed,
    word32 seedSz,
    const byte * nonce,
    word32 nonceSz,
    int timeout_secs,
    word32 flags
)

The range form of wc_rng_bank_seed(): seed instances first_inst through last_inst inclusive.

Parameters:

  • bank The bank to seed.
  • first_inst The first instance offset.
  • last_inst The last instance offset.
  • seed Seed material.
  • seedSz Length of seed in bytes.
  • nonce Optional per-instance nonce material (may be null).
  • nonceSz Length of nonce in bytes.
  • timeout_secs Wait budget per instance.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* flags.

See: wc_rng_bank_seed

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or seed is null, or the range is out of bounds.
  • RNG_FAILURE_E An instance could not be reseeded within timeout_secs.
  • BAD_INDEX_E The instance range is invalid.
  • BAD_STATE_E The bank is not initialized.
  • NO_DEFAULT_FOUND_E bank is null and no default bank is registered.

function wc_rng_bank_reseed

int wc_rng_bank_reseed(
    struct wc_rng_bank * bank,
    const byte * nonce,
    word32 nonceSz,
    int timeout_secs,
    word32 flags
)

Reseed every instance from the module's seed source. Same contract as wc_rng_bank_reseed_range() over the whole bank.

Parameters:

  • bank The bank to reseed.
  • nonce Optional per-instance nonce material (may be null).
  • nonceSz Length of nonce in bytes.
  • timeout_secs Wait budget: per instance for the checkout, and across the whole walk for reseed retries (WC_RNG_BANK_FLAG_CAN_WAIT).
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* flags.

See:

Return:

  • 0 Every instance was reseeded, or – waiting not being allowed – marked due for reseed on its next generate.
  • BAD_FUNC_ARG bank is null, or flags selects instance choice (WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST et al.), which a walk cannot honor.
  • BAD_STATE_E The bank is not initialized, or an instance is out of service.
  • NOT_READY_E WC_RNG_BANK_FLAG_RBGC with the root not in service.
  • WC_TIMEOUT_E The reseed retries exceeded timeout_secs; the walk stopped there.
  • INTERRUPTED_E A signal arrived while waiting; the walk stopped there.
  • other A negative code from wc_rng_bank_checkout(), which stopped the walk; or, the walk having completed, the first per_instance reseed failure it carried on past (see wc_rng_bank_reseed_range()).

function wc_rng_bank_reseed_range

int wc_rng_bank_reseed_range(
    struct wc_rng_bank * bank,
    int first_inst,
    int last_inst,
    const byte * nonce,
    word32 nonceSz,
    int timeout_secs,
    word32 flags
)

The range form of wc_rng_bank_reseed(). A failed reseed does not stop the walk: the instance is marked due for reseed, the next entropy_capable generate on it retries in_boundary, and the walk carries on to the remaining instances – but the first such failure is the return value, so the caller knows the range was not reseeded here and now. A code that stops the walk (WC_TIMEOUT_E, INTERRUPTED_E, a checkout failure) outranks it: the instances past that point were not visited and are not marked due. A transient per_instance code (WC_RNG_ERR_IS_TRANSIENT()) means that instance's reseed is a pass away from resolving on its own; for the rest, see wc_RNG_DRBG_Reseed_Now().

Parameters:

  • bank The bank to reseed.
  • nonce Optional per-instance nonce material (may be null).
  • nonceSz Length of nonce in bytes.
  • first_inst The first instance offset.
  • last_inst The last instance offset, or -1 for the last in the bank.
  • timeout_secs Wait budget: per instance for the checkout, and across the whole walk for reseed retries (WC_RNG_BANK_FLAG_CAN_WAIT).
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* flags.

See: wc_rng_bank_reseed

Return:

  • 0 Every instance in range was reseeded, or – waiting not being allowed – marked due for reseed on its next generate.
  • BAD_FUNC_ARG bank is null, or flags selects instance choice (WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST et al.), which a walk cannot honor.
  • BAD_INDEX_E The instance range is invalid.
  • BAD_STATE_E The bank is not initialized, or an instance in range is out of service.
  • NOT_READY_E WC_RNG_BANK_FLAG_RBGC with the root not in service.
  • WC_TIMEOUT_E The reseed retries exceeded timeout_secs; the walk stopped there.
  • INTERRUPTED_E A signal arrived while waiting; the walk stopped there.
  • other A negative code from wc_rng_bank_checkout(), which stopped the walk; or, the walk having completed, the first per_instance reseed failure it carried on past, as wc_RNG_DRBG_Reseed_Now() (or wc_RNG_DRBG_ReseedRBGC() under WC_RNG_BANK_FLAG_RBGC) returned it.

function wc_rng_bank_invalidate_entropy

int wc_rng_bank_invalidate_entropy(
    struct wc_rng_bank * bank,
    word32 flags
)

Set the entropy-invalidated latch on every instance (see wc_RNG_invalidate_entropy()): cached entropy products are discarded, and each instance is forced through a credited reseed before its next generate serves output. Lock_free and constant_time per instance; safe from a state_invalidation event context (VM fork/resume).

Parameters:

  • bank The bank to invalidate.
  • flags Bitwise-or of WC_RNG_BANK_FLAG_* flags.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank is null.
  • BAD_STATE_E The bank is not initialized.

Example

// VM-resume notifier
(void)wc_rng_bank_invalidate_entropy(bank, WC_RNG_BANK_FLAG_NONE);
// instances recover on next checkout, or by patrol:
//   wc_rng_bank_recover_inst()

Also purges each instance's banked next-seed apertures: the purge is the provenance guarantee that a READY bank observed after the event holds post-event material (see wc_rng_bank_checkout()'s recovery admissions). Walks every instance even on error, returning the first error. flags must be 0.

function wc_rng_bank_daemon_reserve

int wc_rng_bank_daemon_reserve(
    struct wc_rng_bank * bank,
    WC_ATOMIC_UINT_ARG magic
)

Reserve the bank's daemon slot with a caller-chosen nonzero magic word, admitting exactly one scheduling daemon per bank. The lifecycle is strictly ordered: _reserve, then _register, then _unregister, then _release.

Parameters:

  • bank The bank to claim.
  • magic The daemon's magic word.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank is null or magic is the free sentinel.
  • BUSY_E The slot is claimed, or claiming is contended.

function wc_rng_bank_daemon_register

int wc_rng_bank_daemon_register(
    struct wc_rng_bank * bank,
    void * daemon,
    WC_ATOMIC_UINT_ARG magic
)

Register the daemon object in a slot reserved with the same magic word.

Parameters:

  • bank The bank.
  • daemon The daemon object to register.
  • magic The daemon's magic word.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or daemon is null.
  • ALREADY_E The slot is already in the requested state.
  • WRONG_TYPE_OBJECT_E magic does not match the claim.
  • BUSY_E The slot transition is contended; retry.

function wc_rng_bank_daemon_unregister

int wc_rng_bank_daemon_unregister(
    struct wc_rng_bank * bank,
    void ** daemon,
    WC_ATOMIC_UINT_ARG magic
)

Unregister the daemon object, returning it through daemon.

Parameters:

  • bank The bank.
  • daemon Receives the registered daemon object.
  • magic The daemon's magic word.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or daemon is null.
  • ALREADY_E The slot is already in the requested state.
  • WRONG_TYPE_OBJECT_E magic does not match the claim.
  • BUSY_E The slot transition is contended; retry.

function wc_rng_bank_daemon_release

int wc_rng_bank_daemon_release(
    struct wc_rng_bank * bank,
    WC_ATOMIC_UINT_ARG magic
)

Release the daemon slot claimed with magic, returning it to the free sentinel.

Parameters:

  • bank The bank.
  • magic The daemon's magic word.

See: wc_rng_bank_daemon_reserve

Return:

  • 0 Success
  • BAD_FUNC_ARG bank is null.
  • ALREADY_E The slot is already in the requested state.
  • WRONG_TYPE_OBJECT_E magic does not match the claim.
  • BUSY_E The slot transition is contended; retry.

function wc_rng_bank_register_free_hook

int wc_rng_bank_register_free_hook(
    struct wc_rng_bank * bank,
    wc_rng_bank_free_hook_cb_t free_hook,
    void * arg
)

Register a callback fired by wc_rng_bank_fini() once its refcount and leak gates pass – i.e. once teardown is committed – for external registries that must drop their reference when the bank dies. One-shot: the hook is cleared before firing. A null free_hook unregisters.

Parameters:

  • bank The bank to hook.
  • free_hook The callback.
  • arg Opaque argument passed to the callback.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank is null.

function wc_InitRng_BankRef

int wc_InitRng_BankRef(
    struct wc_rng_bank * bank,
    WC_RNG * rng
)

Initialize rng as a bank reference: a WC_RNG with no DRBG of its own, whose wc_RNG_GenerateBlock() transparently checks an instance out of bank, generates, and checks it back in. Release with wc_FreeRng().

Parameters:

  • bank The bank to reference.
  • rng The WC_RNG to initialize as a reference.

See:

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or rng is null.

Example

WC_RNG rng;
if (wc_InitRng_BankRef(bank, &rng) == 0) {
    // rng now serves through the bank
    ret = wc_RNG_GenerateBlock(&rng, out, sizeof(out));
    wc_FreeRng(&rng);
}

function wc_BankRef_Release

int wc_BankRef_Release(
    WC_RNG * rng
)

Release a bank reference. wc_FreeRng() calls this automatically for bank references; direct use is rarely needed.

Parameters:

  • rng The bank reference to release.

See: wc_InitRng_BankRef

Return:

  • 0 Success
  • BAD_FUNC_ARG rng is null or is not a bank reference.

function wc_rng_new_bankref

int wc_rng_new_bankref(
    struct wc_rng_bank * bank,
    WC_RNG ** rng
)

The allocating form of wc_InitRng_BankRef(): the reference is allocated from the bank's heap; release with wc_rng_free().

Parameters:

  • bank The bank to reference.
  • rng Receives the allocated bank reference.

See: wc_InitRng_BankRef

Return:

  • 0 Success
  • BAD_FUNC_ARG bank or rng is null.
  • MEMORY_E Allocation failed.

function wc_rng_bank_debug_stats_snap

int wc_rng_bank_debug_stats_snap(
    struct wc_rng_debug_stats_snapshot * s,
    struct wc_rng_bank * bank
)

Snapshot the RNG debug counters (WC_RNG_DEBUG_STATS) with bank-level context.

Parameters:

  • s Receives the snapshot.
  • bank Optional bank for context, or null.

See: wc_rng_debug_stats_snap

Return:

  • 0 Success
  • BAD_FUNC_ARG s is null.

Updated on 2026-10-28 at 01:13:04 +0000