From 1524ad86c80fc528e3aab96f59806f5f08a87d3c Mon Sep 17 00:00:00 2001 From: jackctj117 Date: Wed, 28 Oct 2026 10:35:05 -0400 Subject: [PATCH 1/2] zephyr: build the FIPS v5 boundary Define BUILDING_WOLFSSL for the library sources so the v5 kdf.c, which predates libwolfssl_sources.h, no longer defines its wc_*_fips wrappers twice. Map the v5 random.c's and onto the current headers; the module needs Zephyr 3.7 or later anyway, as CONFIG_WOLFCRYPT_FIPS selects STATIC_INIT_GNU. Define NO_THREAD_LS, since THREAD_LS_T is empty on Zephyr, and WOLFSSL_ECDSA_SET_K for the ECDSA CAST. The v5 wc_GenerateSeed() is a bare sys_rand_get(), so seed the DRBG from the zephyr,entropy device or the Zephyr CSPRNG instead, through wolfSSL_Init() and, for wolfCrypt-only builds, from an APPLICATION-level hook after the power-on self test. Apply the integrity-layout guards to every FIPS boundary instead of only the one with assembly, and keep the symmetric assembly off under FIPS v2, v5 and v6, whose in-boundary assembly this module does not build. Keep the PQC options off under v2 and v5, whose boundaries have no SHAKE. --- zephyr/CMakeLists.txt | 19 ++++- zephyr/Kconfig | 45 +++++++++-- zephyr/fips-v5-compat/posix/time.h | 36 +++++++++ zephyr/fips-v5-compat/random/rand32.h | 30 ++++++++ zephyr/include.am | 3 + zephyr/user_settings.h | 29 ++++++- zephyr/zephyr_fips_seed.c | 107 ++++++++++++++++++++++++++ zephyr/zephyr_init.c | 16 +++- 8 files changed, 270 insertions(+), 15 deletions(-) create mode 100644 zephyr/fips-v5-compat/posix/time.h create mode 100644 zephyr/fips-v5-compat/random/rand32.h create mode 100644 zephyr/zephyr_fips_seed.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index ec2def9ac39..b7fb32b8486 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -19,7 +19,18 @@ if(CONFIG_WOLFSSL) ) zephyr_library() + # Library sources only, never the application, as the top-level CMake does. + # The v5 kdf.c predates libwolfssl_sources.h: without this, types.h pulls + # in wc_compat.h, which reaches fips.h before kdf.c sets FIPS_NO_WRAPPERS, + # and kdf.c then defines the wc_*_fips wrappers a second time. + zephyr_library_compile_definitions(BUILDING_WOLFSSL) + # The v5 random.c predates the zephyr/ include prefix; map its + # and onto the current headers. + if(CONFIG_WOLFCRYPT_FIPS_V5) + zephyr_library_include_directories(${ZEPHYR_CURRENT_MODULE_DIR}/zephyr/fips-v5-compat) + endif() zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/zephyr/zephyr_init.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/zephyr/zephyr_fips_seed.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/crl.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/dtls.c) @@ -90,7 +101,9 @@ if(CONFIG_WOLFSSL) # The integrity test hashes the boundary .text and .rodata as two ranges, so # keep each in one piece and in file order: no sorting, splitting or merging. - if(WOLF_BOUNDARY_ASM AND CONFIG_WOLFCRYPT_FIPS) + # v5 hashes the same wolfCrypt_FIPS_first..last and ro_start..ro_end pair as + # v7, so this holds for every boundary, not only the one with assembly. + if(CONFIG_WOLFCRYPT_FIPS) if(CONFIG_LINKER_SORT_BY_ALIGNMENT) message(FATAL_ERROR "wolfCrypt FIPS needs CONFIG_LINKER_SORT_BY_ALIGNMENT=n: " "sorting by alignment moves boundary code out of the hashed range") @@ -99,7 +112,7 @@ if(CONFIG_WOLFSSL) "-fno-function-sections;-fno-data-sections;-fno-merge-constants") endif() # native_sim links like a host program and keeps file order without this. - if(WOLF_BOUNDARY_ASM AND CONFIG_WOLFCRYPT_FIPS AND NOT CONFIG_ARCH_POSIX) + if(CONFIG_WOLFCRYPT_FIPS AND NOT CONFIG_ARCH_POSIX) set(WOLF_FIPS_LD ${CMAKE_CURRENT_BINARY_DIR}/wolfcrypt_fips_rodata.ld) file(WRITE ${WOLF_FIPS_LD} "SECTION_PROLOGUE(wolfcrypt_fips_rodata,,)\n{\n") foreach(s ${WOLF_FIPS_SRCS}) @@ -198,7 +211,7 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${WOLF_ARM_ASM_DIR}/${WOLF_ARM_ASM_PREFIX}-${f}.c) endif() endforeach() - elseif(CONFIG_X86_64) + elseif(CONFIG_X86_64 AND NOT CONFIG_WOLFCRYPT_FIPS_LEGACY_ASM) # fe_x25519_asm.S, wc_mlkem_asm.S and wc_mldsa_asm.S are here because # curve25519.c, wc_mlkem_poly.c and wc_mldsa.c all take the Intel path # whenever USE_INTEL_SPEEDUP is set, so leaving one out is a link error diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 18e24f6cd5c..359520b06d5 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -79,6 +79,12 @@ config WOLFCRYPT_FIPS dropped into wolfcrypt/src/ - the CMake FIPS-boundary block compiles them. Select the version that matches the bundle under "wolfCrypt FIPS version". + Set CONFIG_LINKER_SORT_BY_ALIGNMENT=n, which Zephyr defaults on. The + integrity check hashes the boundary as two ranges, so its sections + must stay in file order; the build stops while sorting is on. + + Needs Zephyr 3.7 or later, for STATIC_INIT_GNU. + choice prompt "wolfCrypt FIPS version" depends on WOLFCRYPT_FIPS @@ -99,6 +105,11 @@ config WOLFCRYPT_FIPS_V5 help wolfCrypt FIPS 140-3 validated module, Certificate #4718 (version 5.2.1). + The v5 random.c seeds from a bare sys_rand_get(), so the DRBG is + seeded through a callback instead (zephyr_fips_seed.c): from the + zephyr,entropy device, or else the Zephyr CSPRNG. A board with neither + fails the build unless CONFIG_TEST_RANDOM_GENERATOR is set. + config WOLFCRYPT_FIPS_V6 bool "FIPS 140-3 (SRTP-KDF full submission)" help @@ -225,14 +236,18 @@ config WOLFSSL_PSK config WOLFSSL_MLKEM bool "wolfSSL PQC ML-KEM support" depends on !WOLFSSL_HAS_SETTINGS_FILE + depends on !WOLFCRYPT_FIPS_V2 && !WOLFCRYPT_FIPS_V5 help - Enable PQC ML-KEM support for Key Exchange + Enable PQC ML-KEM support for Key Exchange. Needs SHAKE, which the + FIPS v2 and v5 boundaries do not build. config WOLFSSL_MLDSA bool "wolfSSL PQC ML-DSA support" depends on !WOLFSSL_HAS_SETTINGS_FILE + depends on !WOLFCRYPT_FIPS_V2 && !WOLFCRYPT_FIPS_V5 help - Enable PQC ML-DSA (Dilithium) signatures. + Enable PQC ML-DSA (Dilithium) signatures. Needs SHAKE, which the FIPS + v2 and v5 boundaries do not build. config WOLFSSL_LMS bool "wolfSSL LMS/HSS hash-based signatures" @@ -243,14 +258,19 @@ config WOLFSSL_LMS config WOLFSSL_XMSS bool "wolfSSL XMSS/XMSS^MT hash-based signatures" depends on !WOLFSSL_HAS_SETTINGS_FILE + depends on !WOLFCRYPT_FIPS_V2 && !WOLFCRYPT_FIPS_V5 help Enable XMSS/XMSS^MT stateful hash-based signature verification (verify-only). + Its SHAKE parameter sets need SHAKE, which the FIPS v2 and v5 boundaries + do not build. config WOLFSSL_FALCON bool "wolfSSL PQC Falcon signatures" depends on !WOLFSSL_HAS_SETTINGS_FILE + depends on !WOLFCRYPT_FIPS_V2 && !WOLFCRYPT_FIPS_V5 help - Enable PQC Falcon (FN-DSA) signatures. + Enable PQC Falcon (FN-DSA) signatures. Needs SHAKE, which the FIPS v2 + and v5 boundaries do not build. config WOLFSSL_RSA bool "wolfCrypt RSA support" @@ -327,12 +347,23 @@ endif # WOLFSSL_ECC config WOLFSSL_ECC_ALLOW_ZERO_HASH bool +# v2, v5 and v6 keep their symmetric assembly in the armv8-aes.c and +# armv8-sha256.c of their own boundary (src/include.am's LEGACY_ARMASM_*), +# which this module does not build: their aes.c and sha256.c compile the C +# code out under WOLFSSL_ARMASM, so the link fails, and on x86_64 their +# sha256.c would call the tree's sha256_asm.S from outside the boundary. v7 +# and FIPS Ready carry the asm_c form, which the CMake boundary block builds +# in place. +config WOLFCRYPT_FIPS_LEGACY_ASM + bool + default y if WOLFCRYPT_FIPS && !WOLFCRYPT_FIPS_V7 && !WOLFCRYPT_FIPS_READY + # Thumb2 needs UBFX and LDRD, so ARMv6-M and ARMv8-M baseline keep the C code # and take only the SP speedup. config WOLFCRYPT_ARM_SYMMETRIC_ASM bool - default y if WOLFCRYPT_ASM && (ARM64 || ARMV7_M_ARMV8_M_MAINLINE || \ - (ARM && !CPU_CORTEX_M)) + default y if WOLFCRYPT_ASM && !WOLFCRYPT_FIPS_LEGACY_ASM && \ + (ARM64 || ARMV7_M_ARMV8_M_MAINLINE || (ARM && !CPU_CORTEX_M)) # Not under FIPS v2 or v5, whose pinned aes.c has neither backend, nor with the # Arm assembly, which indexes its AES and GHASH tables with secret data. @@ -703,6 +734,10 @@ config WOLFCRYPT_ASM 32-bit x86 is not offered: only the AES sources have an implementation at that width, and the rest are guarded to x86_64. + Under FIPS v2, v5 and v6 only the single-precision math is + accelerated. Those modules carry their symmetric assembly inside the + boundary in a form this module does not build. + config WOLFCRYPT_SP_SMALL bool "Smaller single-precision math" depends on WOLFSSL_BUILTIN && !WOLFSSL_HAS_SETTINGS_FILE diff --git a/zephyr/fips-v5-compat/posix/time.h b/zephyr/fips-v5-compat/posix/time.h new file mode 100644 index 00000000000..4cb389e65b2 --- /dev/null +++ b/zephyr/fips-v5-compat/posix/time.h @@ -0,0 +1,36 @@ +/* time.h + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Shim for the FIPS v5 random.c, which includes from + * before Zephyr moved its headers under zephyr/. The module needs Zephyr 3.7 + * or later; 4.3 then dropped zephyr/posix/time.h for the libc header. */ +#ifndef WOLFSSL_ZEPHYR_COMPAT_POSIX_TIME_H +#define WOLFSSL_ZEPHYR_COMPAT_POSIX_TIME_H + +#include + +#if KERNEL_VERSION_NUMBER >= 0x40300 + #include +#else + #include +#endif + +#endif /* WOLFSSL_ZEPHYR_COMPAT_POSIX_TIME_H */ diff --git a/zephyr/fips-v5-compat/random/rand32.h b/zephyr/fips-v5-compat/random/rand32.h new file mode 100644 index 00000000000..af6a76661e0 --- /dev/null +++ b/zephyr/fips-v5-compat/random/rand32.h @@ -0,0 +1,30 @@ +/* rand32.h + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Shim for the FIPS v5 random.c, which includes from + * before Zephyr moved its headers under zephyr/ and renamed rand32.h. The + * module needs Zephyr 3.7 or later, which has only the new header. */ +#ifndef WOLFSSL_ZEPHYR_COMPAT_RAND32_H +#define WOLFSSL_ZEPHYR_COMPAT_RAND32_H + +#include + +#endif /* WOLFSSL_ZEPHYR_COMPAT_RAND32_H */ diff --git a/zephyr/include.am b/zephyr/include.am index 57fa67fd77c..83707bee472 100644 --- a/zephyr/include.am +++ b/zephyr/include.am @@ -5,10 +5,13 @@ EXTRA_DIST+= zephyr/CMakeLists.txt EXTRA_DIST+= zephyr/Kconfig EXTRA_DIST+= zephyr/zephyr_init.c +EXTRA_DIST+= zephyr/zephyr_fips_seed.c EXTRA_DIST+= zephyr/module.yml EXTRA_DIST+= zephyr/wolfssl/options.h EXTRA_DIST+= zephyr/user_settings.h EXTRA_DIST+= zephyr/user_settings-fips-v7.h +EXTRA_DIST+= zephyr/fips-v5-compat/posix/time.h +EXTRA_DIST+= zephyr/fips-v5-compat/random/rand32.h EXTRA_DIST+= zephyr/README.md EXTRA_DIST+= zephyr/samples/wolfssl_benchmark/ EXTRA_DIST+= zephyr/samples/wolfssl_benchmark/CMakeLists.txt diff --git a/zephyr/user_settings.h b/zephyr/user_settings.h index 3653eccd0b3..a7b05f42f89 100644 --- a/zephyr/user_settings.h +++ b/zephyr/user_settings.h @@ -147,6 +147,23 @@ extern "C" { #ifndef HAVE_FIPS_VERSION_PATCH #define HAVE_FIPS_VERSION_PATCH 1 #endif + /* fips.c needs a thread-local choice made. Not HAVE_THREAD_LS: + * THREAD_LS_T is empty on Zephyr, so it would only drop the ECC/SP + * cache locks and arm the shared wolfCrypt_Init() recursion guard. */ + #define NO_THREAD_LS + /* The ECDSA CAST in fips_test.c signs with wc_ecc_sign_set_k(). */ + #define WOLFSSL_ECDSA_SET_K + /* The v5 random.c seeds the DRBG from a bare sys_rand_get(), so seed + * through the callback in zephyr_fips_seed.c instead: wolfSSL_Init() + * registers WC_GENERATE_SEED_DEFAULT, and that file registers it for + * wolfCrypt-only builds. configure sets WC_RNG_SEED_CB for v5 too. */ + #define WC_RNG_SEED_CB + #define WC_GENERATE_SEED_DEFAULT wolfssl_zephyr_seed + #ifndef __ASSEMBLER__ + struct OS_Seed; + int wolfssl_zephyr_seed(struct OS_Seed* os, unsigned char* seed, + unsigned int sz); + #endif #elif defined(CONFIG_WOLFCRYPT_FIPS_V2) /* FIPS 140-2 Cert #3389. */ #ifndef HAVE_FIPS_VERSION @@ -306,9 +323,11 @@ extern "C" { /* wolfCrypt Hash-DRBG (SHA2-256). On Zephyr its seed comes from wc_GenerateSeed() * (wolfcrypt/src/random.c), which draws from the hardware entropy driver when one * is present and falls back to sys_rand_get() otherwise -- so no seed callback is - * registered. Guarded by WC_NO_HASHDRBG so a PSA-RNG build - * (CONFIG_MBEDTLS_PSA_CRYPTO_C above) can still disable the internal DRBG and - * route randomness through the PSA provider. */ + * registered. The v5 bundles' random.c has only the fallback, so the FIPS block + * above registers zephyr_fips_seed.c as the seed callback for them instead. + * Guarded by WC_NO_HASHDRBG so a PSA-RNG build (CONFIG_MBEDTLS_PSA_CRYPTO_C + * above) can still disable the internal DRBG and route randomness through the + * PSA provider. */ #ifndef WC_NO_HASHDRBG #define HAVE_HASHDRBG #endif @@ -771,7 +790,9 @@ extern "C" { #if defined(CONFIG_ARM64) && !defined(__ARM_FEATURE_QRDMX) #define WOLFSSL_AARCH64_NO_SQRDMLSH #endif -#elif defined(CONFIG_X86_64) +#elif defined(CONFIG_X86_64) && !defined(CONFIG_WOLFCRYPT_FIPS_LEGACY_ASM) + /* Not under FIPS v2, v5 or v6: their sha256.c would call the AVX + * transforms in the tree's sha256_asm.S, outside the boundary. */ #define USE_INTEL_SPEEDUP #define WOLFSSL_X86_64_BUILD #endif diff --git a/zephyr/zephyr_fips_seed.c b/zephyr/zephyr_fips_seed.c new file mode 100644 index 00000000000..734aa26d330 --- /dev/null +++ b/zephyr/zephyr_fips_seed.c @@ -0,0 +1,107 @@ +/* zephyr_fips_seed.c + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* DRBG seed source for the FIPS v5 bundles, whose wc_GenerateSeed() is a bare + * sys_rand_get() and so not a CSPRNG on the xoshiro or test generators. + * Outside the module boundary. The tree's Zephyr wc_GenerateSeed() in + * wolfcrypt/src/random.c reads the entropy device the same way, but the + * bundle's random.c replaces that file, so the loop is repeated here. */ + +#include + +#ifdef CONFIG_WOLFCRYPT_FIPS_V5 + +#include + +#include +#include + +/* Zephyr 3.7 or later: CONFIG_WOLFCRYPT_FIPS selects STATIC_INIT_GNU. */ +#include +#include +#include +#include + +LOG_MODULE_DECLARE(wolfssl, CONFIG_WOLFSSL_LOG_LEVEL); + +/* A chosen node that is disabled has no device behind it, so check both. */ +#if defined(CONFIG_ENTROPY_HAS_DRIVER) && DT_HAS_CHOSEN(zephyr_entropy) && \ + DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_entropy), okay) + #define WOLF_SEED_ENTROPY_DEVICE + #include + #include +#elif defined(CONFIG_CSPRNG_ENABLED) + #define WOLF_SEED_CSPRNG +#elif !defined(CONFIG_TEST_RANDOM_GENERATOR) + #error "FIPS v5 seeds its DRBG from a zephyr,entropy device or CSPRNG" +#endif + +int wolfssl_zephyr_seed(OS_Seed* os, byte* seed, word32 sz) +{ +#if defined(WOLF_SEED_ENTROPY_DEVICE) + const struct device* dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy)); + word32 off = 0; + uint16_t chunk; + + (void)os; + if (!device_is_ready(dev)) { + return RNG_FAILURE_E; + } + /* entropy_get_entropy() takes a uint16_t length. */ + while (off < sz) { + chunk = (sz - off > 0xFFFFU) ? (uint16_t)0xFFFFU : (uint16_t)(sz - off); + if (entropy_get_entropy(dev, seed + off, chunk) != 0) { + return RNG_FAILURE_E; + } + off += chunk; + } + return 0; +#elif defined(WOLF_SEED_CSPRNG) + (void)os; + return (sys_csrand_get(seed, sz) == 0) ? 0 : RNG_FAILURE_E; +#else + /* CONFIG_TEST_RANDOM_GENERATOR, which Zephyr already flags as insecure. */ + (void)os; + sys_rand_get(seed, sz); + return 0; +#endif +} + +/* wolfSSL_Init() registers WC_GENERATE_SEED_DEFAULT only on its first call, + * and wolfCrypt-only builds never call it. wc_SetSeed_Cb() is refused until + * the power-on self test has run, which is a C constructor, so register at + * APPLICATION level: Zephyr runs the constructors just before it. */ +static int wolfssl_zephyr_seed_init(void) +{ + int ret = wc_SetSeed_Cb(wolfssl_zephyr_seed); + + /* Zephyr hands this return only to a trace hook, and every later + * wc_InitRng() would fail with DRBG_NO_SEED_CB, so say why here. */ + if (ret != 0) { + LOG_ERR("wc_SetSeed_Cb failed: %d", ret); + return -EIO; + } + return 0; +} + +SYS_INIT(wolfssl_zephyr_seed_init, APPLICATION, 0); + +#endif /* CONFIG_WOLFCRYPT_FIPS_V5 */ diff --git a/zephyr/zephyr_init.c b/zephyr/zephyr_init.c index 77a8205806f..4696dfe3a18 100644 --- a/zephyr/zephyr_init.c +++ b/zephyr/zephyr_init.c @@ -19,6 +19,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +/* The port's log module, for the boot-time hook below and the FIPS v5 seed + * callback in zephyr_fips_seed.c, which declares it. Zephyr before 3.2 has + * no zephyr/ include prefix, so the header stays out until one of them + * needs it. */ + +#if defined(CONFIG_WOLFSSL_SYS_INIT) || defined(CONFIG_WOLFCRYPT_FIPS_V5) + +#include + +LOG_MODULE_REGISTER(wolfssl, CONFIG_WOLFSSL_LOG_LEVEL); + +#endif + /* Only a port that brings up a peripheral needs a boot-time hook. */ #ifdef CONFIG_WOLFSSL_SYS_INIT @@ -26,7 +39,6 @@ #include #include -#include #include #ifdef WOLFCRYPT_ONLY @@ -35,8 +47,6 @@ #include #endif -LOG_MODULE_REGISTER(wolfssl, CONFIG_WOLFSSL_LOG_LEVEL); - static int wolfssl_module_init(void) { int ret; From e43b6e540dd9a3a56cbc7895e2b47e4faa7642ac Mon Sep 17 00:00:00 2001 From: jackctj117 Date: Wed, 28 Oct 2026 10:35:05 -0400 Subject: [PATCH 2/2] zephyr: add FIPS v5.2.3 as a Kconfig choice Select the bundle under CONFIG_WOLFCRYPT_FIPS_V5 with CONFIG_WOLFCRYPT_FIPS_V5_2_3. user_settings.h then sets the 5.2.3 version and includes user_settings-fips-v5.2.3.h for the algorithm set of --enable-fips=v5.2.3, as it does user_settings-fips-v7.h for v7; TLS, certificate and platform options keep following Kconfig. The choice selects the RSA, ECC and P-256 options, which user_settings.h would otherwise disable after the set. --- zephyr/Kconfig | 30 +++++++++ zephyr/README.md | 26 ++++++++ zephyr/include.am | 1 + zephyr/user_settings-fips-v5.2.3.h | 102 +++++++++++++++++++++++++++++ zephyr/user_settings.h | 14 +++- 5 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 zephyr/user_settings-fips-v5.2.3.h diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 359520b06d5..313f7ffbf58 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -104,6 +104,7 @@ config WOLFCRYPT_FIPS_V5 bool "FIPS 140-3 (Cert #4718)" help wolfCrypt FIPS 140-3 validated module, Certificate #4718 (version 5.2.1). + A 5.2.3 bundle is selected under "wolfCrypt FIPS v5 bundle". The v5 random.c seeds from a bare sys_rand_get(), so the DRBG is seeded through a callback instead (zephyr_fips_seed.c): from the @@ -130,6 +131,35 @@ config WOLFCRYPT_FIPS_READY endchoice +choice + prompt "wolfCrypt FIPS v5 bundle" + depends on WOLFCRYPT_FIPS_V5 + default WOLFCRYPT_FIPS_V5_2_1 + help + Select the v5 bundle dropped into the tree. Like the version above, + it must match the bundle. + +config WOLFCRYPT_FIPS_V5_2_1 + bool "5.2.1" + help + wolfCrypt 5.2.1. The algorithm set follows the Kconfig options. + +config WOLFCRYPT_FIPS_V5_2_3 + bool "5.2.3" + select WOLFSSL_RSA + select WOLFSSL_ECC + select WOLFSSL_ECC_256 + help + wolfCrypt 5.2.3. The algorithm set is that of + ./configure --enable-fips=v5.2.3, from user_settings-fips-v5.2.3.h. + RSA, ECC and P-256 are selected here because user_settings.h would + otherwise disable them after that file; the other algorithm options + cannot remove what it enables either, and WOLFSSL_ECC_384 and + WOLFSSL_ECC_521 only add the single-precision code for curves the set + already has. + +endchoice + config WOLFSSL_CRYPTO_CB bool "wolfCrypt crypto callbacks" depends on !WOLFSSL_HAS_SETTINGS_FILE diff --git a/zephyr/README.md b/zephyr/README.md index ef0334d1171..46b82780db0 100644 --- a/zephyr/README.md +++ b/zephyr/README.md @@ -76,6 +76,32 @@ west build -p auto -b qemu_x86 modules/crypto/wolfssl/zephyr/samples/wolfssl_tes west build -t run ``` +## Build with a wolfCrypt FIPS v5 bundle + +In a tree holding a v5 FIPS bundle, select it in `prj.conf`: + +``` +CONFIG_WOLFCRYPT_FIPS=y +CONFIG_WOLFCRYPT_FIPS_V5=y +CONFIG_WOLFCRYPT_FIPS_V5_2_3=y +CONFIG_LINKER_SORT_BY_ALIGNMENT=n +``` + +Leave `CONFIG_WOLFCRYPT_FIPS_V5_2_3` out for a 5.2.1 bundle. Every FIPS +boundary needs `CONFIG_LINKER_SORT_BY_ALIGNMENT=n`, which Zephyr defaults on: +the integrity check hashes the boundary as two ranges, and sorting input +sections by alignment moves code out of them, so the build stops while it is +set. + +With 5.2.3, `user_settings.h` takes the algorithm set of +`--enable-fips=v5.2.3` from `user_settings-fips-v5.2.3.h`; the TLS and +certificate options still follow Kconfig. Both v5 bundles seed the DRBG from +the `zephyr,entropy` device, or else the Zephyr CSPRNG, and a board with +neither fails the build unless `CONFIG_TEST_RANDOM_GENERATOR` is set. Under +FIPS v2, v5 and v6 `CONFIG_WOLFCRYPT_ASM` accelerates only the SP math: those +boundaries keep their AES and SHA assembly in a form this module does not +build. + ## Build and Run wolfCrypt Benchmark Application build and execute `wolfssl_benchmark` diff --git a/zephyr/include.am b/zephyr/include.am index 83707bee472..9c5647edc2a 100644 --- a/zephyr/include.am +++ b/zephyr/include.am @@ -10,6 +10,7 @@ EXTRA_DIST+= zephyr/module.yml EXTRA_DIST+= zephyr/wolfssl/options.h EXTRA_DIST+= zephyr/user_settings.h EXTRA_DIST+= zephyr/user_settings-fips-v7.h +EXTRA_DIST+= zephyr/user_settings-fips-v5.2.3.h EXTRA_DIST+= zephyr/fips-v5-compat/posix/time.h EXTRA_DIST+= zephyr/fips-v5-compat/random/rand32.h EXTRA_DIST+= zephyr/README.md diff --git a/zephyr/user_settings-fips-v5.2.3.h b/zephyr/user_settings-fips-v5.2.3.h new file mode 100644 index 00000000000..c64dc52ff1f --- /dev/null +++ b/zephyr/user_settings-fips-v5.2.3.h @@ -0,0 +1,102 @@ +/* user_settings-fips-v5.2.3.h + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Algorithm set of ./configure --enable-fips=v5.2.3, included by + * user_settings.h under CONFIG_WOLFCRYPT_FIPS_V5_2_3, which also selects the + * RSA, ECC and P-256 options so that file cannot disable them afterwards. + * TLS, certificate, platform and DRBG seeding options stay with + * user_settings.h and its Kconfig mapping. */ + +#ifndef WOLFSSL_ZEPHYR_FIPS_V5_H +#define WOLFSSL_ZEPHYR_FIPS_V5_H + +#define TFM_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT +#define WC_RSA_BLINDING +#define WOLFSSL_USE_ALIGN + +/* Hashes and KDFs */ +#define WOLFSSL_SHA224 +#define WOLFSSL_SHA384 +#define WOLFSSL_SHA512 +#define WOLFSSL_NOSHA512_224 +#define WOLFSSL_NOSHA512_256 +#define WOLFSSL_SHA3 +#define HAVE_HKDF +#define WOLFSSL_WOLFSSH + +/* AES. The GHASH method follows the Kconfig choice. */ +#define HAVE_AESGCM +#define HAVE_AESCCM +#define HAVE_AES_ECB +#define WOLFSSL_AES_DIRECT +#define WOLFSSL_AES_COUNTER +#define WOLFSSL_AES_OFB +#define WOLFSSL_CMAC + +/* RSA */ +#define WOLFSSL_KEY_GEN +#define WC_RSA_PSS +#define WC_RSA_NO_PADDING + +/* ECC */ +#define HAVE_ECC +#define ECC_SHAMIR +#define ECC_USER_CURVES +#define HAVE_ECC192 +#define HAVE_ECC224 +#define HAVE_ECC256 +#define HAVE_ECC384 +#define HAVE_ECC521 +#define HAVE_ECC_CDH +#define WOLFSSL_VALIDATE_ECC_IMPORT +#define WOLFSSL_VALIDATE_ECC_KEYGEN + +/* DH */ +#undef NO_DH +#define HAVE_FFDHE_Q +#define HAVE_FFDHE_2048 +#define HAVE_FFDHE_3072 +#define HAVE_FFDHE_4096 +#define HAVE_FFDHE_6144 +#define HAVE_FFDHE_8192 +#define HAVE_DH_DEFAULT_PARAMS +#define HAVE_PUBLIC_FFDHE +#define WOLFSSL_DH_EXTRA +#define WOLFSSL_VALIDATE_FFC_IMPORT + +/* Outside the module */ +#define NO_DSA +#define NO_MD4 +#define NO_MD5 +#define NO_RC4 +#define NO_DES3 +#define NO_DES3_TLS_SUITES + +/* Math. SP_SMALL_STACK moves the 4096-bit mod-exp temporaries (11-23 KB of + * stack on Cortex-M4) to the heap; it touches only the sp_*.c files, which + * sit outside the v5 boundary. */ +#define WOLFSSL_SP_MATH_ALL +#define SP_INT_BITS 8192 +#define WOLFSSL_SP_4096 +#define WOLFSSL_SP_SMALL_STACK + +#endif /* WOLFSSL_ZEPHYR_FIPS_V5_H */ diff --git a/zephyr/user_settings.h b/zephyr/user_settings.h index a7b05f42f89..43aa4eeb845 100644 --- a/zephyr/user_settings.h +++ b/zephyr/user_settings.h @@ -137,7 +137,7 @@ extern "C" { #define HAVE_FIPS_VERSION_PATCH 0 #endif #elif defined(CONFIG_WOLFCRYPT_FIPS_V5) - /* FIPS 140-3 Cert #4718 (wolfCrypt 5.2.1). */ + /* FIPS 140-3 Cert #4718 (wolfCrypt 5.2.1), or the 5.2.3 bundle. */ #ifndef HAVE_FIPS_VERSION #define HAVE_FIPS_VERSION 5 #endif @@ -145,7 +145,11 @@ extern "C" { #define HAVE_FIPS_VERSION_MINOR 2 #endif #ifndef HAVE_FIPS_VERSION_PATCH - #define HAVE_FIPS_VERSION_PATCH 1 + #ifdef CONFIG_WOLFCRYPT_FIPS_V5_2_3 + #define HAVE_FIPS_VERSION_PATCH 3 + #else + #define HAVE_FIPS_VERSION_PATCH 1 + #endif #endif /* fips.c needs a thread-local choice made. Not HAVE_THREAD_LS: * THREAD_LS_T is empty on Zephyr, so it would only drop the ECC/SP @@ -182,6 +186,8 @@ extern "C" { #endif #if defined(CONFIG_WOLFCRYPT_FIPS_V7) || defined(CONFIG_WOLFCRYPT_FIPS_READY) #include "user_settings-fips-v7.h" + #elif defined(CONFIG_WOLFCRYPT_FIPS_V5_2_3) + #include "user_settings-fips-v5.2.3.h" #endif #endif @@ -410,7 +416,9 @@ extern "C" { #endif /* DH */ -#if 0 +#if defined(WOLFSSL_ZEPHYR_FIPS_V5_H) + /* in the v5.2.3 set */ +#elif 0 #undef NO_DH /* on by default */ #define WOLFSSL_DH_CONST /* don't rely on pow/log */ #define HAVE_FFDHE_2048