rng_bank.h
Functions
| Name | |
|---|---|
| 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_root_rng_init(struct wc_rng_bank * bank, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, word32 flags) Initialize the bank's root RNG – the primary-sourced parent that seeds and recovers the bank's instances. The root is WC_RNG_INIT_FLAG_LOCK_REQUIRED (implied) and is operated by the bank through lock-word operations alone, so WC_RNG_INIT_FLAG_USE_FULL_MUTEX is refused: a full-mutex root would be bypassed by the daemon, by reinit-in-place, and by the invalidation walk. |
| WC_RNG * | wc_rng_bank_root_rng_get(struct wc_rng_bank * bank) Report the bank's root RNG. |
| int | wc_rng_bank_root_rng_reinit(struct wc_rng_bank * bank, const byte * nonce, word32 nonceSz, const byte * perso, word32 persoSz, word32 flags) Retire and reinstantiate the bank's root RNG as one serialized transition, excluding concurrent entropy-invalidation walks and whole-instance operations for its span. The recovery path of last resort for a condemned root. With WC_RNG_HAVE_LOCK the root's lease is taken by try-lock and held across the cycle, so a held root yields BUSY_E (retry later); without it, acquisition of the serializing gate spin-waits, so task context only. Either way reinstantiation performs a full seed acquisition. |
| int | wc_rng_bank_root_rng_reseed_now(struct wc_rng_bank * bank, const byte * nonce, word32 nonceSz) Force an immediate reseed of the bank's root RNG, serialized against other root touchers. With WC_RNG_HAVE_LOCK, the root's lease is taken by unconditional try-lock and held across the reseed. Without it, the serializing inst-op gate is claimed by try-once (fail-fast, atomic-legal), excluding member reinstantiations chaining from the root, entropy-invalidation walks, and root reinstantiation for the reseed's span. |
| int | wc_rng_bank_root_rng_reseed_if_due(struct wc_rng_bank * bank, const byte * nonce, word32 nonceSz, wc_drbg_reseed_ctr_t threshold) Threshold form of wc_rng_bank_root_rng_reseed_now(): reseed the bank's root RNG only when its reseed counter has reached threshold, with the counter read and the reseed performed under a single hold of the configuration's root serialization (the root's lease with WC_RNG_HAVE_LOCK, else the inst-op gate). Without the lock facility the saturated counter is the invalidation walk's only root-side record, so a threshold of WC_RESEED_INTERVAL makes this the root's deterministic post-invalidation recovery. |
| 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. |
Functions Documentation
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.
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.
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_root_rng_init
int wc_rng_bank_root_rng_init(
struct wc_rng_bank * bank,
const byte * nonce,
word32 nonceSz,
const byte * perso,
word32 persoSz,
word32 flags
)
Initialize the bank's root RNG – the primary-sourced parent that seeds and recovers the bank's instances. The root is WC_RNG_INIT_FLAG_LOCK_REQUIRED (implied) and is operated by the bank through lock-word operations alone, so WC_RNG_INIT_FLAG_USE_FULL_MUTEX is refused: a full-mutex root would be bypassed by the daemon, by reinit-in-place, and by the invalidation walk.
Parameters:
- bank The bank whose root to initialize.
- nonce Optional instantiation nonce (may be null).
- nonceSz Length of nonce in bytes.
- perso Optional personalization string (may be null).
- persoSz Length of perso in bytes.
- flags Bitwise-or of WC_RNG_INIT_FLAG_* attributes.
Return:
- 0 Success
- BAD_FUNC_ARG bank is null, or flags includes WC_RNG_INIT_FLAG_USE_FULL_MUTEX.
- ALREADY_E The root is already initialized.
function wc_rng_bank_root_rng_get
WC_RNG * wc_rng_bank_root_rng_get(
struct wc_rng_bank * bank
)
Report the bank's root RNG.
Parameters:
- bank The bank to interrogate.
See: wc_rng_bank_root_rng_init
Return: The root WC_RNG, or null when none is initialized or bank is null.
function wc_rng_bank_root_rng_reinit
int wc_rng_bank_root_rng_reinit(
struct wc_rng_bank * bank,
const byte * nonce,
word32 nonceSz,
const byte * perso,
word32 persoSz,
word32 flags
)
Retire and reinstantiate the bank's root RNG as one serialized transition, excluding concurrent entropy-invalidation walks and whole-instance operations for its span. The recovery path of last resort for a condemned root. With WC_RNG_HAVE_LOCK the root's lease is taken by try-lock and held across the cycle, so a held root yields BUSY_E (retry later); without it, acquisition of the serializing gate spin-waits, so task context only. Either way reinstantiation performs a full seed acquisition.
Parameters:
- bank The bank whose root to reinstantiate.
- nonce Optional instantiation nonce (may be null).
- nonceSz Length of nonce in bytes.
- 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 bank is null.
- BUSY_E The root's lease is held (WC_RNG_HAVE_LOCK); nothing was touched, retry later.
- negative wc_FreeRng() or reinstantiation failure; the root is left out of service (WC_DRBG_NOT_INIT) and a later reinit may be attempted.
function wc_rng_bank_root_rng_reseed_now
int wc_rng_bank_root_rng_reseed_now(
struct wc_rng_bank * bank,
const byte * nonce,
word32 nonceSz
)
Force an immediate reseed of the bank's root RNG, serialized against other root touchers. With WC_RNG_HAVE_LOCK, the root's lease is taken by unconditional try-lock and held across the reseed. Without it, the serializing inst-op gate is claimed by try-once (fail-fast, atomic-legal), excluding member reinstantiations chaining from the root, entropy-invalidation walks, and root reinstantiation for the reseed's span.
Parameters:
- bank The bank whose root to reseed.
- nonce Optional reseed nonce (may be null).
- nonceSz Length of nonce in bytes.
See:
Return:
- 0 Success
- BAD_FUNC_ARG bank is null.
- BUSY_E The root's lease or the inst-op gate is held; nothing was touched, retry later.
- negative wc_RNG_DRBG_Reseed_Now() failure.
function wc_rng_bank_root_rng_reseed_if_due
int wc_rng_bank_root_rng_reseed_if_due(
struct wc_rng_bank * bank,
const byte * nonce,
word32 nonceSz,
wc_drbg_reseed_ctr_t threshold
)
Threshold form of wc_rng_bank_root_rng_reseed_now(): reseed the bank's root RNG only when its reseed counter has reached threshold, with the counter read and the reseed performed under a single hold of the configuration's root serialization (the root's lease with WC_RNG_HAVE_LOCK, else the inst-op gate). Without the lock facility the saturated counter is the invalidation walk's only root-side record, so a threshold of WC_RESEED_INTERVAL makes this the root's deterministic post-invalidation recovery.
Parameters:
- bank The bank whose root to reseed.
- nonce Optional reseed nonce (may be null).
- nonceSz Length of nonce in bytes.
- threshold Reseed-counter value at which a reseed is due; 0 reseeds unconditionally.
See:
- wc_rng_bank_root_rng_reseed_now
- wc_RNG_DRBG_GetReseedCtr
Return:
- 0 Success
- BAD_FUNC_ARG bank is null.
- ALREADY_E The counter is below threshold: nothing due.
- BUSY_E The root's lease or the inst-op gate is held; nothing was touched, retry later.
- negative wc_RNG_DRBG_GetReseedCtr() or wc_RNG_DRBG_Reseed_Now() failure.
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.
Return:
- 0 Success
- BAD_FUNC_ARG s is null.
Source code
int wc_rng_bank_new(struct wc_rng_bank **ctx, int n_rngs, word32 flags,
int timeout_secs, void *heap, int devId);
int wc_rng_bank_init(struct wc_rng_bank *ctx, int n_rngs, word32 flags,
int timeout_secs, void *heap, int devId);
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);
int wc_rng_bank_first_failover_inst_set(struct wc_rng_bank *ctx,
int first_failover_inst);
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);
int wc_rng_bank_fini(struct wc_rng_bank *ctx);
int wc_rng_bank_free(struct wc_rng_bank **ctx);
int wc_rng_bank_default_set(struct wc_rng_bank *bank);
int wc_rng_bank_default_checkout(struct wc_rng_bank **bank);
int wc_rng_bank_default_checkin(struct wc_rng_bank **bank);
int wc_rng_bank_default_clear(struct wc_rng_bank *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);
int wc_rng_bank_checkin(struct wc_rng_bank *bank,
struct wc_rng_bank_inst **rng_inst);
int wc_rng_bank_inst_checkin(struct wc_rng_bank_inst **rng_inst);
int wc_rng_bank_get_inst_id(struct wc_rng_bank_inst *rng_inst);
int wc_rng_bank_next_seed_generate(struct wc_rng_bank *bank, int inst_offset,
word32 n);
int wc_rng_bank_next_seed_generate_rbgc(struct wc_rng_bank *bank,
int inst_offset, word32 n);
int wc_rng_bank_inst_reinit(struct wc_rng_bank *bank,
struct wc_rng_bank_inst *rng_inst,
int timeout_secs, word32 flags);
int wc_rng_bank_recover_inst(struct wc_rng_bank *bank, int inst_offset,
int timeout_secs, word32 flags);
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);
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);
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);
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);
int wc_rng_bank_reseed(struct wc_rng_bank *bank,
const byte *nonce, word32 nonceSz,
int timeout_secs, word32 flags);
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);
int wc_rng_bank_invalidate_entropy(struct wc_rng_bank *bank, word32 flags);
int wc_rng_bank_daemon_reserve(struct wc_rng_bank *bank,
WC_ATOMIC_UINT_ARG magic);
int wc_rng_bank_daemon_register(struct wc_rng_bank *bank, void *daemon,
WC_ATOMIC_UINT_ARG magic);
int wc_rng_bank_daemon_unregister(struct wc_rng_bank *bank, void **daemon,
WC_ATOMIC_UINT_ARG magic);
int wc_rng_bank_daemon_release(struct wc_rng_bank *bank,
WC_ATOMIC_UINT_ARG magic);
int wc_rng_bank_root_rng_init(struct wc_rng_bank *bank,
const byte *nonce, word32 nonceSz,
const byte *perso, word32 persoSz,
word32 flags);
WC_RNG *wc_rng_bank_root_rng_get(struct wc_rng_bank *bank);
int wc_rng_bank_root_rng_reinit(struct wc_rng_bank *bank,
const byte *nonce, word32 nonceSz,
const byte *perso, word32 persoSz,
word32 flags);
int wc_rng_bank_root_rng_reseed_now(struct wc_rng_bank *bank,
const byte *nonce, word32 nonceSz);
int wc_rng_bank_root_rng_reseed_if_due(struct wc_rng_bank *bank,
const byte *nonce, word32 nonceSz,
wc_drbg_reseed_ctr_t threshold);
int wc_rng_bank_register_free_hook(struct wc_rng_bank *bank,
wc_rng_bank_free_hook_cb_t free_hook,
void *arg);
int wc_InitRng_BankRef(struct wc_rng_bank *bank, WC_RNG *rng);
int wc_BankRef_Release(WC_RNG *rng);
int wc_rng_new_bankref(struct wc_rng_bank *bank, WC_RNG **rng);
int wc_rng_bank_debug_stats_snap(struct wc_rng_debug_stats_snapshot *s,
struct wc_rng_bank *bank);
Updated on 2026-11-13 at 01:20:07 +0000