Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,11 @@ CONFIG_USE_WOLFSSL_ESP_SDK_WIFI
CONFIG_WOLFCRYPT_ARM_SYMMETRIC_ASM
CONFIG_WOLFCRYPT_ASM
CONFIG_WOLFCRYPT_FIPS
CONFIG_WOLFCRYPT_FIPS_PRE_V7_ASM
CONFIG_WOLFCRYPT_FIPS_READY
CONFIG_WOLFCRYPT_FIPS_V2
CONFIG_WOLFCRYPT_FIPS_V5
CONFIG_WOLFCRYPT_FIPS_V5_2_3
CONFIG_WOLFCRYPT_FIPS_V6
CONFIG_WOLFCRYPT_FIPS_V7
CONFIG_WOLFCRYPT_SP_SMALL
Expand Down
30 changes: 27 additions & 3 deletions zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ 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
# <random/rand32.h> and <posix/time.h> onto the current headers.
if(CONFIG_WOLFCRYPT_FIPS_V5)
Comment thread
Frauschi marked this conversation as resolved.
Resolved
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}/src/crl.c)
Expand Down Expand Up @@ -96,16 +106,30 @@ 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)
Comment thread
Frauschi marked this conversation as resolved.
Resolved
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")
endif()
# The v5 seed callback in zephyr_init.c draws on the Zephyr CSPRNG, which
# must read the entropy driver itself rather than pass the seed through
# a DRBG outside the module, as the CTR-DRBG and PSA generators do. Only
# with an entropy driver, which sets CSPRNG_ENABLED: without one the
# callback uses the test generator or fails the build. The test CSPRNG is
# sys_rand_get() under a name Zephyr already flags as insecure.
if(CONFIG_WOLFCRYPT_FIPS_V5 AND CONFIG_CSPRNG_ENABLED
AND NOT CONFIG_HARDWARE_DEVICE_CS_GENERATOR
AND NOT CONFIG_TEST_CSPRNG_GENERATOR)
message(FATAL_ERROR "wolfCrypt FIPS v5 needs CONFIG_HARDWARE_DEVICE_CS_GENERATOR=y: "
"the DRBG seed must come straight from the entropy driver")
endif()
set_source_files_properties(${WOLF_FIPS_SRCS} PROPERTIES COMPILE_OPTIONS
"-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})
Expand Down Expand Up @@ -211,7 +235,7 @@ if(CONFIG_WOLFSSL)
if(CONFIG_ARM64 AND NOT WOLF_BOUNDARY_ASM)
zephyr_library_sources(${WOLF_ARM_ASM_DIR}/armv8-sha1-asm_c.c)
endif()
elseif(CONFIG_X86_64)
elseif(CONFIG_X86_64 AND NOT CONFIG_WOLFCRYPT_FIPS_PRE_V7_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
Expand Down
78 changes: 73 additions & 5 deletions zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -98,6 +104,15 @@ 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_init.c): the Zephyr CSPRNG,
which reads the zephyr,entropy device. A board without an entropy
driver fails the build unless CONFIG_TEST_RANDOM_GENERATOR is set, and
so does any CSPRNG but CONFIG_HARDWARE_DEVICE_CS_GENERATOR or the test
one: the seed must come straight from the driver, not through a DRBG
outside the module, as the CTR-DRBG and PSA generators route it.

config WOLFCRYPT_FIPS_V6
bool "FIPS 140-3 (SRTP-KDF full submission)"
Expand All @@ -119,6 +134,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
Expand Down Expand Up @@ -225,14 +269,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"
Expand All @@ -243,14 +291,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"
Expand Down Expand Up @@ -327,12 +380,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_PRE_V7_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_PRE_V7_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.
Expand Down Expand Up @@ -703,6 +767,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
Expand Down
40 changes: 40 additions & 0 deletions zephyr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,46 @@ 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 CSPRNG, which has to be `CONFIG_HARDWARE_DEVICE_CS_GENERATOR`, the
default with an entropy driver, so that the seed comes straight from the
driver and not through a DRBG outside the module; a board with no entropy
driver 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.

The `crypto_only` scenario of `tests/wolfssl_condvar` also calls
`wc_InitRng()`, which under v5 only works once the hook in `zephyr_init.c`
has registered the seed callback; `wolfcrypt_test()` registers it itself, so
the test sample cannot tell. CI runs it without a bundle. With one:

```
west build -p always -b native_sim modules/crypto/wolfssl/zephyr/tests/wolfssl_condvar -- -DCONFIG_WOLFSSL_CRYPTO_ONLY=y -DCONFIG_WOLFCRYPT_FIPS=y -DCONFIG_WOLFCRYPT_FIPS_V5=y -DCONFIG_LINKER_SORT_BY_ALIGNMENT=n
west build -t run
```

Add `-DCONFIG_WOLFCRYPT_FIPS_V5_2_3=y` for a 5.2.3 bundle.

## Build and Run wolfCrypt Benchmark Application

build and execute `wolfssl_benchmark`
Expand Down
36 changes: 36 additions & 0 deletions zephyr/fips-v5-compat/posix/time.h
Original file line number Diff line number Diff line change
@@ -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 <posix/time.h> 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 <zephyr/version.h>

#if KERNEL_VERSION_NUMBER >= 0x40300
#include <time.h>
#else
#include <zephyr/posix/time.h>
#endif

#endif /* WOLFSSL_ZEPHYR_COMPAT_POSIX_TIME_H */
30 changes: 30 additions & 0 deletions zephyr/fips-v5-compat/random/rand32.h
Original file line number Diff line number Diff line change
@@ -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 <random/rand32.h> 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 <zephyr/random/random.h>

#endif /* WOLFSSL_ZEPHYR_COMPAT_RAND32_H */
3 changes: 3 additions & 0 deletions zephyr/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ 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
EXTRA_DIST+= zephyr/samples/wolfssl_benchmark/
EXTRA_DIST+= zephyr/samples/wolfssl_benchmark/CMakeLists.txt
Expand Down
5 changes: 5 additions & 0 deletions zephyr/tests/wolfssl_condvar/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=131072

CONFIG_WOLFSSL=y
CONFIG_WOLFSSL_BUILTIN=y

# Seed source for the RNG test, as in samples/wolfssl_tls_sock: native_sim's
# fake entropy driver, with the test generator as the fallback.
CONFIG_ENTROPY_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y
Loading
Loading