20260727-fips-dev-no-post - #11031
Conversation
|
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
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.
c212bc1 to
107fc6d
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
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.
107fc6d to
976257d
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
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.
547791b to
e42afa6
Compare
|
retest this please |
Frauschi
left a comment
There was a problem hiding this comment.
🐺 Skoll Code Review
Overall recommendation: REQUEST_CHANGES
Findings: 33 total — 24 posted, 10 skipped
Posted findings
- [Critical] Infinite recursion in Transform_Sha512() C-fallback path — self-call replaced _Transform_Sha512() —
wolfcrypt/src/sha512.c:1287-1288 - [High] WC_C_DYNAMIC_FALLBACK raw-buffer gating in sha512.c is not scoped to the x86-64/AVX backend, producing wrong digests —
wolfcrypt/src/sha512.c:2013,2248,2304,2610 - [High] Removing the per-context sha_method field leaves two dangling references in tests/swdev/swdev.c —
tests/swdev/swdev.c:352,448 - [High] wc_AesGcmInit() hardcodes encrypt mode, so the FIPS short-nonce rejection breaks AES-GCM decryption via the public streaming API and the EVP compat layer —
wolfcrypt/src/aes.c:14078-14082, 13992-14002 - [High] wc_InitDhKey_ex() returns FIPS_NOT_ALLOWED_E leaving the mp_ints uninitialized, and src/tls.c then frees them —
wolfcrypt/src/dh.c:966-973 - [High] --enable-fips=v5-kcapi silently loses every "-dev" feature override —
configure.ac:657-664 - [High] FIPS_DEVREADY_MAJOR=7 contradicts commit 606415c's stated MAJOR=8, and makes ready/dev/dev-no-post indistinguishable from v7 —
configure.ac:695-704 - [Medium] kernel-settings "-dh" reset leaves enable_dh set-but-empty, defeating AC_ARG_ENABLE's default and building DH when it should be excluded —
configure.ac:1886-1891 - [Medium] WC_DH_INITIAL_RUNTIME_ENABLEMENT=1 only triggers on an exact enable_dh=yes, so --enable-dh=nonblock and --enable-openssh build permanently-disabled DH —
configure.ac:6362-6369, 1744 - [Medium] bench_falconKeySign() never checks WC_ALLOC_VAR results, NULL-dereferencing msg on allocation failure —
wolfcrypt/benchmark/benchmark.c:15806-15847 - [Medium] mldsa_param_{44,65,87}_vfy_test() double-encode an already WC_TEST_RET_ENC-encoded return value —
wolfcrypt/test/test.c:56147-56160, 57149-57162, 58510-58523 - [Medium] random.c: two DRBG_FAILURE comparisons were not converted to WC_NO_ERR_TRACE —
wolfcrypt/src/random.c:816, 1014 - [Medium] wc_dh_enable()/wc_dh_disable() are a non-atomic read-modify-write on a plain volatile int —
wolfcrypt/src/dh.c:60-81 - [Medium] wc_DhGeneratePublic() and wc_DhGenerateParams() are not covered by the DH enablement check —
wolfcrypt/src/dh.c - [Medium] linuxkm_affinity_lock can now fail with INTERRUPTED_E / WC_ACCEL_INHIBIT_E, which wc_rng_bank_checkout treats as fatal —
linuxkm/lkcapi_sha_glue.c:2068-2094 - [Low] FIPS_UNAPPROVED_E error string is missing a space at the concatenation boundary —
wolfcrypt/src/error.c:746-748 - [Low] wc_frodokem_mat.c re-key blocks read aes->use_aesni, which only exists under WOLFSSL_AESNI —
wolfcrypt/src/wc_frodokem_mat.c:1732-1742, 2054-2064 - [Low] falcon.c: wc_MemZero_Add registers sizeof(pointer) instead of sizeof(falcon_sampler_ctx) —
wolfcrypt/src/falcon.c:8313-8314 - [Low] configure --help prints the literal string ${ENABLED_DH_DEFAULT} for --enable-dh —
configure.ac:6379 - [Low] fips-dev-no-post.yml: the fuzzing seed is the shell PID and is never echoed, and the adjacent comment about '$' in the heredoc is now wrong —
.github/workflows/fips-dev-no-post.yml:87-89,116 - [Low] sha256.c: #undef WC_C_DYNAMIC_FALLBACK precedes the header includes, so this TU can see a different struct layout —
wolfcrypt/src/sha256.c:46-53, wolfcrypt/src/sha512.c:68-76 - [Low] tests/api/test_cmac.c drops KCAPI coverage without explanation —
tests/api/test_cmac.c:374-378, 421-425 - [Low] tests/unit.c uses wc_dh_enable()/WC_DH_HAVE_RUNTIME_ENABLEMENT without including dh.h —
tests/unit.c:82-84 - [Info] falcon.c: FALCON_MULHI now additionally requires HAVE___UINT128_T, silently dropping to the 4-multiply fallback —
wolfcrypt/src/falcon.c:1152-1156
Skipped findings
- [High] --enable-fips=v7 no longer defines WOLFSSL_FIPS_READY, flipping the build from FIPS 186-4 to 186-5
- [High] AES-GCM short-nonce rejection is gated on HAVE_FIPS with no version qualifier, changing behavior of shipped FIPS v5/v6 modules and breaking their tests
- [High] Out of scope: 24 cicd findings on CI files this PR does not touch
- [Medium] Already answered by the commit messages -- intentional, with stated rationale
- [Medium] test_wc_AesGcmDecisionCoverage / test_wc_AesGcmArgMcdc expectations do not match the implementation's FIPS gating
- [Medium] FIPS optest -DNO_DH rule names a target kbuild never builds, so the flag is silently dropped
- [Low] settings.h dropped the #undefs before defining HAVE_FIPS_VERSION_MAJOR/_MINOR/_PATCH
- [Low] x86_vector_register_glue.c: new fuzzing code has a misindented unbraced warning and assigns an out-of-enumeration value to the enum-typed flags parameter
- [Info] falcon.c: WC_DECLARE_VAR heap argument reads as a dereference before the NULL check
- [Medium] wc_DhGeneratePublic() and wc_DhGenerateParams() are not covered by the DH enablement check
Review generated by Skoll via Claude/Codex
|
|
||
| if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) { | ||
| #if defined(LITTLE_ENDIAN_ORDER) | ||
| #if defined(LITTLE_ENDIAN_ORDER) && !defined(WC_C_DYNAMIC_FALLBACK) && \ |
There was a problem hiding this comment.
🟠 [High] WC_C_DYNAMIC_FALLBACK raw-buffer gating in sha512.c is not scoped to the x86-64/AVX backend, producing wrong digests
🚫 BLOCK bug
The new raw-big-endian buffer convention requires that, when WC_C_DYNAMIC_FALLBACK is set, the unconditional ByteReverseWords64() calls in Sha512Update(), Sha512Final() (padding and length words) and wc_Sha512Transform() be suppressed, because the compensating just-in-time reversal now lives in Transform_Sha512_C_from_raw(). The diff added && !defined(WC_C_DYNAMIC_FALLBACK) at the OUTER guard of all four sites — but Transform_Sha512_C_from_raw() is only compiled inside the #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && (HAVE_INTEL_AVX1||HAVE_INTEL_AVX2) section. In any configuration where WC_C_DYNAMIC_FALLBACK is defined but that section is NOT compiled, Transform_Sha512() collapses to plain _Transform_Sha512(), which reads host-endian words, while the buffer now holds raw big-endian bytes that are never reversed. Result: silently incorrect SHA-512/SHA-384 digests with no error returned. Two concrete reachable configs: (1) a user_settings.h that sets WC_C_DYNAMIC_FALLBACK together with WOLFSSL_SP_ASM only — the new auto-#undef added at sha512.c:68-76 only tests WOLFSSL_AESNI, so it does not fire; (2) 32-bit x86 --enable-intelasm, where WOLFSSL_X86_64_BUILD is false. sha256.c does NOT have this defect: its SHA256_UPDATE_REV_BYTES switch is correctly nested inside the x86/AVX #if, so the asymmetry between the two files is itself the tell.
The rework adopts the "sha512->buffer always holds the raw big-endian stream" convention by adding && !defined(WC_C_DYNAMIC_FALLBACK) to four ByteReverseWords64() guards (sha512.c:2013 partial-block completion, :2248 Final extra padding block, :2304 Final pre-length-store, :2610 wc_Sha512Transform). The just-in-time replacement Transform_Sha512_C_from_raw() is defined only at sha512.c:1191-1229, inside #if (WOLFSSL_X86_64_BUILD && USE_INTEL_SPEEDUP && (AVX1||AVX2)) || WOLFSSL_ARMASM. But WC_C_DYNAMIC_FALLBACK is a global setting whose only prerequisite is the new WC_HAVE_VECTOR_SPEEDUPS (settings.h:5941-5951), satisfied by USE_INTEL_SPEEDUP, USE_INTEL_SPEEDUP_FOR_AES, WOLFSSL_AESNI, WOLFSSL_ARMASM or WOLFSSL_SP_ASM. When WC_C_DYNAMIC_FALLBACK is set but that dispatcher is absent, Transform_Sha512 degenerates to _Transform_Sha512 (which reads host-endian word64s) while the reversal has been deleted — wrong digests, silently. The inconsistency is visible within a single build: the bulk-block loop's #else arm (sha512.c:2120-2135) still reverses unconditionally, so only the final/partial block is corrupted. Concrete reachable path: configure.ac:1206-1211 defines WOLFSSL_X86_64_BUILD only when (host_cpu = x86_64|amd64) && ENABLED_32BIT != yes, while configure.ac:4724-4730 defines WC_C_DYNAMIC_FALLBACK for any ENABLED_AESNI|ENABLED_INTELASM + KERNEL_MODE_DEFAULTS — so --enable-kernel-settings --enable-intelasm --enable-32bit (or an i686 host) yields WC_C_DYNAMIC_FALLBACK + USE_INTEL_SPEEDUP with no WOLFSSL_X86_64_BUILD, and the new #undef at sha512.c:68-75 does not fire because it requires !defined(USE_INTEL_SPEEDUP). A user_settings.h pairing WC_C_DYNAMIC_FALLBACK with WOLFSSL_SP_ASM hits the same hole. Note sha256.c got this right: its equivalent switch (SHA256_UPDATE_REV_BYTES, sha256.c:242-260) is nested inside the x86-64/AVX gate so other backends fall through to the correct arm; sha512.c has no such scoping.
Commit-message cross-check. 58815c9 identifies exactly this hazard and carves out one case: "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." But settings.h:5941 sets WC_HAVE_VECTOR_SPEEDUPS from four macros -- USE_INTEL_SPEEDUP, USE_INTEL_SPEEDUP_FOR_AES, WOLFSSL_AESNI, WOLFSSL_ARMASM (plus WOLFSSL_SP_ASM) -- and the sha256.c/sha512.c carve-out names only WOLFSSL_AESNI. A WOLFSSL_SP_ASM-only or USE_INTEL_SPEEDUP_FOR_AES-only build passes the new #error WC_C_DYNAMIC_FALLBACK requires WC_HAVE_VECTOR_SPEEDUPS check, keeps WC_C_DYNAMIC_FALLBACK, suppresses the byte-reversal, and has no from_raw adapter. The reasoning is right; the carve-out is one macro wide.
Suggestion: Introduce a single backend-scoped macro, mirroring sha256.c's SHA256_UPDATE_REV_BYTES, and gate on it instead of on WC_C_DYNAMIC_FALLBACK directly:
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) &&
(defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) &&
defined(WC_C_DYNAMIC_FALLBACK)
#define SHA512_RAW_BUFFER_CONVENTION
#endif
/* then use !defined(SHA512_RAW_BUFFER_CONVENTION) at the four sites */
Recommendation: Scope the four !defined(WC_C_DYNAMIC_FALLBACK) conditions to the same #if that compiles Transform_Sha512_C_from_raw(), exactly as sha256.c does. Add a KAT run under WC_C_DYNAMIC_FALLBACK without USE_INTEL_SPEEDUP — no current CI job covers that combination.
[wolfcrypt/src/sha512.c:2013-2027] Gate the raw-buffer convention on the backend that implements it. Define one local switch next to the Intel dispatcher — #if defined(WC_C_DYNAMIC_FALLBACK) && defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) -> #define SHA512_RAW_BUFFER_CONVENTION — and use !defined(SHA512_RAW_BUFFER_CONVENTION) at lines 2013, 2248, 2304 and 2610. That also makes the sha512.c:68-75 #undef unnecessary.
…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.
…FIPS_DEV_NO_POST stubs.
…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.
…GcmEncrypt() remapping if needed.
…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().
…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.
…FIPS || FIPS >= v7.
…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.
…() with xorshift64 (Marsaglia 2003).
…REGISTER_ACCESS configurations.
…a_param_*_vfy_test(), test_mldsa_decode_level(), and mldsa_test().
.github/workflows/fips-dev-no-post.yml: add reporting of fuzzing seed. wolfcrypt/src/aes.c, tests/api/test_aes.c, .wolfssl_known_macro_extras: * change FIPS AES-GCM nonce size restrictions from from opt-out (WC_FIPS_AESGCM_ALLOW_SHORT_NONCES) to opt-in (WC_FIPS_AESGCM_NO_SHORT_NONCES). * apply restrictions only on encryption operations, never on decryption. configure.ac: fix HAVE_FIPS_VERSION of fips-ready; fix enable_dh setup in KERNEL_MODE_DEFAULTS setup; fix help message for --enable-dh. linuxkm/x86_vector_register_glue.c: add dump_stack() on each BUG/WARNING message that didn't already have it. src/tls.c: fix a couple leaks in TLSX_KeyShare_GenDhKey(). tests/swdev/swdev.c: gate src->sha_method access in swdev_sha256_copy_state() and swdev_sha512_copy_state() appropriately. tests/unit.c: conditionally include dh.h, to assure wc_dh_enable() is available. wolfcrypt/src/dh.c: * in wc_InitDhKey_ex(), zero the key at entry unless null, remove duplicate key->trustedGroup = 0, and call wc_FreeDhKey() on error at end. * add missing wc_dh_enabled checks in wc_DhGeneratePublic() and wc_DhGenerateParams(). wolfcrypt/src/error.c: fix missing space in FIPS_UNAPPROVED_E string. b/wolfssl/wolfcrypt/settings.h: sense __SIZEOF_INT128__ and if defined, but HAVE___INT128_T and/or HAVE___UINT128_T are undefined, define them. wolfcrypt/src/falcon.c: tweak the gate on __uint128_t availability to lean solely on HAVE___UINT128_T. wolfcrypt/src/random.c: fix a couple missed WC_NO_ERR_TRACE() wrappers. wolfcrypt/src/rng_bank.c: properly tolerate WC_ACCEL_INHIBIT_E as a retval from bank->affinity_lock_cb(). wolfcrypt/src/sha256.c, wolfcrypt/src/sha512.c: move #undef WC_C_DYNAMIC_FALLBACK for WOLFSSL_AESNI without USE_INTEL_SPEEDUP to follow all includes, assuring no struct layout conflict. wolfcrypt/src/sha512.c: fix wrong call in intelasm Transform_Sha512() !WC_C_DYNAMIC_FALLBACK SHA512_C path. wolfcrypt/test/test.c: fix double-WC_TEST_RET_ENC_EC() in mldsa_param_*_vfy_test().
e42afa6 to
5fec377
Compare
tested with