Skip to content

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.

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_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.

See: wc_rng_bank_root_rng_get

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:

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.

See: wc_rng_debug_stats_snap

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