diff --git a/configure.ac b/configure.ac index 3aaeee994d5..b4d7e41388c 100644 --- a/configure.ac +++ b/configure.ac @@ -1760,8 +1760,14 @@ then if test "$ENABLED_FIPS" = "no" || test "$HAVE_FIPS_VERSION" -ge 7 then test "$enable_eccencrypt" = "" && test "$enable_ecc" != "no" && enable_eccencrypt=yes - test "$enable_cshake" = "" && enable_cshake=yes - test "$enable_kmac" = "" && enable_kmac=yes + # KMAC and cSHAKE (SP 800-185) are outside the FIPS v7 module boundary, + # so only non-FIPS and the dev/ready prep builds turn them on here. + if test "$ENABLED_FIPS" = "no" || test "$ENABLED_FIPS_DEV" = "yes" \ + || test "$ENABLED_FIPS_READY" = "yes" + then + test "$enable_cshake" = "" && enable_cshake=yes + test "$enable_kmac" = "" && enable_kmac=yes + fi fi AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_DECRYPT -DHAVE_AES_ECB -DWOLFSSL_ALT_NAMES" @@ -8486,6 +8492,19 @@ else AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_SHAKE256" fi +# An explicit --enable-kmac/--enable-cshake against a validated module version +# fails here, with the clear configure error this file's convention calls for, +# rather than building a module that silently excludes them (SP 800-185). +if test "$ENABLED_FIPS" != "no" && test -n "$HAVE_FIPS_VERSION" \ + && test "$HAVE_FIPS_VERSION" -ge 7 && test "$ENABLED_FIPS_DEV" != "yes" \ + && test "$ENABLED_FIPS_READY" != "yes" +then + if test "$ENABLED_CSHAKE" != "no" || test "$ENABLED_KMAC" != "no" + then + AC_MSG_ERROR([cshake and kmac are not part of the FIPS module boundary for this version]) + fi +fi + # Set cSHAKE / KMAC flags. Both are built on SHAKE, so re-check here (after any # later logic - e.g. FIPS < 6 - may have force-disabled SHAKE) and fail with a # clear configure error rather than a confusing compile-time #error. KMAC diff --git a/src/include.am b/src/include.am index 9b0e56fce32..c962d19e44b 100644 --- a/src/include.am +++ b/src/include.am @@ -1028,6 +1028,37 @@ endif endif endif +# The FIPS v5 and v6 blocks and the non-FIPS block all list these; v7 did not, +# so aes.c called AES_*_RISCV64, ppc64_AES_* and ppc32_AES_* with nothing to +# link against, and --enable-fips=v7 with --enable-riscv-asm, --enable-ppc64-asm +# or --enable-ppc32-asm failed with undefined references to the AES asm entry +# points. Placement follows the v5/v6 FIPS blocks, which +# also sit outside BUILD_AES. +if BUILD_PPC64_ASM +if BUILD_PPC64_ASM_INLINE +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/ppc64/ppc64-aes-asm_c.c +else +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/ppc64/ppc64-aes-asm.S +endif !BUILD_PPC64_ASM_INLINE +endif BUILD_PPC64_ASM + +if BUILD_PPC32_ASM +if BUILD_PPC32_ASM_INLINE +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/ppc32/ppc32-aes-asm_c.c +else +if BUILD_PPC32_ASM_INLINE_REG +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/ppc32/ppc32-aes-asm_cr.c +else +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/ppc32/ppc32-aes-asm.S +endif !BUILD_PPC32_ASM_INLINE_REG +endif !BUILD_PPC32_ASM_INLINE +endif BUILD_PPC32_ASM + +if BUILD_RISCV_ASM +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/riscv64/riscv-64-aes-asm.S +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/riscv64/riscv-64-aes-asm_c.c +endif BUILD_RISCV_ASM + if BUILD_SHA src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/sha.c endif diff --git a/tests/unit-mcdc/test_sha3_whitebox.c b/tests/unit-mcdc/test_sha3_whitebox.c index 5c895d95f95..fb5d1ba6890 100644 --- a/tests/unit-mcdc/test_sha3_whitebox.c +++ b/tests/unit-mcdc/test_sha3_whitebox.c @@ -33,8 +33,11 @@ * Sha3Update multi-block fast path (line ~874): * (sha3_block_n != NULL) && (blocks > 0) * - * On a capable host cpuid reports AVX2, so the runtime always takes the AVX2 - * branch: the "cached", BMI, and non-fast-path conditions are unreachable from + * On a capable host the runtime now takes the BMI2 branch, because sha3.c + * prefers the BMI2 block (it needs no vector-register claim) and only puts + * AVX2 first when WOLFSSL_SHA3_AVX2 is defined, which no configure- or + * CMake-reachable build defines. So the AVX2 selection, the "cached" + * condition and the non-fast-path condition are the ones unreachable from * tests/api. This TU #includes sha3.c so those static items are in scope and drives * InitSha3 / Update with cpuid_flags and the block pointers forced. * diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index e7db61ad48c..96247ce0acb 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -53,6 +53,9 @@ #undef USE_INTEL_SPEEDUP #undef WOLFSSL_ARMASM #undef WOLFSSL_RISCV_ASM + #undef WOLFSSL_PPC64_ASM + #undef WOLFSSL_PPC64_ASM_POWER8 + #undef WOLFSSL_PPC32_ASM #endif #ifdef WOLFSSL_X86_BUILD #undef USE_INTEL_SPEEDUP @@ -131,21 +134,21 @@ #endif #ifdef USE_INTEL_SPEEDUP - /* Block-function selection when USE_INTEL_SPEEDUP: AVX2 on Intel, else - * BMI2, else the C block. Measured single-instance Keccak-f[1600] - * (Ethereum "Optimizing Keccak"; OpenSSL keccak1600-x86_64.pl): AVX2 is - * ~13-17% faster than BMI2 on Intel Haswell..Skylake, tied on Ice Lake, - * but ~2x SLOWER on AMD Zen, so AVX2 is Intel-only. (Single-stream + /* Block-function selection when USE_INTEL_SPEEDUP: BMI2, then AVX2, then + * the C block. BMI2 is preferred because its block uses general + * registers only and so needs no vector-register save; AVX2 goes first + * only when WOLFSSL_SHA3_AVX2 explicitly asks for it. (Single-stream * AVX-512 is vpermt2q-bound and slower than BMI2 everywhere measured, so * it is not built - see scripts sha3_avx512.rb.) - * Overrides: WOLFSSL_SHA3_AVX2 forces AVX2 on any vendor with it; + * Overrides: WOLFSSL_SHA3_AVX2 puts AVX2 ahead of BMI2; * WOLFSSL_SHA3_NO_AVX2 never uses AVX2. */ - /* SHA3_USE_AVX2() is defined in sha3.h - shared with ML-DSA. */ + /* SHA3_USE_AVX2() is defined in sha3.h - shared with ML-DSA, which still + * selects AVX2 first; only SHA-3's own order changed here. */ /* True when the selected block function uses vector registers and so * needs the caller to save/restore them. BMI2 and the C block use only * general registers. */ -#ifdef WOLFSSL_SHA3_NO_AVX2 +#if defined(WOLFSSL_SHA3_NO_AVX2) #define SHA3_BLOCK_VREGS(f) 0 #else #define SHA3_BLOCK_VREGS(f) ((f) == sha3_block_avx2) @@ -160,6 +163,23 @@ #define SHA3_NEEDS_VREG_CLAIM #endif +/* Whether a refused SAVE_VECTOR_REGISTERS2() may switch this call to the C + * block. A certifiable build carries one Keccak permutation, so there it is an + * error instead; dev and dev-no-post keep the switch (WOLFSSL_FIPS_DEV covers + * both). */ +#if defined(USE_INTEL_SPEEDUP) && defined(WC_C_DYNAMIC_FALLBACK) && \ + !(FIPS_VERSION3_GE(7,0,0) && !defined(WOLFSSL_FIPS_DEV)) + #define SHA3_MAY_SWITCH_TO_C +#endif + +#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \ + !defined(WOLFSSL_ARMASM_THUMB2) && !defined(WOLFSSL_ARMASM_NO_NEON) + /* armv8-32-sha3-asm.S has a NEON block (vpush d8-d15) and an integer-only + * one under WOLFSSL_ARMASM_NO_NEON; only the NEON block needs the save. */ + #define SHA3_BLOCK_VREGS(f) 1 + #define SHA3_NEEDS_VREG_CLAIM +#endif + #if !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_RISCV_ASM) && \ !defined(WOLFSSL_PPC64_ASM) && !defined(WOLFSSL_PPC32_ASM) @@ -910,30 +930,47 @@ static int InitSha3(wc_Sha3* sha3) sha3->hashType = WC_HASH_TYPE_NONE; #endif -#ifdef USE_INTEL_SPEEDUP +#if defined(USE_INTEL_SPEEDUP) { int cpuid_flags_were_updated = cpuid_get_flags_ex(&cpuid_flags); #ifdef WC_C_DYNAMIC_FALLBACK (void)cpuid_flags_were_updated; +#ifdef SHA3_MAY_SWITCH_TO_C + /* Same gate as the places that handle a refused save: a certifiable + * build must not pick a second permutation, so cpuid alone decides. */ if (! CAN_SAVE_VECTOR_REGISTERS()) { SHA3_BLOCK = BlockSha3; SHA3_BLOCK_N = NULL; } else +#endif #else if ((! cpuid_flags_were_updated) && (SHA3_BLOCK != NULL)) { } else #endif - /* See the selection comment above: AVX2 on Intel, otherwise BMI2. */ +#if defined(WOLFSSL_SHA3_AVX2) && !defined(WOLFSSL_SHA3_NO_AVX2) + /* WOLFSSL_SHA3_AVX2 asks for AVX2 ahead of BMI2. */ if (SHA3_USE_AVX2(cpuid_flags)) { SHA3_BLOCK = sha3_block_avx2; SHA3_BLOCK_N = sha3_block_n_avx2; } - else if (IS_INTEL_BMI1(cpuid_flags) && IS_INTEL_BMI2(cpuid_flags)) { + else +#endif + /* BMI2 before AVX2: sha3_block_bmi2 uses general registers only, so + * it needs no vector-register save. */ + if (IS_INTEL_BMI1(cpuid_flags) && IS_INTEL_BMI2(cpuid_flags)) { SHA3_BLOCK = sha3_block_bmi2; SHA3_BLOCK_N = sha3_block_n_bmi2; } +#if !defined(WOLFSSL_SHA3_AVX2) && !defined(WOLFSSL_SHA3_NO_AVX2) + /* AVX2 without BMI2. Only live in the plain build: the overrides + * either select AVX2 above or disable it outright. */ + else if (SHA3_USE_AVX2(cpuid_flags)) { + SHA3_BLOCK = sha3_block_avx2; + SHA3_BLOCK_N = sha3_block_n_avx2; + } +#endif else { SHA3_BLOCK = BlockSha3; SHA3_BLOCK_N = NULL; @@ -1004,7 +1041,7 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, word32 p) if (SHA3_BLOCK_VREGS(sha3_block)) { ret = SAVE_VECTOR_REGISTERS2(); if (ret != 0) { -#ifdef WC_C_DYNAMIC_FALLBACK +#ifdef SHA3_MAY_SWITCH_TO_C sha3_block = BlockSha3; sha3_block_n = NULL; ret = 0; @@ -1177,10 +1214,25 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, word32 p, word32 l if (sha3->i >= rate) return BAD_STATE_E; +#if defined(USE_INTEL_SPEEDUP) || defined(SHA3_NEEDS_VREG_CLAIM) + if (SHA3_BLOCK_VREGS(sha3_block)) { + int ret = SAVE_VECTOR_REGISTERS2(); + if (ret != 0) { +#ifdef SHA3_MAY_SWITCH_TO_C + sha3_block = BlockSha3; +#else + return ret; +#endif + } + } +#endif + #if !defined(BIG_ENDIAN_ORDER) && !defined(WC_SHA3_FAULT_HARDEN) && \ !defined(WOLFSSL_WIDE_BYTE) xorbuf(sha3->s, sha3->t, sha3->i); -#ifdef WOLFSSL_HASH_FLAGS + /* SHA3-256 emits the FIPS 202 0x06 pad; the non-approved legacy + * Keccak-256 0x01 pad is excluded from a certifiable build (FIPS 202 6.1). */ +#if defined(WOLFSSL_HASH_FLAGS) && !defined(WOLFSSL_NO_KECCAK256) if ((p == WC_SHA3_256_COUNT) && (sha3->flags & WC_HASH_SHA3_KECCAK256)) { padChar = 0x01; } @@ -1189,7 +1241,9 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, word32 p, word32 l ((byte*)sha3->s)[rate - 1] ^= 0x80; #else sha3->t[rate - 1] = 0x00; -#ifdef WOLFSSL_HASH_FLAGS + /* SHA3-256 emits the FIPS 202 0x06 pad; the non-approved legacy + * Keccak-256 0x01 pad is excluded from a certifiable build (FIPS 202 6.1). */ +#if defined(WOLFSSL_HASH_FLAGS) && !defined(WOLFSSL_NO_KECCAK256) if ((p == WC_SHA3_256_COUNT) && (sha3->flags & WC_HASH_SHA3_KECCAK256)) { padChar = 0x01; } @@ -1207,22 +1261,14 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, word32 p, word32 l } #ifdef WC_SHA3_FAULT_HARDEN if (check != p) { - return BAD_COND_E; - } -#endif -#endif - #if defined(USE_INTEL_SPEEDUP) || defined(SHA3_NEEDS_VREG_CLAIM) - if (SHA3_BLOCK_VREGS(sha3_block)) { - int ret = SAVE_VECTOR_REGISTERS2(); - if (ret != 0) { -#ifdef WC_C_DYNAMIC_FALLBACK - sha3_block = BlockSha3; -#else - return ret; -#endif + if (SHA3_BLOCK_VREGS(sha3_block)) { + RESTORE_VECTOR_REGISTERS(); } +#endif + return BAD_COND_E; } +#endif #endif for (j = 0; l - j >= rate; j += rate) { @@ -2077,6 +2123,14 @@ int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst) #ifdef WOLFSSL_HASH_FLAGS int wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags) { +#ifdef WOLFSSL_NO_KECCAK256 + /* Keccak-256 is a different hash from SHA3-256, so refuse the request + * instead of accepting it and hashing with the other one (FIPS 202 6.1). + * Checked first, so the answer does not depend on having a context. */ + if ((flags & WC_HASH_SHA3_KECCAK256) != 0) { + return FIPS_NOT_ALLOWED_E; + } +#endif if (sha3) { sha3->flags = flags; } @@ -2339,14 +2393,14 @@ int wc_Shake128_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) } #if defined(USE_INTEL_SPEEDUP) || defined(SHA3_NEEDS_VREG_CLAIM) -#ifdef WC_C_DYNAMIC_FALLBACK +#if defined(USE_INTEL_SPEEDUP) && defined(WC_C_DYNAMIC_FALLBACK) sha3_block = SHA3_BLOCK; #endif if (SHA3_BLOCK_VREGS(sha3_block)) { int ret = SAVE_VECTOR_REGISTERS2(); if (ret != 0) { -#ifdef WC_C_DYNAMIC_FALLBACK +#ifdef SHA3_MAY_SWITCH_TO_C sha3_block = BlockSha3; #else return ret; @@ -2656,14 +2710,14 @@ int wc_Shake256_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) } #if defined(USE_INTEL_SPEEDUP) || defined(SHA3_NEEDS_VREG_CLAIM) -#ifdef WC_C_DYNAMIC_FALLBACK +#if defined(USE_INTEL_SPEEDUP) && defined(WC_C_DYNAMIC_FALLBACK) sha3_block = SHA3_BLOCK; #endif if (SHA3_BLOCK_VREGS(sha3_block)) { int ret = SAVE_VECTOR_REGISTERS2(); if (ret != 0) { -#ifdef WC_C_DYNAMIC_FALLBACK +#ifdef SHA3_MAY_SWITCH_TO_C sha3_block = BlockSha3; #else return ret; @@ -2733,6 +2787,15 @@ int wc_Shake256_Copy(wc_Shake* src, wc_Shake* dst) #if (defined(WOLFSSL_KMAC) || defined(WOLFSSL_CSHAKE)) && \ defined(WC_SHA3_SW_KECCAK) + +#if FIPS_VERSION3_GE(7,0,0) && \ + !defined(WOLFSSL_FIPS_DEV) && !defined(WOLFSSL_FIPS_READY) + /* KMAC and cSHAKE (SP 800-185) have no CAST and no service-layer gate, so + * they are not approved services and stay out of the validated module. + * The dev and ready prep builds still exercise them. */ + #error "KMAC/cSHAKE (SP 800-185) are not part of the FIPS module boundary" +#endif + /* cSHAKE and KMAC - NIST SP 800-185. * * cSHAKE is a customizable SHAKE; KMAC is cSHAKE keyed with the function name diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c248b5cbf18..fc9842bb186 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8010,6 +8010,27 @@ static wc_test_ret_t sha3_256_kat_test(wc_Sha3* sha, wc_Sha3* shaCopy) /* this is a software only variant of SHA3 not supported by external * hardware devices */ #if defined(WOLFSSL_HASH_FLAGS) && !defined(WOLFSSL_ASYNC_CRYPT) +#ifdef WOLFSSL_NO_KECCAK256 + { + /* Keccak-256 is a different hash from SHA3-256, so the module refuses + * the flag rather than accepting it and hashing with the other one + * (FIPS 202 6.1). */ + wc_Sha3 ksha; + + ret = wc_InitSha3_256(&ksha, HEAP_HINT, devId); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + ret = wc_Sha3_SetFlags(&ksha, WC_HASH_SHA3_KECCAK256); + wc_Sha3_256_Free(&ksha); + if (ret != WC_NO_ERR_TRACE(FIPS_NOT_ALLOWED_E)) + return WC_TEST_RET_ENC_EC(ret); + /* The refusal must not depend on the caller having a context. */ + ret = wc_Sha3_SetFlags(NULL, WC_HASH_SHA3_KECCAK256); + if (ret != WC_NO_ERR_TRACE(FIPS_NOT_ALLOWED_E)) + return WC_TEST_RET_ENC_EC(ret); + ret = 0; + } +#else { /* test vector with hash of empty string */ static const char* Keccak256EmptyOut = @@ -8040,6 +8061,7 @@ static wc_test_ret_t sha3_256_kat_test(wc_Sha3* sha, wc_Sha3* shaCopy) keccak_exit: wc_Sha3_256_Free(&ksha); } +#endif /* !FIPS_VERSION3_GE(7,0,0) */ #endif /* WOLFSSL_HASH_FLAGS && !WOLFSSL_ASYNC_CRYPT */ return ret; @@ -8188,6 +8210,76 @@ static wc_test_ret_t sha3_256_reset_test(wc_Sha3* sha) } #endif +/* Only where a refusal is certain to be seen: the AVX2 lane pinned, no switch + * to the C block, and no fuzzer refusing saves at random. */ +#if defined(DEBUG_VECTOR_REGISTER_ACCESS) && \ + !defined(DEBUG_VECTOR_REGISTER_ACCESS_FUZZING) && \ + !defined(WC_C_DYNAMIC_FALLBACK) && defined(USE_INTEL_SPEEDUP) && \ + !defined(WOLFSSL_X86_BUILD) && !defined(WC_SHA3_NO_ASM) && \ + defined(WOLFSSL_SHA3_AVX2) && !defined(WOLFSSL_SHA3_NO_AVX2) && \ + defined(__GNUC__) + #define SHA3_256_NO_SWITCH_TO_C +#endif + +#ifdef SHA3_256_NO_SWITCH_TO_C +/* A refused vector-register save must leave the context usable: the retry has + * to return the same digest, not one built from a half-absorbed state. */ +static wc_test_ret_t sha3_256_no_switch_to_c_test(void) +{ + wc_Sha3 sha; + byte ref[WC_SHA3_256_DIGEST_SIZE]; + byte got[WC_SHA3_256_DIGEST_SIZE]; + wc_test_ret_t ret; + int inited = 0; + + /* Without AVX2 the pinned lane never runs, so there is no save to refuse. */ + if (!__builtin_cpu_supports("avx2")) + return 0; + + ret = wc_InitSha3_256(&sha, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + inited = 1; + ret = wc_Sha3_256_Update(&sha, (const byte*)"abc", 3); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_Sha3_256_Final(&sha, ref); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + wc_Sha3_256_Free(&sha); + inited = 0; + + ret = wc_InitSha3_256(&sha, HEAP_HINT, INVALID_DEVID); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + inited = 1; + ret = wc_Sha3_256_Update(&sha, (const byte*)"abc", 3); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(WC_NO_ERR_TRACE(WC_ACCEL_INHIBIT_E)); + ret = wc_Sha3_256_Final(&sha, got); + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (ret == 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + if (ret != WC_NO_ERR_TRACE(WC_ACCEL_INHIBIT_E)) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + ret = wc_Sha3_256_Final(&sha, got); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(got, ref, WC_SHA3_256_DIGEST_SIZE) != 0) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ret = 0; + +out: + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (inited) + wc_Sha3_256_Free(&sha); + return ret; +} +#endif /* SHA3_256_NO_SWITCH_TO_C */ + static wc_test_ret_t sha3_256_test(void) { wc_Sha3 sha; @@ -8214,6 +8306,10 @@ static wc_test_ret_t sha3_256_test(void) !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_SHA3) if ((ret = sha3_256_reset_test(&sha)) != 0) goto out; +#endif +#ifdef SHA3_256_NO_SWITCH_TO_C + if ((ret = sha3_256_no_switch_to_c_test()) != 0) + goto out; #endif ret = 0; out: diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 49617909723..1f9c078a083 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -6098,6 +6098,22 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS." #error WC_C_DYNAMIC_FALLBACK requires WC_HAVE_VECTOR_SPEEDUPS #endif +/* Keccak-256 uses the legacy 0x01 pad and is not one of the functions FIPS 202 + * specifies, so a certifiable build refuses it. dev and dev-no-post are not + * certifiable and keep it, as they keep the run-time C block switch. */ +#if FIPS_VERSION3_GE(7,0,0) && !defined(WOLFSSL_FIPS_DEV) + #define WOLFSSL_NO_KECCAK256 +#endif + +/* KMAC and cSHAKE (SP 800-185) are outside the FIPS v7 module boundary, so a + * validated build drops them however they were requested; the dev and ready + * prep builds keep them. */ +#if FIPS_VERSION3_GE(7,0,0) && !defined(WOLFSSL_FIPS_DEV) && \ + !defined(WOLFSSL_FIPS_READY) + #undef WOLFSSL_KMAC + #undef WOLFSSL_CSHAKE +#endif + /* setup for opt-in DH in FIPS v7+ */ #if FIPS_VERSION3_GE(7,0,0) && !defined(HAVE_DH) && !defined(NO_DH) #define NO_DH diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index 1c59e274990..6e5e2a912bb 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -412,6 +412,8 @@ WOLFSSL_LOCAL void BlockSha3(word64 *s); * than BMI2 everywhere measured, so it is not built.) * Every caller of sha3_block_avx2()/sha3_block_n_avx2() must select with * this and not with IS_INTEL_AVX2() alone. + * sha3.c puts BMI2 ahead of AVX2 because the BMI2 block needs no + * vector-register save; ML-DSA still selects AVX2 first. * Overrides: WOLFSSL_SHA3_AVX2 forces AVX2 on any vendor with it; * WOLFSSL_SHA3_NO_AVX2 never uses AVX2. */ #if defined(WOLFSSL_SHA3_NO_AVX2)