Skip to content

20261030-RNG-invalidation-redux - #12050

Open
douzzer wants to merge 6 commits into
wolfSSL:masterfrom
douzzer:20261030-RNG-invalidation-redux
Open

douzzer wants to merge 6 commits into
wolfSSL:masterfrom
douzzer:20261030-RNG-invalidation-redux

Conversation

@douzzer

@douzzer douzzer commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

wolfcrypt/src/random.c, wolfssl/wolfcrypt/random.h wolfcrypt/src/rng_bank.c,
linuxkm/lkcapi_sha_glue.c, wolfcrypt/test/test.c,
doc/dox_comments/header_files/random.h: rename nonce to addIn in reseed
APIs, for consistent naming of "additional" data as such.

tests/api/test_random.c, tests/unit-mcdc/test_random_fault_whitebox.c,
tests/unit-mcdc/test_random_whitebox.c: rename nonce to addIn in reseed APIs.

.github/workflows/codespell.yml: add "addIn" to ignore_words_list.

wolfssl/wolfcrypt/wc_port.h, wolfcrypt/src/wc_port.c: add wolfSSL_Atomic_Func_Ptr_CompareExchange() -- casting wrapper around wolfSSL_Atomic_Ptr_CompareExchange().

RNG: add auxiliary invalidation pathway, both sender-side and receiver-side.

  • add APIs wc_RNG_entropy_epoch_extra_inv_init() and wc_RNG_extra_entropy_epoch_init(), and associated callback types.
  • add internal routine current_entropy_epoch() and associated internal state.
  • refactor all ad hoc invalidation checks of global_entropy_epoch to use current_entropy_epoch().
  • refactor entropy epochs as 64 bit width, with wc_RNG_entropy_epoch_t (word64).
  • add struct wc_RNG_entropy_epoch_atomic and associated initializers.
  • add inline helpers wc_RNG_entropy_epoch_export(), wc_RNG_entropy_epoch_import(), and wc_RNG_entropy_epoch_increment_atomic().
  • refactor Hash_DRBG_Reseed() and its callers to pass cur_epoch only when defined(WC_RNG_HAVE_ENTROPY_EPOCH).
  • update tests and documentation for 64 bit epochs.
  • add test and documentation coverage of auxiliary epoch facility.

tested with

wolfssl-multi-test.sh ...
super-quick-check

Copilot AI balanced review requested due to automatic review settings November 6, 2026 20:13
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report · Explore what changed →

zephyr-frdm_rw612

  • FLASH: datas +16 B, log_const_area -8 B, rodata -8 B, text +2,944 B (+1.0%, 285,408 B / 67,108,864 B, total: 0% used)
  • RAM: bss +49 B, datas +16 B (+0.1%, 58,423 B / 983,040 B, total: 6% used)

No memory changes detected for:


Catch memory regressions in CI with MemBrowse. Free for open source.

@douzzer douzzer added the For FIPS v7 Module Related to FIPS v7.0.0 module prep for submission label Nov 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Non-atomic epoch transitions and unsynchronized callback registration can bypass RNG invalidation, duplicate publisher calls, and cause C data races.

4 open issues
What changed in this PR

This PR extends wolfCrypt’s RNG invalidation mechanism with auxiliary callbacks for publishing and receiving entropy events, while standardizing additional-input naming.

Changes:

  • Introduces 64-bit entropy epochs and routes invalidation checks through external-event detection.
  • Adds callback registration APIs and a function-pointer atomic comparison wrapper.
  • Renames reseed APIs from Nonce to AddIn, updates callers and documentation, and adds auxiliary-epoch tests.
File Description
wolfssl/​wolfcrypt/​wc_port.h Adds the function-pointer atomic comparison wrapper.
wolfssl/​wolfcrypt/​random.h Defines epoch types, helpers, callbacks, and renamed APIs.
wolfcrypt/​test/​test.h Declares the auxiliary-epoch test.
wolfcrypt/​test/​test.c Adds auxiliary-epoch coverage and updates API calls.
wolfcrypt/​src/​wc_port.c Checks the wrapper’s pointer-size assumption.
wolfcrypt/​src/​rng_bank.c Updates reseed and stir API names.
wolfcrypt/​src/​random.c Implements auxiliary invalidation and integrates epoch checks.
tests/​unit-mcdc/​test_random_whitebox.c Updates internal stir API calls.
tests/​unit-mcdc/​test_random_fault_whitebox.c Updates stir calls and related comments.
tests/​api/​test_random.c Updates tests to use renamed APIs.
linuxkm/​lkcapi_sha_glue.c Updates kernel reseed call sites.
doc/​dox_comments/​header_files/​random.h Documents auxiliary epochs and renamed APIs.
.github/​workflows/​codespell.yml Adds addIn to the spelling allowlist.

Review effort: Balanced

Comment thread wolfcrypt/src/random.c Resolved
Comment thread wolfcrypt/src/random.c Resolved
Comment thread wolfssl/wolfcrypt/random.h Resolved
Comment thread wolfcrypt/test/test.c Resolved

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #12050

Scan targets checked: linuxkm-src, linuxkm-bugs, wolfcrypt-src, wolfcrypt-bugs, wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): .github/workflows/codespell.yml, doc/dox_comments/header_files/random.h, wolfcrypt/test/test.h
Coverage: 7 of 10 in-scope changed file(s) opened by the reviewer; not opened: tests/api/test_random.c, tests/unit-mcdc/test_random_fault_whitebox.c, tests/unit-mcdc/test_random_whitebox.c

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Review tier: Max

Comment thread wolfcrypt/src/random.c
wc_RNG_entropy_epoch_t cur_extra_entropy_epoch_local =
wc_RNG_entropy_epoch_export(&extra_entropy_epoch_local);
if (cur_extra_entropy_epoch != cur_extra_entropy_epoch_local) {
wc_RNG_global_invalidate_entropy();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Publisher runs before the local external epoch is updated, so a publisher that calls back into the RNG recurses without… · Logic errors

current_entropy_epoch() calls wc_RNG_global_invalidate_entropy(), which runs the registered publisher (line 459), before it updates extra_entropy_epoch_local (line 410). A publisher that calls any RNG API that reads the epoch sees the same external change again and recurses without bound. This happens only for events found through the getter.

Suggested fix: The fix needs a design decision, such as a reentrancy guard that keeps the invalidate-before-import ordering; consult the C11 memory model (ISO/IEC 9899:2011 §5.1.2.4).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as designed; contract-covered. The mechanical observation is accurate,
and deliberate: invalidate-before-import is the pathway's lossless invariant.
Consumption of a detection strictly follows the invalidation it triggers, so a
thread dying anywhere in the window degrades to a duplicate advance, never a
lost one. Every reordering or claim-gating that would prevent the described
recursion reopens a lost-event window, and the loss function here is maximally
asymmetric: a duplicate costs one spurious reseed; a loss costs unbounded reuse
of fork-correlated DRBG state. We optimize the correct tail.

The recursion itself requires the handler to do the one thing its contract
forbids. The dox for wc_RNG_entropy_epoch_extra_inv_init() states the handler
must not call back into wolfCrypt, and the call site in
wc_RNG_global_invalidate_entropy() now carries the same sentence with the
reason ("any epoch read from inside it re-detects the same event and
recurses"). We don't spend runtime state defending against documented misuse;
we document it at both places a reader can arrive from.

Love, Mythos

…bank.c,

  linuxkm/lkcapi_sha_glue.c, wolfcrypt/test/test.c,
  doc/dox_comments/header_files/random.h: rename "nonce" to "addIn" in reseed
  APIs, for consistent naming of "additional" data as such.
tests/unit-mcdc/test_random_whitebox.c: rename "nonce" to "addIn" in reseed APIs.
…mic_Func_Ptr_CompareExchange() -- casting wrapper around wolfSSL_Atomic_Ptr_CompareExchange().
…r-side.

    * add APIs wc_RNG_entropy_epoch_extra_inv_init() and wc_RNG_extra_entropy_epoch_init(), and associated callback types.
    * add internal routine current_entropy_epoch() and associated internal state.
    * refactor all ad hoc invalidation checks of global_entropy_epoch to use current_entropy_epoch().
    * refactor entropy epochs as 64 bit width, with wc_RNG_entropy_epoch_t (word64).
    * add struct wc_RNG_entropy_epoch_atomic and associated initializers.
    * add inline helpers wc_RNG_entropy_epoch_export(), wc_RNG_entropy_epoch_import(), and wc_RNG_entropy_epoch_increment_atomic().
    * refactor Hash_DRBG_Reseed() and its caller to pass cur_epoch only when defined(WC_RNG_HAVE_ENTROPY_EPOCH).
    * update tests and documentation for 64 bit epochs.
    * add test and documentation coverage of auxiliary epoch facility.
…ra_entropy_epoch_reset() and wc_RNG_entropy_epoch_extra_inv_reset() (test helpers).

wolfcrypt/test/test.c and wolfcrypt/test/test.h: call rng_epoch_extra_test()
  from rng_epoch_test() rather than reporting its results separately; fix data
  race in rng_epoch_extra_getCb(); implement ext epoch save/restore in
  rng_epoch_extra_test().
@douzzer
douzzer force-pushed the 20261030-RNG-invalidation-redux branch from 6b5e3f0 to 2775dca Compare November 7, 2026 04:19
@douzzer
douzzer requested review from wolfSSL-Fenrir-bot and a balanced review from Copilot November 7, 2026 04:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new RNG epoch tests can falsely report success because subtest failures are not propagated, and small-stack allocation failure can discard installed production handlers without restoring them.

2 open issues
4 resolved since last review

Review effort: Balanced

Comment thread wolfcrypt/test/test.c
}
#endif /* WC_RNG_SEED_CB && WC_RNG_HAVE_LOCK */

api_ret = rng_epoch_extra_test();
Comment thread wolfcrypt/test/test.c
WOLFSSL_ENTER("rng_epoch_extra_test");

WC_ALLOC_VAR_EX(rng, WC_RNG, 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER,
ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), out_l));

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #12050

Scan targets checked: linuxkm-src, linuxkm-bugs, wolfcrypt-src, wolfcrypt-bugs, wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): .github/workflows/codespell.yml, doc/dox_comments/header_files/random.h
Coverage: 3 of 10 in-scope changed file(s) opened by the reviewer; not opened: linuxkm/lkcapi_sha_glue.c, tests/api/test_random.c, tests/unit-mcdc/test_random_fault_whitebox.c, tests/unit-mcdc/test_random_whitebox.c, wolfcrypt/src/rng_bank.c, wolfcrypt/src/wc_port.c, wolfssl/wolfcrypt/random.h

Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Review tier: Lite

Comment thread wolfcrypt/test/test.c
}
#endif /* WC_RNG_SEED_CB && WC_RNG_HAVE_LOCK */

api_ret = rng_epoch_extra_test();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rng_epoch_extra_test() result is discarded, so failures never fail rng_epoch_test · Weak or missing assertions

The return value of rng_epoch_extra_test() goes into api_ret, which is never checked. Control then falls into out_l, which returns ret (still 0). Any failure in the new auxiliary-epoch tests is silently ignored, so the new facility has no effective test coverage in CI.

Suggested fix: Assign the result to ret, or check api_ret and ERROR_OUT(api_ret, out_l) when it is nonzero, so a failing sub-test fails rng_epoch_test.

Comment thread wolfcrypt/src/random.c
(extra_entropy_epoch_get_arg != &invalid_arg_sentinel))
{
wc_RNG_entropy_epoch_t cur_extra_entropy_epoch =
extra_entropy_epoch_get_handler(extra_entropy_epoch_get_arg);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auxiliary epoch handler pointers are read twice without atomics, so a concurrent reset can cause a NULL function call · Race conditions

current_entropy_epoch() checks extra_entropy_epoch_get_handler != NULL and then reads the global again to make the call. The global is a plain non-atomic read, and wc_RNG_extra_entropy_epoch_reset() can CAS it to NULL in between, which makes the call jump to NULL. wc_RNG_global_invalidate_entropy() has the same check-then-call pattern on entropy_epoch_extra_inv_handler (lines 515/518).

Suggested fix: Load each handler and its arg once into locals with an atomic load, test the locals, and call through the local copy.
Basis: ISO C11 5.1.2.4p25: conflicting non-atomic accesses from different threads, at least one of them a write, are a data race and undefined behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For FIPS v7 Module Related to FIPS v7.0.0 module prep for submission

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants