Skip to content

20260727-fips-dev-no-post - #11031

Open
douzzer wants to merge 38 commits into
wolfSSL:masterfrom
douzzer:20260727-fips-dev-no-post
Open

20260727-fips-dev-no-post#11031
douzzer wants to merge 38 commits into
wolfSSL:masterfrom
douzzer:20260727-fips-dev-no-post

Conversation

@douzzer

@douzzer douzzer commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

tested with

wolfssl-multi-test.sh ... all

@douzzer
douzzer marked this pull request as draft August 1, 2026 03:46
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

gcc-arm-cortex-m4

  • FLASH: .rodata.CSWTCH.1 +8 B, .rodata.str1.1 +121 B (+0.1%, 201,174 B / 262,144 B, total: 77% used)

gcc-arm-cortex-m4-crypto-only

  • FLASH: .rodata.CSWTCH.1 +8 B, .rodata.str1.1 +121 B (+0.1%, 175,185 B / 262,144 B, total: 67% used)

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .rodata +128 B, .text +64 B (+0.0%, 772,268 B / 1,048,576 B, total: 74% used)

gcc-arm-cortex-m4-pkcs7

  • FLASH: .rodata.CSWTCH.1 +8 B, .rodata.str1.1 +121 B (+0.1%, 214,037 B / 262,144 B, total: 82% used)

gcc-arm-cortex-m4-pq

  • FLASH: .rodata +128 B (+0.0%, 280,256 B / 1,048,576 B, total: 27% used)

gcc-arm-cortex-m4-rsa-only

  • FLASH: .rodata +128 B (+0.0%, 326,744 B / 1,048,576 B, total: 31% used)

gcc-arm-cortex-m4-tls13

  • FLASH: .rodata.CSWTCH.1 +8 B, .rodata.str1.1 +121 B (+0.1%, 236,936 B / 262,144 B, total: 90% used)

gcc-arm-cortex-m7

  • FLASH: .rodata.CSWTCH.1 +8 B, .rodata.str1.1 +121 B, .text +64 B (+0.1%, 201,174 B / 262,144 B, total: 77% used)

gcc-arm-cortex-m7-pq

  • FLASH: .rodata +128 B (+0.0%, 280,832 B / 1,048,576 B, total: 27% used)

gcc-arm-cortex-m7-tls13

  • FLASH: .rodata.CSWTCH.1 +8 B, .rodata.str1.1 +121 B (+0.1%, 237,000 B / 262,144 B, total: 90% used)

linuxkm-pie

  • Data: __patchable_function_entries +8 B (+0.0%, 26,360 B)

linuxkm-standard

  • Data: __patchable_function_entries -8 B (-0.0%, 49,104 B)

stm32-sim-stm32h753

@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 #11031

Scan targets checked: linuxkm-bugs, linuxkm-src, wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src
Findings: 5
4 finding(s) posted as inline comments (see file-level comments below)

Medium (1)

Unguarded verifyCore reference in non-PIE FIPS seg_map under WOLFSSL_FIPS_DEV_NO_POST

File: linuxkm/module_hooks.c:1291
Function: seg_map (file-scope, #elif defined(HAVE_FIPS) branch)
Category: Incorrect error handling

The extern declaration of verifyCore (line 119) is now gated with !defined(WOLFSSL_FIPS_DEV_NO_POST), and the primary seg_map initializer (line 1223) got the matching && !defined(WOLFSSL_FIPS_DEV_NO_POST) guard, but the parallel seg_map used when WC_SYM_RELOC_TABLES is undefined (line 1290) was not updated to match, so it references the undeclared verifyCore symbol when building with --enable-fips=dev-no-post and PIE reloc tables disabled.

Recommendation: Add && !defined(WOLFSSL_FIPS_DEV_NO_POST) to the #if at line 1290, matching line 1223.

Referenced code: linuxkm/module_hooks.c:1291-1294 (4 lines)


This review was generated automatically by Fenrir. Findings are non-blocking.

@douzzer
douzzer force-pushed the 20260727-fips-dev-no-post branch from c212bc1 to 107fc6d Compare August 3, 2026 04:17

@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 #11031

Scan targets checked: linuxkm-bugs, linuxkm-src, wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src

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

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread linuxkm/lkcapi_sha_glue.c
Comment thread linuxkm/lkcapi_sha_glue.c
@douzzer
douzzer force-pushed the 20260727-fips-dev-no-post branch from 107fc6d to 976257d Compare August 3, 2026 23:52

@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 #11031

Scan targets checked: linuxkm-bugs, linuxkm-src, wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src

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

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread linuxkm/x86_vector_register_glue.c
Comment thread src/internal.c
douzzer added 19 commits August 3, 2026 22:29
…avx and

-mavx2 AX_APPEND_COMPILE_FLAGS. gcc emits AVX instructions unbidden under those
flags (e.g. for 128-bit types) in code paths that cannot be runtime-dispatched
on cpuid, leading to invalid-opcode crashes on CPUs lacking AVX (e.g. Westmere).
…VALUE_E

"Supplied value was rejected by FIPS policy" and FIPS_UNAPPROVED_E "Requested
operation succeeded, but supplied parameters are unapproved for FIPS".  The
first is a new fatal error, the second is a new nonfatal error to which
WC_FIPS_NOT_APPROVED will be bound.
…SM when not

already set, so settings.h can distinguish assembly translation units.

wolfssl/wolfcrypt/settings.h: in the config-source selection, when
BUILDING_WOLFSSL_ASM && WOLFSSL_USER_SETTINGS_ASM, include user_settings_asm.h
(the assembly-safe, directives-only header produced by user_settings_asm.sh)
instead of user_settings.h, which may contain C that breaks the assembler.

wolfcrypt/src/aes_asm.S: drop the file's bespoke copy of the user_settings_asm.h
selection block and route through libwolfssl_sources_asm.h, so the choice lives
in one place. (aes_asm.S is the only .S that open-coded this.) Also add `#define
WC_FIPS_LL_CRYPTO` immediately above the new include.
…s before

including libwolfssl_sources.h, replacing the previous per-file `#define
FIPS_NO_WRAPPERS` that was placed *after* the include and therefore never took
effect. Low-level crypto TUs stop carrying a per-file opinion about wrapper
generation; settings.h now derives FIPS_NO_WRAPPERS centrally. des3.c and
wolfentropy.c newly acquire FIPS_NO_WRAPPERS (they had none). port/st/stm32.c
converts to the same idiom (drops its HAVE_CONFIG_H/config.h + redundant types.h
block).

Note on scope: FIPS_NO_WRAPPERS governs how the *including* TU resolves its own
outbound calls -- it does not change what the file makes available to others,
beyond defining the FIPS-supported APIs without the `_fips()` extension the
wrappers arrange. The pre-existing effect of the misplacement was that
boundary-internal calls resolved to the wrapped forms, i.e. took an unintended
round-trip back out through the wrappers.

wolfssl/wolfcrypt/settings.h: derive FIPS_NO_WRAPPERS from
(WC_FIPS_LL_CRYPTO || WOLFSSL_FIPS_DEV_NO_POST) under HAVE_FIPS, positioned
after the config-source selection so it sees HAVE_FIPS regardless of whether it
arrived via command line or user_settings.h.
…, MAJOR=8)

and AM_CONDITIONAL BUILD_FIPS_NO_POST. Refactor FIPS dev/ready version setup:
hoist ENABLED_FIPS_DEV / ENABLED_FIPS_READY to set -DWOLFSSL_FIPS_DEV /
-DWOLFSSL_FIPS_READY centrally, and switch the FIPS AS_CASE arms from
`test "$FIPS_VERSION" != "dev"` to `test "$ENABLED_FIPS_DEV" != "yes"` so the
dev semantics extend to v5-dev/v6-dev/lean-aesgcm-dev.

src/include.am: under !BUILD_FIPS_NO_POST, drop fips.c / fips_test.c /
wolfcrypt_first.c / wolfcrypt_last.c from the build (dev-no-post uses no fips
repo content).

wolfssl/wolfcrypt/settings.h, wolfssl/wolfcrypt/wc_compat.h: under
WOLFSSL_FIPS_DEV_NO_POST, squat WOLF_CRYPT_FIPS_H to inhibit fips.h, and change
the FIPS_READY/DEV version block guard to `!defined(HAVE_FIPS_VERSION)`
(required so an externally supplied version is not clobbered).

wolfssl/wolfcrypt/fips_test.h: add WOLFSSL_FIPS_DEV_NO_POST stub block
(fipsCastStatus_get, the PRIVATE_KEY macros) so master builds without the fips
repo.

linuxkm/linuxkm_wc_port.h, linuxkm/module_hooks.c: accommodate
WOLFSSL_FIPS_DEV_NO_POST (guard verifyCore / CAST / fencepost paths that the
fips repo would otherwise provide; force WC_USE_PIE_FENCEPOSTS_FOR_FIPS).

wolfcrypt/test/test.c: in hmac_sha256_test(), don't expect HMAC_KAT_FIPS_E in
WOLFSSL_FIPS_DEV_NO_POST builds.

wolfssl/wolfcrypt/types.h: add stub macro for
wolfCrypt_SetPrivateKeyReadEnable_fips() when WOLFSSL_FIPS_DEV_NO_POST.
…ure unconditional matching of PRIVATE_KEY_UNLOCK() regardless of intervening error code collection.
is_enabled, WC_DH_INITIAL_RUNTIME_ENABLEMENT, WC_DH_HAVE_RUNTIME_ENABLEMENT.
Place the enablement check AFTER key->heap/trustedGroup init in the five entry
points (wc_InitDhKey_ex, wc_DhGenerateKeyPair, wc_DhAgree, wc_DhAgree_ct,
_DhSetKey) so a disabled-DH early return never leaves a half-initialized key for
wc_FreeDhKey to mp_clear on garbage.

configure.ac: add --enable-dh=conditional; when DH is enabled (directly or via
all-crypto) set it initially usable under FIPS v7 with
-DWC_DH_INITIAL_RUNTIME_ENABLEMENT=1; remove the FIPS-v7 DH force-off (in FIPS
v7+, disable build by default, unless building in kernel mode with DH
registration enabled).

linuxkm/lkcapi_glue.c: bracket LKCAPI registration with
`need_dh_disable = (wc_dh_enable() == 0)` ... `if (need_dh_disable)
wc_dh_disable();`, so DH is disabled on every exit path, and only by the caller
that actually enabled it (wc_dh_enable returns ALREADY_E if DH was already on,
so this never disables a DH some other context legitimately enabled).

tests/unit.c, wolfcrypt/test/test.c: bracket the DH tests with enable/disable so
they succeed regardless of runtime initial default enablement.
…12) with

FIPS_BAD_VALUE_E in the GCM IV-construction paths under HAVE_FIPS, overridable
by WC_FIPS_AESGCM_ALLOW_SHORT_NONCES. Decrypt accepts any supported length per
SP 800-38D (IV construction requirements bind encryption only).

The floor takes two shapes, both correct by construction:
  - wc_AesGcmInit_local (reached from wc_AesGcmInit and
    wc_AesGcmEncryptInit_ex, which pass a decrypt_p flag):
        (ret == 0) && (! decrypt_p) && (ivSz > 0) && (ivSz < GCM_NONCE_MID_SZ)
    The `ivSz > 0` clause is load-bearing -- iv is an optional argument there,
    and the key-only re-init form (iv == NULL, ivSz == 0) used for
    module-generated-IV streaming must still pass.
  - wc_AesGcmSetIV / wc_AesGcmSetExtIV: bare `ivSz < GCM_NONCE_MID_SZ`, no
    ivSz>0 clause needed -- CheckAesGcmIvSize() already admits only {8,12,16},
    so ivSz == 0 cannot reach the floor.

tests/api/test_aes.c: update tests for new FIPS nonce size restrictions.

.wolfssl_known_macro_extras: add WC_FIPS_AESGCM_ALLOW_SHORT_NONCES.
wolfcrypt/src/cmac.c: on _InitCmac_common failure free the Aes and set
cmac->type = WC_CMAC_NONE, so a contract-violating wc_CmacFree on a
never-initialized object hits a no-op arm instead of re-entering wc_AesFree;
add explicit case WC_CMAC_NONE arms to the three type switches
(wc_CmacUpdate, wc_CmacFree, wc_CmacFinalNoFree).
(unversioned defined(HAVE_FIPS), not a version arm -- hmac.c is in-boundary and
master's copy only compiles at v7+/MAJOR=8). This structurally closes the
old-TLS MD5 PRF: wc_PRF_TLSv1 -> wc_PRF(md5_mac) -> wc_HmacSetKey(WC_MD5) ->
BAD_FUNC_ARG. Separately, in wc_HKDF_Expand_ex, add `else if (ret == 0) return
BAD_FUNC_ARG;` after the wc_HmacSizeByType call: the existing code guarded
ret < 0 but not ret == 0, and hashSz is the divisor in the
`outSz/hashSz + ((outSz % hashSz) != 0) > 255` check three lines below.

wolfcrypt/src/kdf.c: delete the two WC_HASH_TYPE_MD5_SHA guards in wc_PRF /
wc_PRF_TLS -- they were a domain error (that arg is wc_MACAlgorithm, where
WC_HASH_TYPE_MD5_SHA == 9 == sm3_mac, so the guard blocked SM3, not MD5-SHA),
and the hmac.c reject is the correct layer.

wolfcrypt/src/evp.c: drop the MD5 EVP mapping at FIPS >= 5 (evp.c is out of
boundary, so the version arm is live and correct here).

tests/api/test_kdf.c: derive secLen from MAX_PRF_HALF rather than hardcoding
521/261 -- MAX_PRF_HALF is config-dependent (516 under HAVE_FFDHE_8192, 388
under FFDHE_6144, else 260), so the hardcoded value made the BUFFER_E
expectation config-dependent.
* in AllocKey capture and propagate the return of the per-type wc_*_init_ex
  calls (ed25519, ed448, falcon, ML-DSA, ML-KEM, ...) instead of discarding it,
  so an init failure surfaces rather than leaving a partially-constructed key
  for later use.

* The `default:` arm of the type switch now sets `ret = BAD_FUNC_ARG` and
  breaks, instead of returning directly, so it reaches the common cleanup.

* The failure cleanup distinguishes the two states: if the key was initialized,
  FreeKey(); otherwise XFREE(*pKey) and NULL the caller's pointer -- previously
  an allocation that failed before init leaked.

* Two mis-copied #endif comments corrected: HAVE_CURVE25519 -> HAVE_ED25519 and
  HAVE_CURVE448 -> HAVE_ED448.
…EN(name) ->

`.hidden name` macro under __ELF__, currently empty under !__ELF__.

wolfcrypt/src/*.S, wolfcrypt/src/port/{arm,ppc32,ppc64,riscv64}/*.S: emit
WC_ASM_ATT_HIDDEN for internal ATT-syntax symbols so they don't become
dynamic-table entries or otherwise pollute symbol namespace beyond the
library/module.
…R_SPEEDUPS

definition (any asm speedup present, minus WOLFSSL_NO_ASM) from types.h to
settings.h, and add `#error WC_C_DYNAMIC_FALLBACK requires WC_HAVE_VECTOR_SPEEDUPS`
so a fallback-to-C build with no asm to fall back from is rejected at configure
time rather than mis-building.
wolfcrypt/src/rsa.c: wrap wc_hash2mgf in a targeted -Wswitch-enum pragma

configure.ac: rename $ENABLE_ORIGINAL -> $ENABLE_ORIGINAL_KYBER to disambiguate.

wolfssl/wolfcrypt/types.h: tighten a braced-group guard with __STRICT_ANSI__
(pedantic-mode correctness).

wolfssl/internal.h: add the WOLFSSL_API_PREFIX_MAP mapping for TLSX_CKS_Parse.
Refactor WC_C_DYNAMIC_FALLBACK architecture to allow per-call alternation
between asm and C:

* Under WC_C_DYNAMIC_FALLBACK keep the block buffer as the raw big-endian stream
and byte-reverse just-in-time inside the C transform, so a given wc_Sha256 /
wc_Sha512 instance may switch between the vectorized and pure-C transforms per
call without producing a wrong digest.

* Add Transform_*_C_from_raw / Transform_*_Len_C_from_raw JIT-reversing
adapters; the dispatchers early-out through them on (method == C) ||
SAVE_VECTOR_REGISTERS2 failure; caller-side method-keyed ByteReverse sites are
compiled out under the raw-buffer convention and the final block's length words
are written unconditionally big-endian.

* Remove the init-time CAN_SAVE_VECTOR_REGISTERS pin from Sha*_SetTransform so
the recorded method reflects pure CPU capability (enabling fall-forward, not
only fallback).  Update the bulk paths to check the transform return and not
advance on failure.

* The raw-buffer convention is scoped to WC_C_DYNAMIC_FALLBACK specifically --
not to WC_NO_INTERNAL_FUNCTION_POINTERS -- because only the fallback build can
change transform mid-object; a plain no-function-pointers build picks one method
and keeps it, so it retains the conventional host-endian buffer (no change from
incumbent code).

* Drop the per-object `.sha_method` member.  Method selection is a property of
the CPU, not of the hash object, so it becomes a file-scope static in each .c,
set once (Sha*_SetTransform() early- returns when already set) and read by every
instance.  Shrinks both structs.

* When WOLFSSL_AESNI is enabled without the rest of USE_INTEL_SPEEDUP, `#undef
WC_C_DYNAMIC_FALLBACK` -- AES-NI alone satisfies WC_HAVE_VECTOR_SPEEDUPS but
leaves SHA with no vectorized transform to fall back from, and the caller-side
gating would otherwise suppress a byte-reversal that is still required.
WOLFSSL_DEBUG_TRACE_ERROR_CODES support for internal DRBG errors.

Converts the DRBG internal status #defines (DRBG_SUCCESS/DRBG_FAILURE,
WC_DRBG_*) to enums, that are wrapped in WC_ERR_TRACE() when
WOLFSSL_DEBUG_TRACE_ERROR_CODES.

Deploys well-known error codes and WC_NO_ERR_TRACE() as needed throughout.
…i_rsa_glue.c, linuxkm/lkcapi_sha_glue.c, wolfcrypt/test/test.c:

* Use defined(WC_HAVE_RNG_BANKREF), not defined(WC_RNG_BANK_SUPPORT), as the feature sensor for RNG bankrefs.

* Add DRBG_KAT_FIPS_E and DRBG_CONT_FIPS_E to the list of immediate-failure errors in wc_rng_bank_init().
douzzer added 19 commits August 4, 2026 01:01
…sm}:

The AVX2 constant-time table-lookup routines seed a broadcast vector with a
legacy-SSE GPR->XMM move (movd/movq), which writes bits [127:0] and leaves
[255:128] UNMODIFIED, then read the register at full YMM width via
vpermd %ymm,%ymm(zeroed),%ymm (a lane-0 broadcast across all 256 bits). If a
prior vector op left the upper lane non-zero, the broadcast is corrupt and the
constant-time selection returns the wrong table entry -- a wrong ECC point/entry
in sp_{256,384,521}_get_{point_33,entry_64,entry_65}_avx2 and
sp_{2048,3072,4096}_get_from_table_avx2, or a wrong X25519 public key from
fe_cmov_table_avx2. Deterministic given register history; surfaces as
intermittent failures because it depends on the upper lane being dirty on entry.
Under kernel_fpu_begin (which does not zero YMM) a dirty upper lane is ambient,
which is why ED25519 asm was kept disabled in kernel mode. Fix: emit the VEX
form (vmovd for 32-bit source, vmovq for 64-bit), which zeroes [255:128].
…, wolfcrypt/test/test.h, wolfcrypt/test/test.c: Falcon fixes and cleanups:

wolfcrypt/src/falcon.c:

* define _WC_BUILDING_FALCON_C;

* add #error arch guards -- WOLFSSL_FALCON_FPR_ASM requires x86-64
(wc_falcon_fpr_x86_64_asm.S), WOLFSSL_FALCON_FFT_AVX2 requires an x86 target,
WOLFSSL_FALCON_FFT_NEON requires AArch64 (ARM32 NEON lacks the double-precision
lanes used by float64x2_t);

* drop the unused FALCON_PRIMES forward declaration;

* fix u->U literals and an (sword64)z0*(sword64)z0 overflow;

* tightened __uint128_t guard.

wolfcrypt/benchmark/benchmark.c:

* falcon message buffer -> WC_ALLOC_VAR;

* bench wiring for the experimental algs.

wolfcrypt/test/test.h: add frodokem_test / falcon_test externs.

wolfcrypt/test/test.c: mldsa/falcon WC_ALLOC_VAR conversions.

configure.ac: update all-quantum-crypto with the experimental algorithms.
…_func() /

err_sys_with_errno_func() taking __FILE__ and __LINE__, with function-like
macros preserving every existing call site; failure messages now carry file and
line ("wolfSSL error, %s L %d: %s").

tests/suites.c: client_test / server_test failure reports go to stderr
(printf -> fprintf(stderr, ...)).
…tions:

Under WC_C_DYNAMIC_FALLBACK, SAVE_VECTOR_REGISTERS2() can fail on any call, so
two calls on the same object can dispatch differently.  Each of these
algorithms had state that silently assumed a single dispatch for its lifetime.

wolfcrypt/src/wc_mldsa.c: add MLDSA_NTT_AVX2()/MLDSA_INVNTT_AVX2() selecting
the "full" AVX2 NTT/invNTT under WC_C_DYNAMIC_FALLBACK.  The non-full variants
leave NTT-domain coefficients in a permuted, lane-interleaved order that only
their matching consumers understand, whereas the full variants and the C
implementations use standard order.  NTT-domain data at rest (cached s1/s2/t0
vectors, the challenge polynomial) can be produced and consumed by
differently-dispatched calls, so its representation must be dispatch-invariant.
Without fallback, dispatch is invariant and the ~2%/~4% faster permuted-order
variants are kept.  Both pipelines are bit-identical end to end.

wolfcrypt/src/wc_mlkem_poly.c: in mlkem_derive_secret(), re-initialize the
shared SHAKE-256 object under WC_C_DYNAMIC_FALLBACK.  The buffer-stuffing
shortcut assumes a freshly initialized (zeroed) sponge, which no longer holds
once the C fallback legs of mlkem_gen_matrix()/mlkem_get_noise() drive the XOF
on that object and leave it mid-squeeze.

wolfcrypt/src/wc_slhdsa.c: in slhdsakey_fors_sign(), replace the
CAN_SAVE_VECTOR_REGISTERS() test with an actual SAVE_VECTOR_REGISTERS2() == 0
acquisition and a matching RESTORE_VECTOR_REGISTERS(), so the region is held
rather than merely predicted to be available.

wolfcrypt/src/wc_frodokem_mat.c: in the AES row kernels of
frodokem_mul_add_as_plus_e_aes() and frodokem_mul_add_sa_plus_e_aes(), re-key
with wc_AesSetKeyDirect() when IS_INTEL_AESNI() but !aes->use_aesni.  The
kernels consume aes->key directly, which holds an AES-NI-layout schedule only
if SetKey ran with vector registers available; under fallback a failed
SAVE_VECTOR_REGISTERS2() inside SetKey returns success having keyed only the
C-fallback schedule.  Re-keying happens inside the held region, where the
nested save always succeeds.  Loop conditions gain (ret == 0) so a re-key
failure stops the run.

wolfssl/wolfcrypt/settings.h: with the above, ML-KEM, ML-DSA, SLH-DSA and
FrodoKEM are fuzzer-clean, so the DEBUG_VECTOR_REGISTER_ACCESS_FUZZING
exclusion narrows from the _WC_BUILDING_WC_MLKEM_POLY_C / _WC_BUILDING_WC_MLDSA_C
/ _WC_BUILDING_WC_SLHDSA_C set to _WC_BUILDING_FALCON_C alone.  Falcon stays
excluded because it uses FP or vector registers in all of its asm
implementations and there is no option yet to build the C-no-FP implementation
alongside them.

tests/api/test_mldsa.c: in test_mldsa_encode_w1_large_values(), pin dispatch to
the C path with WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL() for the duration of the
test and restore it afterward.  The two calls being compared are only specified
-- and only equal -- on the valid input domain, so letting the fuzzer send them
down different (AVX2 vs C) implementations is not a meaningful comparison.
MAYBE_INHIBIT vector-register save mode for the convenience of the DRBG glue
logic.

Add WC_SVR_FLAG_MAYBE_INHIBIT = 2 (WC_SVR_FLAG_FUZZ becomes 4), and add
SAVE_VECTOR_REGISTERS_MAYBE_INHIBIT() / RESTORE_VECTOR_REGISTERS_MAYBE_INHIBITED()
macros, routing through wc_{save,restore}_vector_registers_x86(WC_SVR_FLAG_MAYBE_INHIBIT).

linuxkm/x86_vector_register_glue.c: implement the mode.  A _MAYBE_INHIBIT call
must be outermost (BAD_STATE_E otherwise, and a warning on the matching restore
at non-outermost depth).  The fuzzer check moves ahead of the inhibit decision
so that a fuzzed failure converts into an inhibited (rather than failed)
acquisition when _MAYBE_INHIBIT is set; a real inability to use SIMD
(preempt_count() != 0 && !may_use_simd()) does the same.  The restore path
treats _MAYBE_INHIBIT like _INHIBIT when deciding whether registers were
actually taken.

Note, under fuzzer vector disablement,
wc_save_vector_registers_x86(WC_SVR_FLAG_MAYBE_INHIBIT) returns 0 with affinity
locked, as though explicit WC_SVR_FLAG_INHIBIT were passed.  Thus on 0 return,
the caller must use `CAN_SAVE_VECTOR_REGISTERS()` to discover whether vector
registers are actually usable.
… SAVE_VECTOR_REGISTERS_MAYBE_INHIBIT() and RESTORE_VECTOR_REGISTERS_MAYBE_INHIBITED(), and in wc_linuxkm_rng_bank_init(), disable vector ops only if FIPS <v7.
…tement-expr

definitions with __extension__ at both arms (the fuzzing arm and the plain arm)
so -pedantic builds (which the kernel-settings CI configs use) don't drown in
"ISO C forbids braced-groups within expressions" across the hundreds of
expansion sites.
…nable-fips=dev-no-post.

Notes:

* EXTRA_CPPFLAGS carries -Werror in the base configure line, because the
  autotools -Werror is gated on a VCS checkout being detected in the configure
  CWD and these are VPATH builds, which would otherwise silently get no -Werror
  at all.

* The fuzzing cell's WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED is $$, which changes
  from run to run.

* The two out-of-tree kernel-module cells (linuxkm, linuxkm-all-asm) are
  commented out, with a note that out-of-tree module builds don't work yet.
…PTO_FIPS) != defined(HAVE_FIPS) more informative.
…iables

exported to the linuxkm sub-make.

linuxkm/Kbuild:
* Feature-detect $(intcmp) (GNU make >= 4.4) into $(HAVE_INTCMP).
* Derive FIPS_OPTEST_NO_DH from $(HAVE_FIPS_VERSION_MAJOR) via $(intcmp) when
  available; otherwise $(error) with instructions to supply it on the make
  command line. When set, build the optest wrapper with -DNO_DH -- DH is not
  optested at FIPS v7+ even when the module has DH, because its APIs have no
  FIPS wrappers.
* Same $(intcmp)/$(error) treatment for NO_PIE_FLAG (target kernel < 5.11), and
  change its test from `ifdef NO_PIE_FLAG` to an explicit
  `ifeq "$(NO_PIE_FLAG)" "0"` so an explicitly-zero value means what it says.
* Add $(CFLAGS_AUTO_VECTORIZE_DISABLE) to benchmark.o ccflags-y and drop its
  unused asflags-y line.
…IPS_DEV from the gate for implicit defining of WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST.
…SL_DEBUG_TRACE_ERROR_CODES_SUPPORT, facilitating opt-in per-file error tracing in debug campaigns.
…a_param_*_vfy_test(), test_mldsa_decode_level(), and mldsa_test().
…pt/src/sha3_asm.asm, wolfcrypt/src/wc_mlkem_asm.asm: synchronize with current generator scripts.
@douzzer
douzzer force-pushed the 20260727-fips-dev-no-post branch from 547791b to e42afa6 Compare August 4, 2026 07:04
@douzzer
douzzer marked this pull request as ready for review August 4, 2026 07:04
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

retest this please

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants