Skip to content

Zephyr module: wolfPSA provider support + POSIX-free native threading#32

Open
Frauschi wants to merge 17 commits into
masterfrom
zephyr_fixes
Open

Zephyr module: wolfPSA provider support + POSIX-free native threading#32
Frauschi wants to merge 17 commits into
masterfrom
zephyr_fixes

Conversation

@Frauschi

Copy link
Copy Markdown
Owner

Downstream Zephyr integration fixes carried on zephyr_fixes (vs master).
Five commits, in two themes plus a native_sim time fix.

wolfPSA PSA-provider enablement

  • acbd93526 support wolfPSA as the PSA Crypto provider under CONFIG_WOLFPSA: share one wolfCrypt config between the module and wolfPSA, and compile the extra sources wolfPSA needs (ascon, xmss), all gated on CONFIG_WOLFPSA so the stock TLS build is unaffected.
  • a7ded24e9 the module's user_settings.h now lets the USER drive the wolfCrypt config (their CONFIG_WOLFSSL_SETTINGS_FILE, else the wolfPSA default feature set) and applies the wolfPSA structural baseline on top in both cases.

Native Zephyr threading without POSIX

  • 8ae3d20ee a non-SINGLE_THREADED wolfCrypt build on Zephyr used to require CONFIG_POSIX_THREADS/CONFIG_PTHREAD_IPC via a hard #error, even though mutexes and thread creation were already native. Drop the #error; back wolfSSL_Mutex/threads/condvars with native k_mutex/k_thread/k_condvar from <zephyr/kernel.h>, and pull the POSIX pthread shims only when the app actually enables the POSIX layer. Adds a native k_condvar COND_TYPE + WOLFSSL_COND and implements the six wolfSSL_Cond* functions, plus a zephyr/tests/wolfssl_condvar ztest.
  • 56cf493ac gate WOLFSSL_COND on KERNEL_VERSION_NUMBER >= 0x20400 (k_condvar was introduced in Zephyr 2.4), so pre-2.4 targets build without condition variables exactly as before.

native_sim time

  • 4ea9ac70f read the native simulator RTC in z_time() regardless of libc, so ASN.1 certificate date validation has a real wall clock in simulation.

Validation

  • Full wolfcrypt test suite passes on the POSIX path (wolfssl_test).
  • A no-POSIX multi-threaded build exercises native k_mutex/k_thread/k_condvar (wolfssl_condvar ztest: producer/consumer handshake + NULL guards).
  • wolfSSL Zephyr CI matrix (2.7.4 / 3.4.0 / 3.5.0 / 4.x) is all >= 2.4; verified k_condvar is present with a matching API in the v2.7.4 kernel headers.

Pairs with the wolfPSA module changes (separate repo/PR).

Frauschi and others added 5 commits July 17, 2026 13:57
On native_posix/native_sim the host libc is used, so the
CONFIG_RTC && (CONFIG_PICOLIBC || CONFIG_NEWLIB_LIBC) gate that guarded
the native_rtc_gettime() path never matched there. z_time() therefore
fell back to clock_gettime(CLOCK_REALTIME) (uptime since boot), leaving
ASN.1 certificate date validation without a real wall-clock in
simulation.

Read the simulator RTC directly on native builds, independent of the
selected libc. native_rtc_gettime() is unconditionally linked for both
native boards across supported Zephyr versions (3.5 board-local source,
NSI core in newer releases), so no additional guard is needed.

The real-target RTC-device path stays gated as before; its uptime
fallback now lives in the non-native branch so there is no unreachable
code on native builds, and the timespec it uses is zero-initialised so a
failing clock_gettime() returns a defined value.
Under CONFIG_WOLFPSA, use one shared wolfCrypt configuration for both this
module's wolfCrypt objects and the wolfPSA provider so their struct ABI is
identical:

- user_settings.h: when CONFIG_WOLFPSA is set (and no explicit settings file),
  include wolfPSA's user_settings_wolfpsa.h instead of the default TLS body.
- CMakeLists.txt: compile ascon.c and wc_xmss.c/wc_xmss_impl.c (needed by
  wolfPSA, absent from the default source list) via
  zephyr_library_sources_ifdef(CONFIG_WOLFPSA ...).

Both changes are gated on CONFIG_WOLFPSA, so the stock wolfSSL/TLS build is
unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbL4s9KzVRKNLJyEUjzA3i
Restructure the module's user_settings.h so that under CONFIG_WOLFPSA the
wolfCrypt feature configuration comes from the user's own settings file
(CONFIG_WOLFSSL_SETTINGS_FILE) if provided, otherwise wolfPSA's default feature
set, and the wolfPSA structural baseline (user_settings_wolfpsa_baseline.h) is
then applied on top in BOTH cases. Previously a CONFIG_WOLFPSA build always
forced wolfPSA's fixed maximal config, and a custom settings file under
CONFIG_WOLFPSA received no baseline at all (so WOLFSSL_PSA_ENGINE was missing and
wolfPSA would not compile). Pairs with the wolfPSA module changes.
wolfCrypt's Zephyr port already backed wolfSSL_Mutex with k_mutex and
wolfSSL_NewThread with k_thread, but a non-SINGLE_THREADED build still
required CONFIG_POSIX_THREADS / CONFIG_PTHREAD_IPC: wc_port.h issued a
hard #error otherwise, and condition variables were left unimplemented
(an empty WOLFSSL_COND stub deferring to the pthreads translation layer).

- wc_port.h: drop the POSIX #error. Under !SINGLE_THREADED, always include
  <zephyr/kernel.h> (which provides k_mutex, k_thread and k_condvar) and
  pull the POSIX pthread shims only when the application actually enables
  the POSIX layer (CONFIG_PTHREAD_IPC / CONFIG_POSIX_THREADS) and is not
  building for native_sim (CONFIG_ARCH_POSIX, which uses the host headers).
- types.h: add a native Zephyr COND_TYPE (k_condvar over a k_mutex) and
  define WOLFSSL_COND for the WOLFSSL_ZEPHYR threading branch.
- wc_port.c: implement wolfSSL_CondInit/Free/Start/Signal/Wait/End with
  k_condvar; k_condvar_wait(cv, mutex, K_FOREVER) matches pthread_cond_wait
  semantics (atomic unlock/wait/relock).
- zephyr/tests/wolfssl_condvar: new ztest covering the producer/consumer
  wakeup handshake and the NULL-pointer guards, built multi-threaded with
  no POSIX so it exercises the native k_condvar path on native_sim.

A multi-threaded wolfCrypt build on Zephyr now uses native kernel objects
and no longer forces the POSIX compatibility layer. Existing POSIX-enabled
builds are unaffected (the full wolfcrypt test suite still passes).
The native condition-variable support defines WOLFSSL_COND for every
!SINGLE_THREADED Zephyr build, but k_condvar was only introduced in Zephyr
2.4. Guard the COND_TYPE / WOLFSSL_COND definition on
KERNEL_VERSION_NUMBER >= 0x20400 so a pre-2.4 target builds exactly as
before (no condition-variable support) instead of failing on the missing
k_condvar API. wc_port.c's wolfSSL_Cond* implementations are already under
#ifdef WOLFSSL_COND, so they follow automatically.

All wolfSSL Zephyr CI versions (2.7.4, 3.4.0, 3.5.0, 4.x) are >= 2.4 and
are unaffected; verified k_condvar is present with a matching API in the
v2.7.4 kernel headers.
Comment thread wolfssl/wolfcrypt/wc_port.h Outdated
Comment thread wolfssl/wolfcrypt/wc_port.h Outdated
Comment thread zephyr/tests/wolfssl_condvar/testcase.yaml
Comment thread zephyr/CMakeLists.txt Outdated
Comment thread zephyr/user_settings.h
Frauschi added 4 commits July 21, 2026 13:14
- wc_port.h: reword the threading comment ("does not need" rather than "no
  longer needs"), and remove the Zephyr POSIX pthread shim includes. They
  were vestigial: wolfCrypt's Zephyr threading is fully native
  (k_mutex/k_thread/k_condvar) and references no pthread types, so the shims
  were never actually needed. Verified wolfssl_test and wolfssl_tls_thread
  still build on qemu_x86 with CONFIG_POSIX_THREADS=y -- the !ARCH_POSIX path
  the shims lived in.
- tests/wolfssl_condvar/testcase.yaml: restrict to native_sim via
  platform_allow. wc_port.c's z_time() needs clock_gettime(), which non-native
  boards only get with the POSIX clock, so this no-POSIX test can only build
  on native_sim.
Part of moving wolfPSA to derive its config from the module instead of the
module reaching into wolfPSA (review feedback). The module now carries no
wolfPSA-specific configuration:

- user_settings.h: remove the CONFIG_WOLFPSA branch that pulled in
  user_settings_wolfpsa.h and the wolfPSA baseline. The config source is now
  just the user's settings file (CONFIG_WOLFSSL_SETTINGS_FILE) or the module
  default. No wolfPSA reference remains.
- Kconfig: add generic wolfCrypt build-profile knobs -- WOLFSSL_CRYPTO_ONLY,
  WOLFSSL_HASH_DRBG, WOLFSSL_RNG_SEED_CB, WOLFSSL_SINGLE_THREADED -- each mapped
  1:1 to a wolfCrypt #define, applied on top of the chosen config source. These
  are ordinary wolfSSL options; other modules may select them.
- CMakeLists.txt: compile ascon.c and wc_xmss*.c unconditionally like the rest
  of wolfCrypt (their own #ifdef HAVE_ASCON / WOLFSSL_HAVE_XMSS decide
  inclusion) rather than gating them on CONFIG_WOLFPSA.

A plain wolfSSL/TLS build is unaffected (none of the new knobs are selected and
the default config path is unchanged); verified with wolfssl_test.
The native k_condvar/k_mutex/k_thread threading test was not exercised by CI.
Add a twister step to the Zephyr workflow that runs it on native_sim
(introduced in Zephyr 3.4, so skipped on the 2.7.4 matrix entry) and include it
in the failure-log upload conditions. Verified the twister invocation locally
(crypto.wolfssl.condvar passes on native_sim/native/64).
The comment implied wolfCrypt itself pulls in posix_types.h, which is no
longer true after the native-threading rework dropped the pthread shims.
Reword it to explain the actual rationale: the early <sys/types.h> is
defensive so host libc sets __timer_t_defined before any later
posix_types.h pulled in by an application POSIX layer (e.g.
CONFIG_POSIX_API) can define a conflicting timer_t. Comment-only change;
verified the wolfPSA psa_transform image still builds and runs through it.
Comment thread wolfssl/wolfcrypt/wc_port.h Outdated
Comment thread zephyr/Kconfig Outdated
Comment thread zephyr/CMakeLists.txt Outdated
Frauschi added 2 commits July 21, 2026 23:03
…Make sources)

- wc_port.h: reword the early sys/types.h comment to present tense, dropping
  the "no longer" history phrasing.
- zephyr/Kconfig: remove the explanatory comment block above the generic
  build-profile knobs.
- zephyr/CMakeLists.txt: add ascon.c and wc_xmss.c/wc_xmss_impl.c as individual
  zephyr_library_sources() entries in their alphabetical slots, matching the
  rest of the wolfcrypt source list, instead of a special multi-file block.

Verified: the wolfSSL library builds and links in every wolfPSA native_sim
build (which compiles these three sources).
…verage

Adds crypto.wolfssl.condvar_crypto_only, a CONFIG_WOLFSSL_CRYPTO_ONLY=y variant
of the native-threading condvar ztest, giving that build-profile knob explicit
build+run coverage: the native k_mutex/k_thread/k_condvar path must still work
in a WOLFCRYPT_ONLY image. Verified on native_sim/native/64.
Comment thread zephyr/tests/wolfssl_condvar/testcase.yaml Outdated
Comment thread zephyr/Kconfig
Adds WOLFSSL_MLDSA (ML-DSA/Dilithium), WOLFSSL_LMS and WOLFSSL_XMSS alongside the
existing WOLFSSL_MLKEM, so a Kconfig-driven build (no user-provided settings
file) can include exactly the post-quantum families a consumer needs and keep
flash down. Each maps to its wolfCrypt WOLFSSL_HAVE_* define in user_settings.h;
SHAKE is enabled when ML-KEM or ML-DSA is on. All default off, so existing builds
are unaffected.

Verified on native_sim/native/64: module-default wolfssl_test builds clean with
all four PQC knobs on (~123 KB text over the no-PQC default) and with none;
wolfssl_condvar still 2/2.
Comment thread zephyr/user_settings.h
Comment thread zephyr/user_settings.h
Comment thread zephyr/user_settings.h
Comment thread zephyr/user_settings.h
Comment thread zephyr/user_settings.h Outdated
Comment thread zephyr/user_settings.h Outdated
Comment thread zephyr/user_settings.h
Comment thread zephyr/Kconfig Outdated
…ub-options

With wolfPSA driving the module-default (Kconfig-only) config, add knobs so a
wolfCrypt-via-wolfPSA build can trim the API surface / flash. New knobs (defaults
preserve the previous behavior): WOLFSSL_RSA, WOLFSSL_ECC, WOLFSSL_CHACHA_POLY,
WOLFSSL_SNI, WOLFSSL_SESSION_CACHE, WOLFSSL_SESSION_TICKET (default y) and
WOLFSSL_CURVE25519 (default n; Ed25519/Curve25519). Static PSK stays bundled
under WOLFSSL_PSK.

Also per review: ML-DSA size sub-options (NO_LARGE_CODE/SMALL/VERIFY_SMALL_MEM/
DYNAMIC_KEYS/SIGN_SMALL_MEM/MAKE_KEY_SMALL_MEM), WOLFSSL_MLKEM_DYNAMIC_KEYS,
WOLFSSL_SHA3_SMALL, blank lines between the PQC blocks, trim the ML-DSA help, and
clarify why the tail build-profile knobs (incl. HASH_DRBG) live outside the
WOLFSSL_SETTINGS_FILE guard (they apply on the settings-file path wolfPSA uses).

Verified on native_sim/native/64: the 8 wolfSSL secure-sockets scenarios stay
green (90/90; defaults unchanged), the PQC sub-options build, and enabling
WOLFSSL_CURVE25519 pulls Ed25519/Curve25519 into the image.
Comment thread zephyr/Kconfig Outdated
Comment thread zephyr/user_settings.h Outdated
Comment thread zephyr/user_settings.h Outdated
Comment thread zephyr/user_settings.h Outdated
Frauschi added 2 commits July 22, 2026 16:01
Per review: a user-supplied CONFIG_WOLFSSL_SETTINGS_FILE is now authoritative --
the build-profile knobs (WOLFSSL_CRYPTO_ONLY, WOLFSSL_SINGLE_THREADED) apply ONLY
inside the module-default block, never on top of a settings file, so the two
config interfaces no longer mix. The redundant WOLFSSL_HASH_DRBG /
WOLFSSL_RNG_SEED_CB knobs are dropped (the module-default block already defines
HAVE_HASHDRBG/WC_RNG_SEED_CB; a consumer like wolfPSA now checks its
requirements itself). Also decouple TLS session tickets from the session cache
(HAVE_SESSION_TICKET gated only on TLS 1.3) and drop the classic-crypto-knobs
comment.

Verified on native_sim/native/64: the 8 secure-sockets scenarios stay green
(90/90; module-default behavior unchanged).
Move the secure-seed policy into the module (where wolfCrypt's seeding belongs)
instead of the wolfPSA layer. zephyr_init.c registers wc_SetSeed_Cb from the
hardware entropy driver, gated WC_RNG_SEED_CB && CONFIG_ENTROPY_HAS_DRIVER &&
!CONFIG_WOLFSSL_CSPRNG_GENERATOR -- the last term avoids double-setting the
global hook that subsys/random/random_wolfssl.c already installs when it is the
chosen sys_csrand_get provider. WC_RNG_SEED_CB now keys off ENTROPY_HAS_DRIVER;
with no entropy driver wolfCrypt keeps its default wc_GenerateSeed/sys_rand_get.

So every wolfCrypt RNG in the image (TLS, wolfPSA) inherits the cryptographic
seed, and wolfPSA just calls wc_InitRng().

Verified: native_sim (no entropy driver -> fallback) wolfPSA suite 11/11; the
seed-cb compiles + links on nucleo_h743zi with CONFIG_ENTROPY_GENERATOR=y.
Comment thread zephyr/user_settings.h Outdated
Comment thread zephyr/zephyr_init.c Outdated
Frauschi added 2 commits July 23, 2026 10:45
wolfCrypt's Zephyr wc_GenerateSeed() used sys_rand_get(), a general-purpose
PRNG, so obtaining a cryptographic seed previously meant installing a global
wc_SetSeed_Cb from the module's zephyr_init.c. Fold that logic into
wc_GenerateSeed() itself: when a hardware entropy driver is present
(CONFIG_ENTROPY_HAS_DRIVER) it reads the driver directly and a dead source
returns RNG_FAILURE_E; otherwise it keeps the sys_rand_get() fallback. wolfCrypt
now seeds cryptographically by default on Zephyr with no callback.

With that in place:
  - user_settings.h no longer defines WC_RNG_SEED_CB (and HAVE_HASHDRBG is set
    unconditionally in the module-default block -- the old WC_NO_HASHDRBG guard
    was inert),
  - zephyr_init.c drops the seed-cb SYS_INIT and is back to a minimal stub,
  - WOLFSSL_SINGLE_THREADED now defaults y when !MULTITHREADING, so no-threads
    builds (and consumers such as wolfPSA) get it without selecting it.

Verified on native_sim/native/64 (psa_smoke 15/15, socket-TLS + rng suites) and
on nucleo_h743zi, where wolfCrypt's RANDOM and RSA self-tests pass seeding from
the STM32 TRNG.
Address skoll review of the RNG/threading changes:
  - wc_GenerateSeed (Zephyr HW-entropy path): version-gate the new
    <zephyr/device.h>/<drivers/entropy.h> includes like the neighboring random
    headers (the zephyr/-prefixed layout post-dates Zephyr 3.1); chunk the
    request to entropy_get_entropy()'s uint16_t length so a >64KiB seed cannot
    silently truncate; and guard on DT_HAS_CHOSEN(zephyr_entropy) so a board
    with CONFIG_ENTROPY_HAS_DRIVER but no chosen entropy node degrades to
    sys_rand_get() instead of failing the build.
  - wolfssl_condvar CI: the step ran twister against the hardware-model-v2
    target native_sim/native/64, which does not exist on the 3.4.0/3.5.0 CI
    matrix (native_sim_64 there), so the native-threading test was silently
    skipped. Use plain native_sim (valid on those versions and x86 CI) and
    allow both boards in platform_allow; correct the stale clock_gettime comment
    (z_time() now reads the native_sim RTC).

Verified on native_sim/native/64 and nucleo_h743zi (wolfCrypt RANDOM/RSA
self-tests seed from the STM32 TRNG).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant