wolfcrypt/test/test.c: work around false positive cppcheck nullPointer warning in random_bank_test().
CMakeLists.txt, cmake/options.h.in: add WOLFSSL_SLHDSAVERIFYONLY.
wolfcrypt/src/random.c: allow WC_HAVE_RNG_BANKREF with HAVE_FIPS if WOLFSSL_FIPS_DEV.
wolfssl/wolfcrypt/random.h:
* remove WC_RNG_BANK_SUPPORT from the exclusion list for WC_RNG_LOCK_ATFORK
* pivot WC_HAVE_RNG_BANKREF on WC_RNG_WANT_BANKREF_SUPPORT, with FIPS exclusion.
wolfcrypt/src/rng_bank.c: update wc_InitRng_BankRef_local() and wc_BankRef_Release() to use WC_RNG_FLAG_BANKREF, not WC_DRBG_BANKREF.
wolfssl/wolfcrypt/rng_bank.h: remove backward-compat clause defining WC_HAVE_RNG_BANKREF.
linuxkm/lkcapi_rsa_glue.c: refactor km_rsa_ctx_init_rng() to check ctx->rng.flags, not ctx->rng.status, for bankref status.
configure.ac: in ENABLED_RNG_BANK setup, split out WC_RNG_WANT_BANKREF_SUPPORT as a separate flag, and don't define it if FIPS.
wolfcrypt/benchmark/fips_cast_bench.c: omit bench_pct_slhdsa() if defined(WOLFSSL_SLHDSA_VERIFY_ONLY).
wolfcrypt/test/test.c: in myCryptoDevCb(), add HAVE_INTEL_RDRAND to list of macros enabling use of wc_RNG_GenerateBlock() for WC_ALGO_TYPE_RNG.
linuxkm/Makefile: use bash-4.3-compatible syntax in $(()) expression.
.wolfssl_known_macro_extras: remove unneeded entries.
Gating the MOVBE store block behind CPUID made the C fallback reachable
on x86_64 CPUs without MOVBE. With WOLFSSL_AESNI, WOLFSSL_GENERAL_ALIGNMENT
is 16, so the alignment staging guarded by WOLFSSL_GENERAL_ALIGNMENT < 4 was
compiled out, leaving unaligned word32 stores to the caller's hash buffer
(LMS passes buffer + 23 in wc_hss_derive_seed_i). Make the staging
unconditional so the reversed digest is copied byte-wise into an unaligned
hash. Addresses Fenrir review on PR #11340.
CPUID can advertise AVX2 when the OS has not enabled YMM, and
wc_Sha256HashBlock emitted movbe without a MOVBE check. ML-DSA
encode_w1 also ran AVX2 asm while cpuid_flags was still
WC_CPUID_INITIALIZER.
Mask AVX* unless OSXSAVE and XCR0 allow it. Use movbe only when
CPUID reports MOVBE. Call cpuid_get_flags_ex before ML-DSA encode
dispatch.
Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
test_TLSX_Cookie_parse, test_TLSX_KeyShare_process, and
test_TLSX_ALPN_parse segfault when MEM_FAIL_CNT forces one allocation
to fail. Expect then skips the next wolfSSL_new, so ssl still holds the
object from the previous block and the following wolfSSL_free frees
that address again.
Clear ssl and ctx after each free. wolfSSL_free(NULL) does nothing, and
the next block does not use the freed object.
--enable-memorylog counts the allocation in xmalloc before the
installed allocator runs. A NULL return leaves MemFailCount Total
above Frees. Undo that count, and do the same for xrealloc of a
null pointer.
Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
WOLFSSL_AES_CONSTANT_TIME depends on !WOLFSSL_HAS_SETTINGS_FILE, but a
subsystem that extends the symbol with a default of its own is not bound
by that. wolfPSA does, so a settings-file build came out with
CONFIG_WOLFSSL_AES_CONSTANT_TIME and CONFIG_WOLFSSL_AES_TOUCH_LINES set.
user_settings.h ignores both there, because the settings file replaces
the module defaults that map them, so the .config claimed a backend the
build did not have.
Gate WOLFSSL_AES_CONSTANT_TIME_AVAILABLE on it as well. Such a default
already has to reference that symbol for the FIPS case, and
AVAILABLE has a single definition, so its depends on binds.
Every Zephyr ECC build on the module defaults accepted an all-zero digest
in wc_ecc_sign_hash() and wc_ecc_verify_hash(). PSA needs that, because
psa_sign_hash() and psa_verify_hash() treat the digest as opaque bytes,
but a non-PSA user loses wolfCrypt's guard against signing an
uninitialized buffer without asking for it.
Add the promptless WOLFSSL_ECC_ALLOW_ZERO_HASH for a consumer to select,
and define the macro only when it is set. wolfPSA selects it.
The symbol has no dependencies so that it can be selected from a build
that supplies CONFIG_WOLFSSL_SETTINGS_FILE, where WOLFSSL_ECC is not
available; a dependency would turn that select into a Kconfig warning.
In such a build the symbol is set but unused, because the settings file
replaces the module defaults and must define WC_ALLOW_ECC_ZERO_HASH
itself.
The unknown-macro check reads every CONFIG_ symbol the preprocessor
evaluates and fails on any it cannot account for.
CONFIG_WOLFSSL_AES_BITSLICED and CONFIG_WOLFSSL_AES_TOUCH_LINES are
tested with defined() in zephyr/user_settings.h, so both reach it.
The other three symbols the AES option adds do not, and are left out:
CONFIG_WOLFSSL_AES_BS_WORD_SIZE is only reachable through the
CONFIG_WOLFSSL_AES_BITSLICED branch, which no default build takes, and
CONFIG_WOLFSSL_AES_CONSTANT_TIME and its AVAILABLE companion exist only
in Kconfig and never appear in a source file.
fips-check.sh pins wolfcrypt/src/aes.c per FIPS flavor, and the older
bundles predate both backends: the tags behind FIPS v2 (WCv4-stable) and
v5 (v5.2.1-stable) contain no reference to WC_AES_BITSLICED or
WOLFSSL_AES_TOUCH_LINES at all, while WCv6.0.0-RC5 and master do.
Defining either macro against those bundles is therefore not an error,
it is a no-op. Measured on a real --enable-fips=v5 build: both macros
compiled, passed the power-on self test, and left the in-core integrity
digest byte-identical to a build without them. An integrator asking for
constant-time AES would have got the table core with nothing to say the
request had been dropped, which is worse than refusing it.
Gate the option on a new hidden WOLFSSL_AES_CONSTANT_TIME_AVAILABLE so
the set of bundles that can honour the request is stated once, here,
rather than in each subsystem that wants the guarantee. A plain
depends on is not enough: another module extending this symbol with a
default of its own is not bound by it, and the default would win.
From FIPS v6 on the macros do take effect, and change the in-core
digest: the module has to be rehashed and is no longer the validated
binary. That is the integrator's call, so it stays available there.
wolfPSA's src/psa_config.h refuses to compile against an AES core that
indexes its tables with key- or state-derived bytes, and requires
WC_ALLOW_ECC_ZERO_HASH because PSA treats the argument to
psa_sign_hash()/psa_verify_hash() as opaque bytes and an all-zero digest
is a legal input. Neither macro was reachable from Kconfig, so a Zephyr
application that relied on the module's default configuration and set no
CONFIG_WOLFSSL_SETTINGS_FILE could not be built against wolfPSA at all.
Add WOLFSSL_AES_CONSTANT_TIME as a plain bool over a choice of
WOLFSSL_AES_TOUCH_LINES (the default, leaving sizeof(Aes) unchanged) and
WOLFSSL_AES_BITSLICED. A bool over a choice rather than a three-way
choice because kconfiglib cannot select a choice member: the symbol a
subsystem defaults on has to be the requirement, leaving the
implementation to the target.
WC_AES_BS_WORD_SIZE gets its own symbol because the bitsliced key
schedule costs 30 * WC_AES_BS_WORD_SIZE^2 bytes on every Aes and Cmac.
Measured with gdb against this module's defaults, sizeof(Aes) is 328
bytes with table lookup and 2,248 / 8,008 / 31,048 / 123,208 bytes at
word sizes 8 / 16 / 32 / 64. It defaults to 16 rather than wolfCrypt's
own 64, which would put a single AES operation beyond the whole heap of
a typical part.
WC_ALLOW_ECC_ZERO_HASH gets no symbol and is defined unconditionally
wherever ECC is enabled.
linuxkm/lkcapi_sha_glue.c: in wc_linuxkm_drbg_generate_tfm(), break out of the loop unconditionally if !WC_LINUXKM_HAVE_RNG_INVALIDATION, matching other nearby generator loops.
wolfcrypt/src/random.c:
* in Hash_df() and Hash512_df(), break out of the generate loop on error.
* in Hash_DRBG_Generate() and Hash512_DRBG_Generate(), wipe output blocks on error (otherwise, future retry will recapitulate some of the same output bytes, since errors no longer leave mutated state).
* in Hash_DRBG_StirGenerate(), map error codes from Hash*_DRBG_Generate() correctly.
* in wc_RNG_GenerateBlock(), return early from failed wc_RNG_DRBG_NextSeedNow_local() for both DRBG_CONT_FIPS_E and RNG_FAILURE_E.
wolfcrypt/src/sha256.c, wolfcrypt/src/sha512.c, wolfcrypt/src/sha3.c:
* Don't exclude WOLFSSL_ASYNC_CRYPT from in-place (true) reset implementations -- the Free+Init_ex fallback silently dropped the async device binding, and async builds are compatible with in-place reset.
* Remove frivolous asserts on in-place reset implementation when WOLFSSL_KERNEL_MODE.
linuxkm/lkcapi_sha_glue.c: in wc_linuxkm_entropy_daemon(), relax the invalidation-time root_rng reseed loop with an actual sleep, to prevent flat-out retry spinning.
wolfcrypt/src/random.c: in wc_FreeRng(), wipe rng->nextStir.
wolfcrypt/src/sha3.c: fix wc_Shake128_Reset() and wc_Shake256_Reset() to properly set shake->hashType.
to assure that wc_Sha256Reset() and wc_Sha512Reset() are the no-heap-operation
in-place implementations in those builds.
wolfcrypt/src/sha256.c: gate the in-place wc_Sha256Reset() on
!WOLF_CRYPTO_CB_ONLY_SHA256.
linuxkm/lkcapi_sha_glue.c, doc/dox_comments/header_files/rng_bank.h:
Serialize whole-object RNG-bank transitions against invalidation walks: add
WC_RNG_BANK_HAVE_INST_OP_GATE (present whenever a root_rng or the next-seed
banker is), regating inst_op_gate from WC_RNG_HAVE_NEXT_SEED; bracket
wc_rng_bank_invalidate_entropy()'s full walk with a spin-acquired gate claim,
excluding it from instance and root free/reinstantiate cycles; add
wc_rng_bank_root_rng_reinit(), a gate-bracketed retire-and-reinstantiate used by
the linuxkm entropy daemon's post-invalidation last-ditch arm; fix a gate leak
in wc_rng_bank_inst_reinit()'s lock-read failure path.
Fixes for RNG invalidation handling, WC_RNG_BANK_HAVE_ROOT_RNG gating, and
CONFIG_PREEMPT_RT preemption balance:
* Pivot on WC_RNG_BANK_HAVE_ROOT_RNG for the entropy daemon's root_rng
setup/teardown, the root stats dump, and the invalidation pre/post checks,
replacing hand-spelled feature disjunctions -- glue now follows root_rng
member existence exactly, including the WC_RNG_HAVE_LOCK-only configs the
old spellings missed, and root-less configs now compile the affected
functions cleanly.
* Wipe staged output on invalidation in the user-facing paths:
wc_get_random_bytes_user() and wc_extract_crng_user() now ForceZero the
staged block on EAGAIN before the post-check. Bytes generated before an
invalidation was noticed may be live in a forked VM; wc__get_random_bytes()
already wiped, the user paths did not.
* Rework invalidation retry in wc__get_random_bytes(): retire the ad-hoc
1-second jiffies window in favor of rng_invalidation_post_check() as the
single bounding authority -- EAGAIN retries, anything else is terminal
(-ETIMEDOUT/-EBUSY/-EINTR from the post-check) -- matching the user-facing
paths.
* WC_DRBG_NEXT_STIR_LEN -> WC_RNG_NEXT_STIR_LEN ripple in
wc_mix_pool_bytes(); root stats label "wc_entropyd root" -> "default bank
root" (the stats are the bank's root's, daemon or no daemon).
* wc_lkm_LockMutex(): latch wc_linuxkm_can_block() once at entry (the
caller's context is the disposition that matters, and the function itself
toggles preemption), and on CONFIG_PREEMPT_RT kernels skip the
post-trylock preempt_enable() -- RT spin_trylock() does not disable
preemption, so re-enabling underflowed the preempt count.
Fixes for deallocation races, unpercolated errors, and gating flubs in
random.c/rng_bank.c:
* Move the NextStir aperture into WC_RNG;
* Add must-succeed DRBG health checks to new reseed APIs;
* Fix the DRBG health test error codes for consistency and specificity.
* Fixes for previously unrecovered internal SHA failures in low level DRBG
implementations (WOLFSSL_SMALL_STACK_CACHE builds only).
* Add WC_RNG_BANK_HAVE_ROOT_RNG, and consistently pivot on it throughout
wolfssl/wolfcrypt/rng_bank.h and wolfcrypt/src/rng_bank.c.
Details:
* Relocate nextStir/nextStirLen from DRBG_internal/DRBG_SHA512_internal to
WC_RNG itself, fixing a deallocation race in wc_RNG_DRBG_NextStirStore()
* The stir is generic, not DRBG-specific, making this refactor natural.
* Splits stir functionality out of wc_RNG_DRBG_NextSeedNow_Nonce_local() into
wc_RNG_DRBG_NextStirNow_local(), streamlining both.
* Pending stir material now survives DRBG reinstantiation and
condemnation-recovery reinit -- this fixes the deallocation race in
wc_RNG_DRBG_NextStirStore().
* WC_DRBG_NEXT_STIR_LEN renamed to WC_RNG_NEXT_STIR_LEN to reflect flavor independence.
* Health-test error codes:
* DRBG_CONT_FAILURE now means exactly one thing -- a ConstantCompare mismatch
in wc_RNG_HealthTestLocal(), its sole producer, signifying unrecoverable
back end cryptographic failure.
* The _ex_internal helpers return DRBG_FAILURE or BAD_FUNC_ARG rather than
blanket WC_FAILURE (generic -1).
* PollAndReSeed() propagates instead of collapsing codes together, with
percolation of distinct root causes (MEMORY_E, ENTROPY_RT_E, ENTROPY_APT_E,
seed-source errors), while positive protocol-domain codes (DRBG_FAILURE,
DRBG_CONT_FAILURE, etc.) are translated at the public boundaries.
* rng->status carries the disposition, while return carries the cause.
* Note that wc_RNG_HealthTest(_ex) with a wrong-size output now returns
BAD_FUNC_ARG, whereas previously it returned generic -1.
* Reseed error handling in wc_RNG_DRBG_Reseed_Now() and
wc_RNG_DRBG_NextSeedNow_Nonce_local():
* Fixed to force rng->status to DRBG_CONT_FAILED on KAT mismatch
(deterministic, non-retryable), returning DRBG_CONT_FIPS_E.
* Seed source failure fixed for consistency with wc_RNG_GenerateBlock(): force
rng->status to DRBG_FAILED when the reseed counter is exhausted. The seed
failure code is returned verbatim unless it is an internal code
(DRBG_FAILURE, DRBG_NO_SEED_CB, etc.), in which case RNG_FAILURE_E or
NOT_READY_E is returned, depending on whether the RNG was condemned for
failed mandatory reseed.
* Fix failure paths in Hash_df/Hash_gen/Hash_DRBG_Generate (both DRBG flavors)
in WOLFSSL_SMALL_STACK_CACHE builds:
* Unconditionally reset the cached hash context via
wc_Sha256Reset()/wc_Sha512Reset(), so a failed operation cannot leave a
partially updated context for the next use.
* Back story: wc_Sha256Final()/wc_Sha512Final() are only reachable if previous
SHA calls all succeed; on midstream failure, the existing code left the SHA
object in an indeterminate state.
* WC_RNG_BANK_HAVE_ROOT_RNG is added as a consistent marker that struct
wc_rng_bank has a root_rng member. The new macro is used to assure proper
initialization and teardown along with the bank.
restarted like the Final APIs but with no output. Plain-software configs reset
in place with no heap calls; other configs fall back to Free + Init_ex,
preserving heap hint and devId.
* wc_Sha256Reset()
* wc_Sha224Reset()
* wc_Sha512Reset()
* wc_Sha512_224Reset()
* wc_Sha512_256Reset()
* wc_Sha384Reset()
* wc_Sha3_224_Reset()
* wc_Sha3_256_Reset()
* wc_Sha3_384_Reset()
* wc_Sha3_512_Reset()
* wc_Shake128_Reset()
* wc_Shake256_Reset()
Fix error-trace machinery and add missing WC_NO_ERR_TRACE()s: errno-domain
comparisons in the PK and SHA glue and module_hooks (ENOMEM, EAGAIN, EINTR,
EBADMSG, and wolfCrypt INTERRUPTED_E/NOT_READY_E sites) now use the
-WC_NO_ERR_TRACE(E*) idiom, with .wolfssl_known_macro_extras updated to match.
Change default kernel "mutex" (spinlock) behavior: atomic-context callers now
never spin -- they trylock and fail fast -- and task-context lockers re-enable
preemption (and with it, migration) immediately after acquisition, rebalancing
the preempt count just before release. The legacy behavior -- task-context
holders promoted to non-preemptible for the duration of the hold, permitting
atomic-context callers (except NMI) to spin-wait -- remains available via a new
WC_LINUXKM_SPIN_IN_ATOMIC macro, which is #error-incompatible with
CONFIG_PREEMPT_RT; the mutex state field (.irq_flags vs .preempt_reenabled)
follows the selected regime, and wc_lkm_UnlockMutex() moves out of line (with a
pie redirect table entry).
Add pre- and post-checks bracketing DRBG operations against the invalidation
recovery window (keyed off last_invalidation_at, stamped at invalidation). The
pre-check works as a waiting room, keeping callers from generating a CAS scan
storm during the invalidation recovery interval (during which there are no
usable RNGs system-wide). In the post-check, -EAGAIN passes through for another
lap, a window overrun returns -ETIMEDOUT, atomic-context callers get one-shot
-EBUSY (blockability is checked before signal state, because in hardirq context
`current` is an unrelated task), pending signals return -EINTR, and otherwise
the caller relaxes and retries. Both checks have stubs so reduced
configurations build, and in-window messaging is ratelimited.
Add emergency reinitialization of the entropy daemon's root_rng: when the
recovery sweep finds the root invalidated, the daemon retries
wc_RNG_DRBG_Reseed_Now() with an uncredited timestamp nonce while the failure
remains retryable (BUSY_E, NOT_READY_E, ENTROPY_RT_E, ENTROPY_APT_E), relaxing
between attempts; for the default bank the reseed runs with preemption disabled
to maximize its chances. If the reseed fails terminally, the daemon makes one
last-ditch recovery via wc_FreeRng() and wc_rng_bank_root_rng_init() (or
wc_InitRng() for a standalone root); a successful reinit always clears the
invalidated state. If that too fails, the daemon exits, leaving bank instances
to self-reseed. Outcomes are reported at severities differentiated by default
vs non-default bank (pr_notice/pr_info success, pr_emerg/pr_err failure). The
daemon also now supports a standalone malloc'd root_rng where no bank features
are built, instantiated at startup and freed on exit.
Also:
* wc_linuxkm_drbg_generate_tfm(): retry loop around the invalidation window
replaces the single-shot call; output buffer is zeroized on terminal error.
* wc__get_random_bytes(): honors the recovery window, and zeroizes its
staging buffer both before retry re-entry and on the error exit. An
invalidation may be peculiar to this VM and leave the bytes live in another
VM, so they are wiped when abandoned, as possible CSP elsewhere.
* wc_linuxkm_entropy_daemon(): the registered-leaf recovery pass is now
additionally gated on WC_LINUXKM_HAVE_RNG_REGISTRY, matching its actual
dependency; seed health test failures (ENTROPY_RT_E/ENTROPY_APT_E) on bank
instances are now reported unconditionally at pr_warn_ratelimited severity
("entropy source suspect"), rather than pr_err only under WC_VERBOSE_RNG;
the WC_RNG_DEBUG_STATS dump at daemon exit is removed (was redundant).
* wolfcrypt/test/test.c: SVR access-counter checks now additionally gated on
new WC_SVR_HAVE_FLAGS, matching the configurations that actually maintain
the counters.