Commit Graph
819 Commits
Author SHA1 Message Date
David Garske 80d2969348 Merge pull request #11098 from Frauschi/script_fix
Fix CI flakes from ccache saturation and stale schedule estimates
2026-08-06 18:31:03 -07:00
Tobias Frauenschläger 5d2188f958 CI: build the cert sign callback path
WOLFSSL_CERT_SIGN_CB is set only by --enable-certsigncb, and that flag
appears nowhere under .github/. wc_SignCert_cb() is therefore compiled by
no CI job, and neither is test_wc_SignCert_cb(), the only test covering
it. The buffer bounds check the preceding commits add to that function,
and the test assertions that go with it, would have merged without
anything building them.

Added as its own entry in the os-check Linux config list, in sorted
position. "minutes" is seeded at 8.3 from the sibling --enable-all entries
rather than omitted: the omission defaults it to 1.0, which sorts an
eight minute build last in a list scheduled longest-first and deals it
into whichever shard is already fullest. It also suppresses the stale
estimate annotation that would otherwise prompt the refresh. Replace it
with the real number from the Minutes column of the first run.

Verified by running the entry through the workflow's own driver,
.github/scripts/parallel-make-check.py, with the CFLAGS the workflow
applies at make time (-pedantic -Wdeclaration-after-statement
-Wnull-dereference -Wno-overlength-strings
-DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE) and --private-dir=certs.
The out-of-tree build produces no compiler warnings and make check
reports 17 passed, 6 skipped, 0 failed. Both test_wc_SignCert_buffer_bounds
and test_wc_SignCert_cb run rather than skip.
2026-08-06 22:19:42 +02:00
Tobias Frauenschläger 9a788724d7 Fix CI flakes from ccache saturation and stale schedule estimates
pq-all and trackmemory restore a seed ccache that already sits at its
cap, so every object a run compiles evicts a seeded one that is still
needed. Both reported a cache 100% full with over 200 cleanups and a
43-44% hit rate, and their configs took 3-5x their warm time. That left
pq-all shards finishing at 23-26 min against a 30 min limit: a healthy
shard passed with 5.6 min to spare, so any hiccup ahead of the build
took the job down. One did, twice, when the prebuilt deb image came up
short and the dependency step fell back to apt for 9.7 min - the only
two jobs out of 47 whose install ran past 2 min are the only two that
timed out. Size both caches to hold the seeded objects and a run's own
alongside them, and widen the limits so a slow install is survivable.

Raise the trackmemory limit as well, for a different reason: its
wolfEntropy configs have overrun it outright, once with six configs
done inside 8 min while all-wolfentropy ran on for another 32. That is
a stall rather than a slow run - 91 jobs have a 17.2 min median and a
17.9 min p90, with nothing between 18 min and the cap - so the higher
limit is headroom, not a fix. It costs nothing on a healthy run.

Recalibrate "minutes", which drives longest-first scheduling and shard
balancing. pq-all and fips-dev-no-post had drifted several-fold in both
directions: two frodokem cross-builds were declared at 4 min but take
0.3, so the pool kept scheduling them first as its longest work. pq-all
is calibrated from runs whose ccache actually hit, which the resized
cache makes the normal case; a value read off a cold run makes every
warm run warn instead. os-check-linux was already calibrated cold and
correct, so only its three genuine outliers change.

Both config lists are re-sorted to restore the documented descending
order, so most of their diff is a mechanical move rather than a value
change. Shard totals come out at 29.4/29.6 for pq-all and 76.9-77.7
across the four os-check shards.
2026-08-06 18:56:15 +02:00
Tobias Frauenschläger eab70a1e88 Merge pull request #11031 from douzzer/20260727-fips-dev-no-post
20260727-fips-dev-no-post
2026-08-06 08:47:10 +02:00
Daniel Pouzzner 67df4928c5 fixes from peer review, post-rebase test results, and test coverage expansion:
wolfcrypt/src/wc_mldsa.c: WC_C_DYNAMIC_FALLBACK fixes for AVX512.

tests/api/test_frodokem.c, wolfcrypt/test/test.c: fixes for WC_DEBUG_CIPHER_LIFECYCLE.

wolfcrypt/src/fe_x25519_asm.S, wolfcrypt/src/port/arm/armv8-32-aes-asm.S,
wolfcrypt/src/port/arm/armv8-aes-asm.S, wolfcrypt/src/port/arm/armv8-aes-asm_c.c,
wolfcrypt/src/port/arm/thumb2-aes-asm.S, wolfcrypt/src/sha3_asm.S,
wolfcrypt/src/wc_mldsa_asm.S: regenerate from scripts#647

.github/workflows/fips-dev-no-post.yml:
* update "minutes" for tests using empirical data;
* add --enable-experimental --enable-all-quantum-crypto to kernel-settings-all-asm scenario and rename it kernel-settings-all-pqc-asm; add all-pqc-asm-fallback-fuzzer scenario.

wolfcrypt/src/wolfentropy.c: remove WC_FIPS_LL_CRYPTO (it is not a FIPS file except in FIPS v5.2.4).

wolfcrypt/src/sha256.c: fix for rebase error (stray #endif).
2026-08-05 13:55:14 -05:00
Daniel Pouzzner 64a91957af fixes from AI review:
linuxkm/x86_vector_register_glue.c: in wc_save_vector_registers_x86(), properly squelch the hard-IRQ call warning if flags & WC_SVR_FLAG_MAYBE_INHIBIT;

src/internal.c: in AllocKey(), properly set key_inited = 1 if wc_SlhDsaKey_Init() succeeds;

.github/workflows/fips-dev-no-post.yml: test -DWC_FIPS_AESGCM_NO_SHORT_NONCES.
2026-08-05 13:53:47 -05:00
Daniel Pouzzner 83b175ce95 fixes and improvements from AI review:
.github/workflows/fips-dev-no-post.yml: add reporting of fuzzing seed.

wolfcrypt/src/aes.c, tests/api/test_aes.c, .wolfssl_known_macro_extras:

* change FIPS AES-GCM nonce size restrictions from from opt-out (WC_FIPS_AESGCM_ALLOW_SHORT_NONCES) to opt-in (WC_FIPS_AESGCM_NO_SHORT_NONCES).
* apply restrictions only on encryption operations, never on decryption.

configure.ac: fix HAVE_FIPS_VERSION of fips-ready; fix enable_dh setup in KERNEL_MODE_DEFAULTS setup; fix help message for --enable-dh.

linuxkm/x86_vector_register_glue.c: add dump_stack() on each BUG/WARNING message that didn't already have it.

src/tls.c: fix a couple leaks in TLSX_KeyShare_GenDhKey().

tests/swdev/swdev.c: gate src->sha_method access in swdev_sha256_copy_state() and swdev_sha512_copy_state() appropriately.

tests/unit.c: conditionally include dh.h, to assure wc_dh_enable() is available.

wolfcrypt/src/dh.c:
* in wc_InitDhKey_ex(), zero the key at entry unless null, remove duplicate key->trustedGroup = 0, and call wc_FreeDhKey() on error at end.
* add missing wc_dh_enabled checks in  wc_DhGeneratePublic() and wc_DhGenerateParams().

wolfcrypt/src/error.c: fix missing space in FIPS_UNAPPROVED_E string.

b/wolfssl/wolfcrypt/settings.h: sense __SIZEOF_INT128__ and if defined, but HAVE___INT128_T and/or HAVE___UINT128_T are undefined, define them.

wolfcrypt/src/falcon.c: tweak the gate on __uint128_t availability to lean solely on HAVE___UINT128_T.

wolfcrypt/src/random.c: fix a couple missed WC_NO_ERR_TRACE() wrappers.

wolfcrypt/src/rng_bank.c: properly tolerate WC_ACCEL_INHIBIT_E as a retval from bank->affinity_lock_cb().

wolfcrypt/src/sha256.c, wolfcrypt/src/sha512.c: move #undef WC_C_DYNAMIC_FALLBACK for WOLFSSL_AESNI without USE_INTEL_SPEEDUP to follow all includes, assuring no struct layout conflict.

wolfcrypt/src/sha512.c: fix wrong call in intelasm Transform_Sha512() !WC_C_DYNAMIC_FALLBACK SHA512_C path.

wolfcrypt/test/test.c: fix double-WC_TEST_RET_ENC_EC() in mldsa_param_*_vfy_test().
2026-08-05 13:53:47 -05:00
Daniel Pouzzner 2f15926139 .github/workflows/fips-dev-no-post.yml: add new workflow to cover --enable-fips=dev-no-post.
Notes:

* EXTRA_CPPFLAGS carries -Werror in the base configure line, because the
  autotools -Werror is gated on a VCS checkout being detected in the configure
  CWD and these are VPATH builds, which would otherwise silently get no -Werror
  at all.

* The fuzzing cell's WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED is $$, which changes
  from run to run.

* The two out-of-tree kernel-module cells (linuxkm, linuxkm-all-asm) are
  commented out, with a note that out-of-tree module builds don't work yet.
2026-08-05 13:53:47 -05:00
Daniel Pouzzner 4f2953252d .github/workflows/codespell.yml: add *.bin to skip list. 2026-08-05 13:53:46 -05:00
Tobias Frauenschläger ff730fec9e Keep the record size probe clear of a suspended build
Second review follow-up on the async record layer series.

Stop the probe reselecting the cipher side. BuildMessage()'s BUILD_MSG_BEGIN
case can call SetKeysSide() for DTLS with secure renegotiation, which swaps
the active encryption state and clears recordSzOverhead. That is not part of a
size calculation, and after the previous commit the suspended build survives
to resume against whatever side the probe last chose, so a DTLS 1.2 record
suspended for PREV_ORDER could resume against the renegotiation keys. Skip it
when sizeOnly is set; the sizes are the same either way.

The probe itself has to keep running. Not re-entering BuildMessage at all
while a build is suspended looks tidier, but wolfssl_local_GetMaxPlaintextSize()
derives the DTLS fragment size from this result, so falling back to the upper
bound there shrinks fragments inconsistently between calls and the MTU
reproducer fails its buffer comparison. Saving and restoring the two fields is
what keeps the answer exact.

Resume inside the record when handshake content is left. The previous commit
declined to skip the padding for a fragmented or coalesced
certificate_request, which was right, but left processReply at doProcessInit
with the index inside the record, so the resume still started a fresh record
parse in the middle of one. Mirror both halves of the end of record block
instead: set runProcessingOneMessage when content remains, advance past the
padding only at the boundary.

Note the shared state at the source. BuildMessage() and BuildTls13Message()
write ssl->options.buildMsgState even for a sizeOnly probe with asyncOkay
clear, where everything else goes to the caller's own arguments. Nothing said
so at those sites, so the next sizeOnly caller would reintroduce this.

Record why only one of the three wc_ecc_make_key_ex() calls in eccsi.c needs
a wait: the other two are preceded by wc_ecc_free(), which clears the marker
their pending path is gated on. Moving either free would make them pend.

Test changes. Force the overhead cache cold before probing, otherwise an AEAD
suite answers from the cache without ever calling BuildMessage and the
assertions hold no matter what the probe did. Compare against BuildMessage's
own figure rather than only checking the size is positive, and run the whole
thing for TLS 1.3 as well as TLS 1.2, since BuildTls13Message() clobbers the
state by a different route: its sizeOnly return bypasses exit_buildmsg
entirely. Checked by stubbing the restore out again, which fails the test.

Also spell the new guard in cryptocb_test() as #if defined(WOLFSSL_ASYNC_CRYPT)
to match the rest of that file, which uses that form 170 times against 4.
2026-08-05 20:39:57 +02:00
Tobias Frauenschläger ac7bff1147 CI: run the async software simulator against --enable-all
Nothing in CI exercised an asynchronous build that actually returns
WC_PENDING_E from a full feature set, which is why the five preceding
fixes all describe failures no workflow could see.

The async workflow has two groups and neither reaches these paths. The
asynccrypt-all entries pass --enable-asynccrypt --enable-all, but
--enable-all turns on cryptocb, and configure.ac only auto-enables the
software simulator when cryptocb, pkcallbacks, Cavium and Intel QA are all
off. Those builds therefore define WOLFSSL_ASYNC_CRYPT without ever
suspending an operation. The asynccrypt-sw entries do suspend, but they
build only OCSP stapling, so they compile neither TLS 1.3 post-handshake
authentication nor DTLS.

Add one entry that pairs --enable-asynccrypt-sw with --enable-all and
--enable-dtls13, which covers both reproducers: the post-handshake auth
case in tests/test-tls13.conf and the DTLS MTU case in
tests/test-dtls-mtu.conf.

Measured at 1.6 minutes locally. Declared as 3 to match the neighbouring
asynccrypt-all entries, which measure 1.4 locally against their declared 3,
so this machine runs roughly twice as fast as whatever those values were
taken from and 1.6 here projects to about 3.4 there. The value is only a
scheduling weight, and the existing entries are left alone rather than
rewritten from local timings.
2026-08-05 08:34:09 +02:00
David Garske e51c06e0a6 Merge pull request #10983 from Frauschi/zephyr_fixes
Zephyr: wolfSSL module support for the wolfPSA provider and native RTOS use
2026-08-04 20:04:25 -07:00
David Garske 5f272267c0 Merge pull request #10901 from Frauschi/slhdsa_tls_handshake
Add SLH-DSA support for the TLS 1.3 and DTLS 1.3 handshake
2026-08-04 18:46:01 -07:00
David Garske 0ffedd2b69 Merge pull request #10971 from LinuxJedi/se050_applet72_ecdh
SE050: create ECDH derive target object for applet 7.2 middleware
2026-08-04 17:35:23 -07:00
David Garske d6708600a2 Merge pull request #11027 from Frauschi/fenrir_2
Fixes for OCSP stapling, cert manager, and certificate_status_request_v2 handling
2026-08-04 15:54:59 -07:00
David Garske 684e06df00 Merge pull request #10991 from padelsbach/ccache-init-seed-settings
CI: set ccache path so settings are saved on initial seed
2026-08-04 15:54:14 -07:00
Tobias Frauenschläger 039d689809 Merge pull request #10975 from aidangarske/x509-tiny-ci
Move WOLFSSL_X509_TINY test to the unit test suite and run
2026-08-04 23:28:52 +02:00
Tobias Frauenschläger ac75f181cd Add SLH-DSA support for the TLS 1.3 and DTLS 1.3 handshake
Implement SLH-DSA (SPHINCS+, FIPS 205) as an entity authentication
algorithm for the TLS 1.3 and DTLS 1.3 handshake, following
draft-reddy-tls-slhdsa. All twelve parameter sets (SHAKE and SHA2 families,
128/192/256 in the f and s variants) are wired into the handshake for
signing and verifying the CertificateVerify message; test certificates and
configs cover the 128f and 128s sets.

Handshake integration:
- Map the SLH-DSA signature schemes to and from the wire in the
  signature_algorithms extension and CertificateVerify. The mapping,
  advertisement, and OID handling are gated per parameter set so a build
  only offers, accepts, and maps the variants actually compiled in
  (including partial SHA2 builds).
- Sign and verify the CertificateVerify with an SLH-DSA entity key, and
  load SLH-DSA private keys and certificates (ssl_load.c, ssl.c,
  ssl_api_pk.c, asn.c).
- Preserve the verify return code on a failed SLH-DSA CertificateVerify
  rather than flattening every non-zero result to SIG_VERIFY_E.
  wc_SlhDsaKey_Verify already returns SIG_VERIFY_E on a real mismatch, so
  the failure semantics are unchanged while WC_PENDING_E (async crypto
  callbacks) and hard errors now propagate, matching ML-DSA and Falcon.

Protocol version gating:
- SLH-DSA is defined for TLS 1.3 only, so the schemes are no longer offered
  to a TLS 1.2 peer, and MatchSigAlgo and PickHashSigAlgo pin an SLH-DSA
  certificate both to the scheme for its exact parameter set and to
  TLS 1.3.
- Reject a Falcon, ML-DSA or SLH-DSA key in the TLS 1.2 CertificateVerify
  with SIG_TYPE_E. No signature scheme below TLS 1.3 covers a post-quantum
  key, the record is reserved for a classic signature, and the signing
  switches have no post-quantum case, so continuing would have sent the
  reserved buffer's uninitialized tail.

Streamed CertificateVerify send:
- SLH-DSA signatures are large (up to ~50 KB). When the CertificateVerify
  body exceeds a single record, generate the signature into a
  connection-level buffer and emit it one record at a time so the output
  buffer never has to hold the whole signature. This keeps peak memory near
  one signature plus a single fragment and resumes correctly across a
  non-blocking WANT_WRITE without recomputing the randomized signature.
  Gated by WOLFSSL_TLS13_STREAM_CERT_VERIFY (TLS 1.3, non-async, PQC
  signatures); DTLS and WOLFSSL_ASYNC_CRYPT keep the existing in-place
  fragmented path.
- Drop a half-sent streamed CertificateVerify in wolfSSL_clear. Left in
  place, the resume guard would fire on the next handshake and re-send the
  previous one's signature into a different transcript.
- Dual-algorithm (WOLFSSL_DUAL_ALG_CERTS, BOTH) CertificateVerify bodies are
  streamed as well. The combined two-signature body may include a
  variable-length signature, so the body buffer is sized from the
  per-signature upper bounds and the exact length is recorded after signing;
  the small trailing slack is never sent.

Buffer sizing:
- Keep MAX_X509_SIZE a fixed 9 KB for post-quantum builds. It sizes a
  static per-certificate slot embedded by value in every cached session, so
  it must not scale with a post-quantum signature; nor may it derive from
  the enabled ML-DSA level, or a level-restricted build would silently drop
  certificates that a full build keeps.
- Add MAX_CERT_WIRE_SZ for the largest certificate that may appear in a
  handshake message, sized from the enabled post-quantum signatures, and
  derive MAX_CERTIFICATE_SZ from it instead of from MAX_X509_SIZE.
- Add MAX_CERT_MSG_DEPTH for the chain depth assumed when sizing the
  certificate message. MAX_CHAIN_DEPTH bounds how deep a chain may be
  verified, while this sizes a buffer an unauthenticated peer can make us
  allocate, so it is trimmed to 5 when a post-quantum certificate has
  inflated the per-certificate size. Classic builds are unchanged.
- Size the CertificateVerify buffers from the actual signature length
  instead of the worst-case WC_MAX_CERT_VERIFY_SZ, which balloons with
  SLH-DSA. WC_MAX_CERT_VERIFY_SZ is retained for API compatibility and its
  growth is documented in README.md.
- Order Scv13Args widest member first so it carries no interior padding and
  still fits ssl->async->args under WOLFSSL_ASYNC_CRYPT together with
  WOLFSSL_DUAL_ALG_CERTS.

Dual-algorithm certificates:
- Reserve the two signature length prefixes in the in-place
  CertificateVerify sizing that the streamed path already accounted for.
- Build the PreTBS for an alternative signature check from the certificate
  size minus both signatures, and retry once at a size the canonical
  re-encode cannot exceed when that estimate turns out short. The estimate
  keeps the allocation small on constrained targets, and wc_GeneratePreTBS
  reports an encoder failure as WOLFSSL_FAILURE, which is zero, so a
  non-positive result is now an error instead of silently skipping
  ConfirmSignature and reading as a verified signature.

Device held private keys:
- Support an SLH-DSA private key that lives in a device and is referenced
  by id or label. The parameter set cannot be recovered from a device side
  identifier, so it is carried from the key type down to
  wc_SlhDsaKey_Init_id and wc_SlhDsaKey_Init_label, and the key is released
  with wc_SlhDsaKey_Free once the certificate and key pair is checked.

Robustness:
- Check the SlhDsaParamToType, wc_SlhDsaKey_PublicSizeFromParam and
  wc_SlhDsaParamToOid results in the certificate and key load paths.
- Zeroize an SLH-DSA key before wc_SlhDsaKey_Init, which can return
  NOT_COMPILED_IN before it clears the object, in both the certificate load
  path and AllocKey.
- Take the alternative key's parameter set from the certificate's sapkiOID
  rather than keyOID, which describes the native key.
- Re-initialise across hash families in wc_SlhDsaKey_PublicKeyDecode as
  wc_SlhDsaKey_PrivateKeyDecode already does. The hash objects share a union
  selected by family, so importing across families writes the new family's
  state over the old one's and orphans it.
- Copy pkCurveOID in SetSSL_CTX when only SLH-DSA is enabled, matching the
  struct member guard. Without it the field stayed zero and the signature
  scheme matching above was dead in exactly that build.
- Derive the per parameter set WOLFSSL_SLHDSA_PARAM_NO_* macros from the
  group level exclusions, and select WC_SLHDSA_DEFAULT_PARAM with those
  same macros, so the parameter table and the TLS mappings cannot disagree.
- Add SLH-DSA to the lean build WOLFSSL_MAX_SIGALGO carve-out, since twelve
  more entries no longer fit the small list.
- Prefix the new SLHDSA_ALL_NO_* macros in the installed header with WC_.

Tests and certificates:
- Add SLH-DSA entity (client and server) certificates for the SHAKE and
  SHA2 128f and 128s parameter sets, and update the generation script.
- Add TLS 1.3 and DTLS 1.3 entity-cert CertificateVerify test configs
  covering the fragmented (128f) and single-record (128s) send paths for
  both hash families, wired into suites.c. These sign with the entity key,
  so they are excluded from verify-only builds.
- Interrupt the streamed CertificateVerify with one WANT_WRITE and with
  several on the same record, and assert the handshake still completes and
  re-emits identical bytes, which the blocking .conf handshakes never
  exercise. The record to interrupt is counted first, because the server's
  record batching differs between builds. Where the flight is flushed as a
  single write the send is retried below SendTls13CertificateVerify, so
  these do not by themselves cover the fragOffset resume path.
- Drive the streamed path with an ML-DSA leaf under a negotiated
  max_fragment_length, covering it for a non SLH-DSA algorithm.
- Reject a TLS 1.2 handshake that presents an SLH-DSA client certificate.
- Map every compiled-in scheme from its wire code point to the key OID, and
  extend the exhaustive SaToNid coverage with the twelve new algorithms.
- Accept an SLH-DSA private key referenced by id and by label.

Build configuration:
- configure.ac: --enable-slhdsa now keeps the certificate/ASN code enabled
  (as --enable-mldsa does), so an SLH-DSA-only build with RSA, ECC and DH
  disabled configures instead of erroring that ASN is off.
- Guard the WOLFSSL, WOLFSSL_CTX and WOLFSSL_X509 pkCurveOID members for
  WOLFSSL_HAVE_SLHDSA, so an SLH-DSA-only build declares the field the
  handshake and CopyDecodedToX509 already reference under an SLH-DSA guard.
- Mark checkKeySz used in the SLH-DSA branch of ProcessBufferCertPublicKey;
  SLH-DSA is the only certificate signature algorithm with no minimum-size
  check, so an SLH-DSA-only build otherwise tripped -Wunused-parameter.
- Propagate haveSlhDsaSig in wolfSSL_set_SSL_CTX, which copied the Falcon
  and ML-DSA flags but not the SLH-DSA one.
- CI: add a SHA2-only SLH-DSA build (--enable-slhdsa=sha2) so the
  SHAKE-disabled combined-maxima guards are exercised, and an async crypto
  build with dual-algorithm certificates, which is the only configuration
  that compiles the in-place fragmented CertificateVerify send.
2026-08-04 22:23:03 +02:00
Aidan Garske 82cf3d8947 Add x509 tiny certificate test coverage 2026-08-04 12:21:25 -07:00
Paul Adelsbach 1c9ebe1af6 PR feedback: use instead of duplicating path 2026-08-04 12:06:11 -07:00
Tobias Frauenschläger 044f08c0ea Zephyr: wolfSSL module support for the wolfPSA provider and native RTOS use
Extend the wolfSSL Zephyr module for the wolfPSA-provider and secure-sockets
efforts:

  - Native RTOS threading: wolfCrypt's Zephyr port uses k_mutex/k_thread/
    k_condvar directly (no CONFIG_POSIX_THREADS), with k_condvar gated on the
    kernel version, covered by a native-threading ztest wired into CI.
  - Config interface: a user-supplied CONFIG_WOLFSSL_SETTINGS_FILE is
    authoritative and the module never layers Kconfig #defines over it. The
    module-default block is shaped by build-profile knobs (WOLFSSL_CRYPTO_ONLY,
    WOLFSSL_SINGLE_THREADED, which now defaults from !MULTITHREADING) plus new
    classic-crypto/TLS/PQC feature knobs (RSA/ECC/ChaCha-Poly/Curve25519/SNI/
    session-cache/session-ticket and ML-KEM/ML-DSA/LMS/XMSS/Falcon, each with
    its memory-reduction "small" options). A consumer such as wolfPSA validates
    its own requirements rather than the module injecting them.
  - DRBG seeding: wc_GenerateSeed() on Zephyr draws seed material from the
    hardware entropy driver when present (chunked to the entropy API's uint16_t
    length, DT_HAS_CHOSEN-guarded) and falls back to sys_rand_get() otherwise;
    HAVE_HASHDRBG stays guarded by WC_NO_HASHDRBG.
  - z_time(): read the native_sim simulator RTC for a real wall clock on the
    native targets regardless of libc.

Verified on native_sim/native/64 and nucleo_h743zi.
2026-08-04 20:53:36 +02:00
Andrew Hutchings 6176a5a77d SE050: skip peer key upload on applet 7.2 ECDH path (peer review)
The direct ECDH APDU carries the peer public point in the command, so
uploading the peer key to the SE050 on the applet >= 7.2 path wasted
APDU round trips, consumed a persistent object slot per distinct peer
in the default build, and added a failure path the derive does not
need. Confine the upload, the keyId bookkeeping and the keyCreated
cleanup to the pre-7.2 arm; on 7.2 builds a reference object is only
taken when the peer public key is already SE050-resident.

Also from review: validate the ECC direct-APDU response length against
the curve size, mirroring the Curve25519 arm; scope the derive-key
state (deriveKey, ctx_derive_key, deriveKeyCreated and their init and
cleanup) into the pre-7.2 arm instead of voiding it; and reword the CI
workflow comment to describe SE050_SIM_STRICT_ECDH as a regression
guard, noting the pre-7.2 arm is hardware-verified (SE050C applet
3.1.1) until an 03_XX matrix leg exists.

Verified: wolfCrypt suite passes against the strict simulator on the
07_02 build; the pre-7.2 arm compiles clean against an 03_XX SDK.
2026-08-04 11:42:20 +01:00
Sean Parkinson 03e9107df4 AES asm: Add GCM 8-bit table, fixes
Added assembly to do 8-bit-table GCM_gmult_len.
Wired it into aes.c and wired small to use C code.
Fixed guards around assembly.
2026-08-04 17:48:14 +10:00
Andrew Hutchings 160c616a97 SE050 CI: update pinned simulator to PR 12 head
The pinned simulator gained review cleanups; move SIMULATORS_REF to the
final wolfSSL/simulators PR #12 head. Becomes fetchable from the
upstream clone once that PR is merged.
2026-08-03 16:34:07 +01:00
Andrew Hutchings dc364d0eaa SE050 CI: pin simulator with direct ECDH variant support
Bump SIMULATORS_REF to the simulator commit that accepts the Tag7-less
direct ECDH form the port now uses on applet >= 7.2 and that refuses
HMACKey ReadObject unconditionally, both matching SE051 applet 7.2.0
hardware. The pinned commit is wolfSSL/simulators PR #12 and becomes
fetchable from the upstream clone once that PR is merged.
2026-08-03 16:34:07 +01:00
Andrew Hutchings a2bde67b70 SE050 CI: update pinned simulator to PR 11 head
The pinned simulator gained an sdk-test fix and review changes; move
SIMULATORS_REF to the final wolfSSL/simulators PR #11 head. Becomes
fetchable from the upstream clone once that PR is merged.
2026-08-03 16:34:07 +01:00
Andrew Hutchings 2ae4ec7300 SE050 CI: pin simulator that always enforces symmetric read policy
Bump SIMULATORS_REF to the simulator commit that refuses ReadObject on
an HMACKey object without POLICY_OBJ_ALLOW_READ in all modes, matching
real hardware on every applet generation as verified on SE050C applet
3.1.1 silicon. With this pin a plain (non-strict) CI run reproduces the
SW 0x6986 readback failure that previously only appeared on hardware,
covering the pre-7.2 Binary derive target fix in the previous commit.

The pinned commit is wolfSSL/simulators PR #11 and becomes fetchable
from the upstream clone once that PR is merged.
2026-08-03 16:34:07 +01:00
Andrew Hutchings 4c055f5272 SE050 CI: pin simulator with applet 7.2 read-policy enforcement
Bump SIMULATORS_REF to the simulator commit that, in strict mode,
refuses ReadObject on an HMACKey object unless the policy attached at
creation grants POLICY_OBJ_ALLOW_READ. This reproduces the SW 0x6986
derive-target readback failure seen on SE05x applet >= 7.2 hardware
(ZD 22212) and verifies the attached-policy fix in the previous commit.

The pinned commit is wolfSSL/simulators PR #10 and becomes fetchable
from the upstream clone once that PR is merged.
2026-08-03 16:34:07 +01:00
Andrew Hutchings 356aa6338b SE050 CI: correct pinned simulator commit id
The previous pin abbreviated to the right commit but the full hash was
invalid, so the simulator checkout step could never resolve it. Pin the
full commit id of the merged simulator change.
2026-08-03 16:34:06 +01:00
Andrew Hutchings 6213bbaf58 SE050 CI: pin strict simulator for applet 7.2 ECDH contract
Bump SIMULATORS_REF to the simulator commit that supports HMACKey
WriteSymmKey and the applet 7.2 ECDH InObject contract, and run the
test container with SE050_SIM_STRICT_ECDH=1 so the simulator refuses
an ECDH derive whose Tag7 target object was not pre-created. This is
the failure mode seen on SE05x applet >= 7.2 hardware and reproduces
it in CI against the unfixed port.

The pinned simulator commit also consumes the WOLFSSL_EXTRA_CFLAGS
build ARG, so the only-key-id matrix leg now really builds with
-DWOLFSSL_SE050_ONLY_KEY_ID (previously the ARG was not consumed and
the leg silently built the default configuration), and it fixes the
simulator to derive the EC public key on private-only key pair import
so wc_ecc_use_key_id can read the public part back.

Raise the job timeout for cold image rebuilds until the weekend cron
refreshes the registry cache for the new ref.
2026-08-03 16:34:06 +01:00
Tobias Frauenschläger 91769d99f6 CI: raise the os-check linux timeout and allow seeding on demand
The ccache that keeps this workflow fast is written only by the weekday
seed job, which runs on a schedule against the default branch. Nothing
had seeded it since 2026-07-24, because the workflow itself was failing
to load for that whole stretch, and the Actions cache evicts entries
untouched for seven days. The first run after the fix therefore reported
"Cache not found for input keys" on all four shards.

That cold run measured ~102 thread-minutes per shard, or 24-27 minutes
of wall including checkout, deps and autogen, against a 30 minute
timeout. Three minutes of headroom on the slowest shard is not enough,
and a shard killed by the timeout presents as a test failure rather than
as a cold cache. Raise it to 40. The comment above it claimed ~68
thread-minutes and ~20 minutes of wall, which the measurement above
contradicts, so replace it with the measured figures. macOS and Windows
are left alone: they came in at 11.6 minutes against 45 and 2.0 against
6.

Add workflow_dispatch so the seed can be run on demand rather than
waiting up to a day for the next cron, which matters exactly in the
situation above, where every PR run stays cold until something refills
the cache.

Adding the trigger alone would not have been enough. The seed behaviour
hangs off `github.event_name == 'schedule'` in five places (CCACHE_RECACHE,
--build-only on linux and macOS, the cache save, and skipping the Windows
job), so a manual run would have gone through the full test path and
saved nothing. All five now treat a dispatch as a seed as well.

The condition is written against `github.event.inputs.seed` rather than
`inputs.seed`, because the `inputs` context is only documented as
available on workflow_dispatch and workflow_call, whereas `github.event`
always exists. That yields strings, so it is compared explicitly rather
than for truthiness, where the string 'false' would read as true. It
tests `!= 'false'` and not `== 'true'` so that a dispatch which sends no
input at all still seeds: a declared default is not reliably reflected
into `github.event.inputs`, and keying on the positive would have made
`gh workflow run` quietly skip the seeding it was invoked to do.

Comments are brought in line with all of this, including one that was
already wrong before the trigger existed: the macOS ccache step is
read-only purely on pull_request, so every non-PR run writes that cache,
where the note claimed only the seed did. The two platforms seed
differently in a second way as well - linux sets CCACHE_RECACHE and so
rebuilds from scratch, macOS never does and only accumulates deltas.
Neither behaviour is changed here, but both are now written down at the
top of the file rather than left to be rediscovered from a surprising
cache.
2026-08-03 17:05:29 +02:00
Tobias Frauenschläger 641c39dbf3 CI: catch workflows that GitHub silently fails to load
A workflow file GitHub cannot load does not fail loudly. Its runs end
within 0s with zero jobs, no logs, no annotations and no check runs, and
the workflow re-registers under its bare path instead of its `name:`
field. Among the few hundred checks on a PR that reads as unrelated
flake, so the coverage just disappears: os-check.yml was in this state on
master for ten days in July 2026 before anyone noticed, and no open PR
reported a problem the whole time.

Add two guards.

Pre-merge, check-workflows.py measures every `run:` step against
GitHub's 21000 character cap and fails the build past it, with a warning
from 18000 so a growing step is noticed while there is still runway.
Sizes come from the parsed YAML, which is what the Actions service
evaluates, so block-scalar indentation needs no guessing. It runs from
check-source-text.yml over every workflow and composite action rather
than only PR-changed files: the cap applies per file, the whole sweep
takes well under a second, and a file can be pushed over the line by a
change elsewhere in the PR. Note that this cap is enforced by the
service and not by the workflow schema, so neither a YAML validator nor
actionlint reports it.

Post-merge, workflow-health.yml runs check-workflow-health.py daily and
looks for the symptom rather than any particular cause, so a workflow
that stops loading for a reason nobody anticipated is still caught. Two
signals: an active workflow whose registered name equals its path, and a
completed run that failed with zero jobs (prefiltered on
created_at == updated_at, so only a handful need a jobs lookup). Against
the live repository the first signal flags os-check.yml and nothing else
across 107 workflows, and reports clean on wolfTPM and wolfMQTT. It
exits 1 on a finding and 2 when the check could not be carried out at
all, because a missing token and a broken workflow call for different
responses.

Findings go into a single reused issue rather than another red check
that would blend into the noise: the body is rewritten on each run, a
comment is posted only when the set of affected workflows changes, and
the issue closes itself once everything loads again.

Finding that issue reliably turned out to be the fiddly part, and the
approach here is the one that survived testing against a live
repository. The issue is identified by both a dedicated label and its
title, and looked up through the REST issues endpoint. Both halves of
that identity matter: the label alone is a normal repository label that
anyone can apply, and an adopted issue has its body overwritten and is
then closed, so matching on the label alone would destroy a mislabelled
issue. Searching by title instead is unusable, because search ignores
--state and returns closed issues, which had the monitor re-closing an
already closed issue on every clean run. `gh issue list` reads a GraphQL
replica that can lag. The REST endpoint lags too, by about 2.4s for a
newly created issue, so the lookup re-checks a few times before
concluding nothing is open - without that, consecutive runs each open a
duplicate, and a clean run right after an outage fails to close the
issue it just opened.

Verified against the commit that caused the outage: check-workflows.py
fails on acff4d62a (21813 characters) and passes on its parent
f5ace71dd, which it flags at 20662 - already inside the warning band,
338 characters short of breaking. The full issue lifecycle (open,
repeat with no comment, comment on change, close, stay closed, reopen a
fresh issue for a new outage) was exercised end to end against a live
repository.
2026-08-03 17:05:29 +02:00
Tobias Frauenschläger a6bd8c00e4 CI: move parallel-make-check config lists into .github/configs
GitHub caps a single `run:` step at 21000 characters. os-check.yml
embedded its 109-entry Linux config list as a heredoc inside that step,
and commit c00e7260b ("Add AES-GCM DEM, CryptoCb support, and devId
threading to ECIES") pushed it from 20662 to 21813 characters. Since
that merge on 2026-07-24 GitHub has refused to load the file at all:
every run of the workflow ends in failure within 0s with zero jobs, on
master and on every PR branch.

The failure is easy to miss. The run registers under the literal path
`.github/workflows/os-check.yml` rather than its `name:` field, its
check suite carries no check runs so there are no logs or annotations,
and because GitHub cannot read the file it cannot apply the `on:`
filters either - hence the master push runs for a workflow whose push
trigger is restricted to release/**. Meanwhile `gh pr checks` still
reports hundreds of green checks from the other workflows.

Move the config lists to checked-in JSON under .github/configs/;
parallel-make-check.py already accepts the JSON path as its positional
argument. Splitting the step in two would not have been enough: the
heredoc alone was 21387 characters once de-indented.

  os-check-linux.json   109 configs
  os-check-macos.json     7 configs
  pq-all.json            31 configs
  multi-arch.json        23 configs
  smoke-test.json        10 configs

The os-check lists are the fix; the other three are preventive - pq-all
and multi-arch were the next largest run steps at 14076 and 11011
characters. The largest remaining run step is now 6285 characters.

Each list was compared object-for-object against the version it
replaces, so this is a pure relocation with no coverage change.
2026-08-03 17:05:29 +02:00
David Garske 56e92ea0dc Merge pull request #10947 from night1rider/benchmark-msvc-arm64
benchmark: build the AArch64 cycle counter under MSVC/ARM64
2026-07-31 14:23:26 -07:00
Tobias Frauenschläger 1d15e1f27f Make OCSP stapling request ownership explicit
The OcspRequest carried a "void* ssl" back-pointer that the stapling
paths wrote just before handing the request to the OCSP layer. For the
request cached on the WOLFSSL_CTX that field is shared by every
connection using it, so concurrent handshakes raced on it. Drop the
field and pass the connection to CheckOcspRequest() and
CheckOcspResponse() as an argument instead, which is the only thing it
was ever read for.

Ownership of the cached request was equally implicit. Publication moves
out of CreateOcspRequest() into CreateOcspResponse(), and callers now
learn whether the CTX took ownership from a "ctxOwnsRequest" flag rather
than by comparing pointers against ssl->ctx->certOcspRequest, which was
read without the lock that guards it. The flag and the request are
handed back together on success and both left untouched on failure, so a
caller never decides ownership against a request it is not holding.

The cache is a field of the WOLFSSL_CTX, so serialize it with a lock
scoped to the CTX. SSL_CM(ssl) can resolve to a per-SSL cert manager
when WOLFSSL_LOCAL_X509_STORE is defined, which left two connections on
one CTX taking different locks for a check-then-set on the same pointer.
GetCtxOcspLock() keys off ssl->ctx->cm for both the reader and the
publisher, and a failure to take it is logged instead of silently
disabling the cache.

CheckOcspRequest() also loses its heap argument. It was only ever the
hint for the response buffer it hands back, which the caller frees
against the connection, so take it from the connection rather than from
a parameter every caller had to keep in step with its own free.

Smaller fixes in the same paths: zero the caller's response buffer
before the argument check can return, since SendCertificateStatus()
frees it without checking the return code; fold the ocsp_stapling NULL
check into the single early skip so the later uses need no guard;
gate the SetupOcspResp() free on success like the other two callers;
split the three differently owned requests in the
WOLFSSL_CSR2_OCSP_MULTI case into separate variables; and let that
case's allocation failures fall through to its shared cleanup instead of
returning, which leaked an already built leaf response.

Add test_ocsp_ctx_request_cache, which runs three handshakes over one
CTX pair and checks that the later ones reuse the cached request rather
than building another. The responder callback answers with a canned good
response, so stapling runs all the way through and the ownership
decision each connection makes is actually acted on: a connection that
freed the shared request shows up as a use after free on the next pass
and a double free at CTX teardown. The cached request is marked before
the last pass and the encoded request the callback sees is compared,
since a request rebuilt from the same certificate would otherwise be
identical byte for byte. The test is gated on !WOLFSSL_COPY_CERT:
OPENSSL_ALL implies it, and it gives every WOLFSSL its own certificate
copy, which takes the cache out of play. A new ocsp.yml job covers the
plain stapling build, an --enable-all build with the copy turned back
off, and an ASan build.

Also gate test_tls13_pha_status_request on KEEP_PEER_CERT. It checks the
received client certificate with wolfSSL_get_peer_certificate(), which is
only built when that macro is defined, so a post-handshake auth build with
stapling but without the OpenSSL compatibility layer failed to link
tests/unit.test.

Fixes F-7230 and F-7231.
2026-07-31 22:02:42 +02:00
Sean Parkinson c78f35725b Merge pull request #10343 from MarkAtwood/feat/sbom-bomsh
feat: SBOM generation and OmniBOR build provenance (CRA compliance)
2026-07-27 21:28:22 +10:00
night1rider 59c79512e3 benchmark: build and run the wolfCrypt benchmark in Windows ARM64 CI 2026-07-24 16:42:44 -06:00
JacobBarthelmeh acff4d62a1 Merge pull request #10883 from night1rider/Extend-ECIES
Add AES-GCM DEM, CryptoCb support, and devId threading to ECIES
2026-07-24 14:02:32 -06:00
Paul Adelsbach a192af8ff9 CI: set ccache path so settings are saved on initial seed 2026-07-24 11:56:31 -07:00
night1rider c00e7260be Add AES-GCM DEM, CryptoCb support, and devId threading to ECIES
Add AES-GCM (128/256) as an ECIES DEM next to the AES-CBC/CTR+HMAC modes. Only the encryption key comes from the KDF; the mac salt is bound as GCM AAD and the 16-byte tag replaces the HMAC. The GCM DEM honors all three IV build modes, and default fixed-nonce GCM is gated behind the new WOLFSSL_ECIES_STATIC_GCM_NONCE opt-in. Adds ECIES CryptoCb encrypt/decrypt, the WOLF_CRYPTO_CB ctx getters, devId/heap threading into the DEM primitives, and test/benchmark/CI coverage.
2026-07-24 10:19:40 -06:00
Mark Atwood be9963f392 sbom: drop liboqs dependency support (removed from wolfSSL)
wolfSSL removed liboqs: Falcon is now provided natively by wolfCrypt, and
--with-liboqs is a deprecated no-op (configure.ac). A build therefore no
longer links liboqs, so recording it as an SBOM dependency is dead code and
the SBOM integration CI (which asserted a liboqs dep package) failed.

Remove the liboqs dependency throughout:
- scripts/gen-sbom: drop DEP_META['liboqs'] and the --dep-liboqs flag.
- Makefile.am / configure.ac: drop --dep-liboqs "$(ENABLED_LIBOQS)" and the
  now-unused AC_SUBST([ENABLED_LIBOQS]).
- .github/workflows/sbom.yml: drop the liboqs install / --with-liboqs steps
  and the liboqs dep assertion; keep the native-Falcon build so the
  HAVE_FALCON build-property capture is still exercised.
- scripts/test_gen_sbom.py: drop the liboqs-specific tests, guard against
  the key reappearing, and use openssl as the example dep elsewhere.
- doc/SBOM.md: drop the --dep-liboqs / liboqs dependency references.
2026-07-23 22:32:50 -07:00
Sameeh Jubran d08282ff9a sbom: use docdir, portable version parse, and widen CI filter
Use Automake's $(docdir) for sbomdir so a --docdir override is honoured,
match tab/space in the wolfSSL version parse ([[:space:]]), document the
GNU-make requirement and the intentional install/uninstall-sbom
asymmetry, and widen the SBOM workflow pull_request filter to '**' so PRs
onto release/** base branches also run.

Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
2026-07-23 21:51:26 -07:00
Sameeh Jubran 5ab0ad9fab sbom: address advisory/SBOM review findings
- gen-advisory: honour explicit per-version status when defaultStatus is
  "affected", so unaffected/fixed releases are no longer marked vulnerable
- gen-advisory: fail loudly when a CVE record has no non-empty English
  description (CSAF/CycloneDX note text is required, minLength 1)
- gen-advisory: note that --cve-id fetches from the CVE Services API
- bomsh_verify: scope the object-store shape check to sha1, matching the
  sha1 gitoid hashing (drop the unreachable sha256-length branch)
- Makefile.am: fail `make bomsh` early when python3/pyspdxtools are absent;
  quote $(ENABLED_LIBZ)/$(ENABLED_LIBOQS); consolidate clean-local so the
  omnibor/ and advisories/out/ build dirs are removed on clean
- tests: cover the defaultStatus fix, the _bucket_for unknown-state
  hard-fail, and a csaf_validate.mjs runner self-test wired into CI

Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
2026-07-23 21:51:26 -07:00
Sameeh Jubran 4ec80d309a feat: SBOM generation and OmniBOR build provenance (CRA compliance)
Add tooling to produce Software Bills of Materials and build provenance
for wolfSSL, supporting EU Cyber Resilience Act (CRA) obligations.

SBOM generation:
- New `make sbom` target producing SPDX 2.3 output with NTIA minimum
  elements, urn:uuid document namespaces, and SPDX LicenseRef compliance.
- Reproducible library discovery across autotools and CMake builds, with
  liboqs recorded as a linked artefact.
- Standalone `scripts/gen-sbom` for embedded / RTOS / custom-builder
  flows that do not use the main build system, plus --srcs-file,
  --no-artifact-hash, and hash-source options.

Build provenance (OmniBOR / bomsh):
- End-to-end bomsh tracing of the built binaries with ArtifactID
  insertion, snapshotting the traced library before libtool relink and
  hashing the bomsh-traced binary.
- `scripts/bomsh_verify.py` to validate provenance against the traced
  gitoid.

Security advisories:
- `scripts/gen-advisory` generating CSAF 2.0 and CycloneDX VEX, with a
  `make` target, VEX overlay schema/example, and CWE name data.

Docs, tests, and CI:
- doc/SBOM.md and doc/CRA.md, plus README/INSTALL updates.
- Unit and regression tests for gen-sbom and gen-advisory.
- New sbom.yml and advisory.yml workflows: SPDX validation via
  pyspdxtools, CSAF validation, bomsh provenance verification, SBOM
  artifact archiving, macOS coverage, and actions pinned to SHAs.

Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
2026-07-23 21:51:26 -07:00
Sean Parkinson e23054ca9e Merge pull request #10931 from julek-wolfssl/socat-ci-hang-fix
socat CI: prevent rare shard hang in inverted OPENSSL tests
2026-07-24 10:45:20 +10:00
Sean Parkinson 00c9405c24 Merge pull request #10969 from Frauschi/ci_flakyness_fixes
CI: reduce flakiness in the libssh2, trackmemory, and socat jobs
2026-07-24 10:41:54 +10:00
Sean Parkinson f7571db708 Merge pull request #10896 from julek-wolfssl/julek-dev/openvpn-set0-crls
X509_STORE_CTX_set0_crls: implement for OpenVPN
2026-07-24 10:18:40 +10:00
Sean Parkinson e6c3bb4403 Merge pull request #10827 from danielinux/falcon-native
Falcon: native implementation replacing liboqs, with crypto callbacks and ARM acceleration. Deprecate liboqs support.
2026-07-23 21:17:10 +10:00
Brett Nicholas e6d86b4bbb Merge pull request #10832 from padelsbach/curve25519-cryptocb-only
Add crypto callback only mode for curve25519
2026-07-22 17:35:55 -06:00
David Garske 983e1090d7 Merge pull request #10922 from aidangarske/fenrir-asn-strict
Enforce RFC 5280 extension MUSTs under WOLFSSL_NO_ASN_STRICT and validate DTLS 1.3 legacy_session_id echo
2026-07-22 14:12:33 -07:00