Repository navigation
Guard cpuid dispatch reads against the 0xFFFFFFFF sentinel - #12039
Conversation
The file-local cpuid_flags statics in sha3.c, wc_frodokem_mat.c, wc_mlkem_poly.c and wc_mldsa.c start out as WC_CPUID_INITIALIZER, which is all ones. Any dispatch read before cpuid_get_flags_ex() therefore reports every feature present and sends a CPU without the extension into the asm path, where it dies with SIGILL. The dispatchers assume a prior key init set the flags, but the unit tests and white-box harnesses call them directly, without wc_MlDsaKey_Init() (and friends). On a CPU without AVX-512 this crashed the ML-DSA white-box harness in wc_mldsa_make_hint_88_avx512. aes.c already carries this pattern: a lazy init check before the dispatch. Add the same guard here - every dispatch now reads the flags through a per-file helper that resolves the sentinel on first use, so a read before any init reports no features and takes the C fallback instead of trapping. Verification: configure --enable-intelasm, full testwolfcrypt KAT suite passes (ML-DSA, ML-KEM, FrodoKEM, SHA-3), unit test groups mldsa/mlkem/frodokem/sha3 all pass; the ML-DSA AVX2 white-box harness that SIGILL'd before now runs to completion.
|
There was a problem hiding this comment.
🟡 Changes recommended
Three critical AArch64 configurations can emit unused static ARM helper functions, causing builds with -Werror=unused-function to fail unless their definitions are guarded consistently with their call sites.
3 open issues
What changed in this PR
This pull request makes SHA-3, ML-KEM, ML-DSA, and FrodoKEM CPU-feature dispatch safe when file-local CPUID flags remain at the all-ones sentinel, preventing unsupported assembly paths and potential SIGILL failures during direct or white-box calls.
Changes:
- Added per-file lazy CPUID resolution helpers.
- Routed optimized Intel and AArch64 dispatch decisions through the resolved flags.
- Preserved explicit initialization paths while enabling safe C fallbacks before initialization.
| File | Summary | Review findings |
|---|---|---|
wolfcrypt/src/wc_mlkem_poly.c |
Adds lazy CPUID resolution for ML-KEM SIMD and AArch64 dispatches. | Critical (1 vote): The helper may be emitted without any compiled call sites under default AArch64 configurations, causing -Werror=unused-function build failures. |
wolfcrypt/src/wc_mldsa.c |
Adds lazy CPUID resolution across ML-DSA hashing, vector, arithmetic, and hint dispatches. | Critical (1 vote): The helper may be emitted without any compiled call sites under default AArch64 configurations, causing -Werror=unused-function build failures. |
wolfcrypt/src/wc_frodokem_mat.c |
Guards FrodoKEM SIMD, SHA-3, AES, SVE, and SME dispatches against the sentinel. | No review findings. |
wolfcrypt/src/sha3.c |
Adds guarded CPUID resolution for SHA-3 implementation selection. | Critical (1 vote): The helper may be emitted without any compiled call sites on AArch64 configurations lacking the SHA-3 crypto extension, causing -Werror=unused-function build failures. |
Review effort: Lite
9a2a835 to
ecc0a4b
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #12039
Scan targets checked: wolfcrypt-src, wolfcrypt-bugs
Coverage: 4 of 4 in-scope changed file(s) opened by the reviewer
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
Review tier: Max

The file-local cpuid_flags statics in sha3.c, wc_frodokem_mat.c, wc_mlkem_poly.c and wc_mldsa.c start out as WC_CPUID_INITIALIZER, which is all ones. Any dispatch read before cpuid_get_flags_ex() therefore reports every feature present and sends a CPU without the extension into the asm path, where it dies with SIGILL.
The dispatchers assume a prior key init set the flags, but the unit tests and white-box harnesses call them directly, without wc_MlDsaKey_Init() (and friends). On a CPU without AVX-512 this crashed the ML-DSA white-box harness in wc_mldsa_make_hint_88_avx512.
aes.c already carries this pattern: a lazy init check before the dispatch. Add the same guard here - every dispatch now reads the flags through a per-file helper that resolves the sentinel on first use, so a read before any init reports no features and takes the C fallback instead of trapping.
Verification: configure --enable-intelasm, full testwolfcrypt KAT suite passes (ML-DSA, ML-KEM, FrodoKEM, SHA-3), unit test groups mldsa/mlkem/frodokem/sha3 all pass; the ML-DSA AVX2 white-box harness that SIGILL'd before now runs to completion.