Commit Graph

30718 Commits

Author SHA1 Message Date
David Garske f44b16cfa3 Merge pull request #10759 from Frauschi/pkcs7_mldsa
PKCS#7: add ML-DSA support
2026-07-09 10:32:26 -07:00
David Garske f2fc9b6603 Merge pull request #10822 from mattia-moffa/20260629-ticket-hint-window-check
Fix session ticket key rotation when hint exceeds key lifetime
2026-07-09 10:27:57 -07:00
Daniel Pouzzner 40f1582dc4 Merge pull request #10824 from yosuke-wolfssl/fix/f_6555
Lock globalRNGMutex around all shared globalRNG access
2026-07-09 12:14:49 -05:00
David Garske 0315ea3a60 Merge pull request #10826 from yosuke-wolfssl/fix/f_6539
Preserve DTLS association on invalid record headers during handshake
2026-07-09 10:11:39 -07:00
David Garske 2dfb38f92c Merge pull request #10845 from danielinux/mcdc-test-coverage
Infrastructure for Mc/Dc test coverage + AES coverage campaign
2026-07-09 09:40:43 -07:00
Tobias Frauenschläger bc3288204e PKCS#7: add ML-DSA (FIPS 204) SignedData support
Add ML-DSA signing and verification for CMS/PKCS#7 SignedData, following
RFC 9882. ML-DSA is used in CMS "pure" mode: the signature is computed
over the complete message (the DER SET OF signed attributes, or the
eContent when none are present) with an empty context string and absent
signatureAlgorithm parameters, rather than over a pre-computed DigestInfo
as with RSA/ECDSA.

wolfcrypt/src/pkcs7.c:
- New ML-DSA helpers: wc_PKCS7_MlDsaLevelFromOID, wc_PKCS7_BuildPureSigMessage,
  wc_PKCS7_MlDsaSign and wc_PKCS7_MlDsaVerify, wired into the per-algorithm
  switch sites (GetSignSize, SignedDataGetEncAlgoId, SetPublicKeyOID,
  CheckPublicKeyDer) and the sign/verify dispatchers. Only the final FIPS 204
  ML-DSA OIDs are accepted; pre-standard draft Dilithium OIDs are not.
- GetSignSize derives the ML-DSA signature length from the parameter set.
- InitWithCert copies the signer public key into the RSA-sized publicKey buffer
  only for RSA/ECC certs (the raw-sign callback consumers); large PQC keys such
  as ML-DSA would overflow it and are never read back, so publicKeySz stays 0.
- wc_MlDsaKey is always heap allocated (it embeds multi-KB key buffers); the
  accompanying DecodedCert uses the WC_DECLARE_VAR/WC_ALLOC_VAR_EX macros for
  stack-vs-heap handling under WOLFSSL_SMALL_STACK.
- wc_PKCS7_SignedDataBuildSignature skips building the DigestInfo for ML-DSA,
  which signs the full message in pure mode and never consumes it.
- wc_PKCS7_MlDsaSign wraps the ML-DSA private-key decode in
  PRIVATE_KEY_UNLOCK/PRIVATE_KEY_LOCK. Unlike RSA/ECC, the FIPS module gates
  wc_MlDsaKey_PrivateKeyDecode behind the private-key read lock, so signing
  would otherwise fail with FIPS_PRIVATE_KEY_LOCKED_E under --enable-fips. The
  macros are no-ops in non-FIPS builds.

wolfssl/wolfcrypt/pkcs7.h:
- Document that the fixed-size signer public key buffer (publicKey/publicKeySz)
  holds only RSA/ECC keys; it stays RSA-sized.

wolfcrypt/src/hash.c:
- Map the SHAKE128/SHAKE256 OIDs to their hash types in wc_OidGetHash().

certs/mldsa:
- Add expanded-only PKCS#8 DER private keys (mldsa44/65/87-key.der) matching
  the self-signed ML-DSA certificates, with README and include.am updates.
  The expanded-only shape (no seed) decodes via wc_MlDsaKey_ImportPrivRaw
  without keygen-from-seed or the ASN template, so pkcs7signed_mldsa_test also
  passes in WOLFSSL_MLDSA_NO_MAKE_KEY and non-WOLFSSL_ASN_TEMPLATE builds.

certs/renewcerts.sh:
- Generate the mldsa<N>-key.der files from the matching mldsa<N>-key.pem in the
  expanded-only shape (openssl pkey -provparam ml-dsa.output_formats=priv), so
  a regeneration keeps the DER key in step with the cert. The OpenSSL detection
  probe now requires both ML-DSA keygen and that conversion across all three
  levels, so the block runs fully (matched cert+key) or is skipped entirely
  rather than aborting mid-way.

wolfcrypt/test/test.c:
- Add pkcs7signed_mldsa_test(): round-trip encode/verify of SignedData across
  ML-DSA-44/65/87, with and without signed attributes, including a check that
  the digest algorithm parameters are encoded as expected. The message-digest
  OID is selected from the enabled hash set (SHA-512, else SHA-256, else SHA-1)
  so the test builds when SHA-512 is disabled. A negative case confirms ML-DSA
  rejects a caller-supplied pre-computed content hash with BAD_FUNC_ARG.
2026-07-09 18:09:03 +02:00
David Garske 9e72e8d718 Merge pull request #10853 from night1rider/cross-library-testing
Add cross-library compile-testing for wolfSSL products
2026-07-09 09:08:35 -07:00
David Garske f430d5b472 Merge pull request #10251 from MarkAtwood/fix/aes-eax-empty-plaintext
fix: AES-EAX allow empty plaintext
2026-07-09 08:24:55 -07:00
Daniel Pouzzner 5caa3565b8 Merge pull request #10858 from anhu/89compl
C89 compliance items
2026-07-09 10:14:16 -05:00
Daniele Lacamera c1500f8622 tests: import the falcon benchmark key instead of OQS keygen
test_wc_falcon_sign_verify aborted (SIGABRT) when run as part of the
full unit suite in liboqs configs. The direct OQS_SIG_keypair() call
draws from liboqs' randombytes callback, which wolfSSL points at its
default liboqs RNG; wolfSSL_liboqsClose() (run by wolfCrypt_Cleanup)
frees that RNG without resetting liboqs_init, so after any earlier
Init/Cleanup cycle in the suite the re-Init never re-creates it and
the callback abort()s on the freed RNG. Running the test alone passed,
which is why this only surfaced in make check.

Drop the direct liboqs usage entirely: decode the embedded
bench_falcon_level1_key (certs_test.h) with wc_Falcon_PrivateKeyDecode
and exercise sign/verify through the wolfSSL API only, which hands the
test's own RNG to liboqs and does not depend on the default-RNG
lifecycle. Also removes the oqs/oqs.h include and the OQS_STATUS
handling; with no liboqs symbols left in the body, only the guard
still references HAVE_LIBOQS, easing the planned liboqs removal.

Validated in --with-liboqs --enable-experimental --enable-falcon (the
failing PRB-liboqs config): the full unit suite now completes with the
test passing at the position that aborted; also passes under
opensslall+falcon and compiles clean with -Werror=bad-function-cast.
2026-07-09 10:55:20 +02:00
Daniele Lacamera 7487366b0c tests: keep OQS_SIG_keypair() out of ExpectIntEQ
ExpectIntEQ casts both arguments to int (tests/unit.h ExpectInt), and
casting a function call that returns the liboqs OQS_STATUS enum trips
-Werror=bad-function-cast, which is part of the test warning set. Store
the status in a local first; casting a variable does not trigger the
warning. Broke falcon-enabled configs once the HAVE_PQC guard fix made
this test compile.

Verified: the TU reproduces the exact CI error before this change and
compiles clean after, and test_wc_falcon_sign_verify still passes in a
--disable-md5 --enable-opensslextra --enable-falcon --with-liboqs
build.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 53cad55295 tests: address review findings (dead HAVE_PQC guard, guard/style cleanups)
Address the PR 10845 review findings:

* test_signature.c: the Falcon sign/verify test was guarded on
  HAVE_PQC, which no build system ever defines (--enable-falcon sets
  HAVE_FALCON only), so the test always compiled out to skipped. Gate
  it on HAVE_FALCON && HAVE_LIBOQS like the library does, and drop the
  now-unreferenced HAVE_PQC entry from .wolfssl_known_macro_extras.
  Verified with --enable-opensslall --enable-experimental
  --enable-falcon --with-liboqs: the test now executes and passes.

* api.c: revert the (OPENSSL_EXTRA || OPENSSL_ALL) widening of the
  inner guards of test_wolfSSL_TXT_DB and the new
  test_wolfSSL_NCONF_negative_paths. Both functions live inside the
  enclosing OPENSSL_ALL block and their TEST_DECLs are OPENSSL_ALL-
  gated (and TXT_DB/NCONF themselves are OPENSSL_ALL-only APIs), so
  the widening could never take effect. Inner guards now match their
  siblings (filesystem/BIO deps only).

* test_pkcs12.c: wrap the expected BAD_FUNC_ARG values of the new
  parse guardrail asserts in WC_NO_ERR_TRACE() for consistency with
  the rest of the PR's negative-path assertions.

All six affected tests pass in an opensslall+falcon+liboqs build:
falcon_sign_verify, TXT_DB, NCONF, NCONF_negative_paths,
PKCS12_parse_guardrails, PKCS12_create_guardrails.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 2159b15a66 tests: keep test_wolfSSL_X509V3_EXT OPENSSL_ALL-only
PRB-generic-config-parser failed in test_wolfSSL_X509V3_EXT under an
OPENSSL_EXTRA (non-OPENSSL_ALL) config:

    test_ossl_x509_ext.c:1519  ExpectIntEQ(actual, 0)   /* got -5 */

The function walks the OCSP root CA's extensions by hardcoded index (i=0 basic
constraints, i=1 subject key id, i=2 authority key id, ...) and asserts fixed
values. The strcmp result -5 is exactly '2'-'7': the i=1 i2s produced the
authority-key-id value ("27:8E:...") instead of the subject-key-id
("73:B0:..."), i.e. the stored-extension order differs in OPENSSL_EXTRA-only
builds, so the index assumption breaks.

On master this test is gated on OPENSSL_ALL; the MC/DC campaign commit
(bc92090b3) over-widened it to (OPENSSL_EXTRA || OPENSSL_ALL) when splitting
api.c. Revert just this function's guard to OPENSSL_ALL. The by-NID
test_wolfSSL_X509V3_EXT_aia above keeps its OPENSSL_EXTRA widening (that is the
one the AIA leak fix needed, and it looks extensions up by NID so it is
order-independent).

Verified: skipped under --enable-opensslextra (no longer runs/fails there),
runs and passes under --enable-all.
2026-07-09 10:02:22 +02:00
Daniele Lacamera a79c7044da tests: make RsaDecisionCoverage padding-mismatch check deterministic
test_wc_RsaDecisionCoverage decrypted an OAEP-SHA256 cipher text as PKCS#1 v1.5
and asserted it must return < 0. That is flaky: v1.5 decrypt-unpadding of the
random OAEP plaintext spuriously "succeeds" whenever byte[1] lands on 0x02 with
a valid 0x00 separator after >=8 nonzero bytes -- a few-percent-per-run coin
flip, and a fresh random key is generated each run. It surfaced as intermittent
make-check failures (e.g. "result: 36 >= 0", "140 >= 0") on PR CI.

Replace it with a deterministic padding-mismatch: decrypt the (no-label) OAEP
cipher text as OAEP with a non-empty label. OAEP authenticates the label via
lHash, so a label mismatch fails the integrity check every time, still
exercising the padding-mismatch decision branch in rsa.c.

Verified locally by looping test_wc_RsaDecisionCoverage 150x in an
OAEP+SHA256 build: old assertion failed 2/150, new assertion 0/150.
2026-07-09 10:02:22 +02:00
Daniele Lacamera a178b6f50d tests: also exclude old FIPS from AesFeatureCoverage CCM block
PRB-fips-repo-and-harness-test-v3-part1 (FIPS v2, --enable-fips=v2
--enable-opensslextra/--enable-opensslall) failed in test_wc_AesFeatureCoverage.

Reproduced against a real FIPS v2 build (linuxv2 = WCv4-stable module, in-core
integrity hash regenerated)
2026-07-09 10:02:22 +02:00
Daniele Lacamera e14a3aafc9 tests: skip AesFeatureCoverage GCM/CCM under the self-test module
The PRB-CAVP-selftest-v2 leg (--enable-selftest=v2, frozen wolfCrypt 4.1.0
crypto) failed in test_wc_AesFeatureCoverage.

Reproduced against that exact build; the failing assertion is:

    tests/api/test_aes.c:8324
      ExpectIntEQ(wc_AesCcmEncrypt(&aes, NULL, NULL, 0, ccmNonce13,
        sizeof(ccmNonce13), ccmTag, 16, ccmAad, sizeof(ccmAad)), 0)   /* got -173 */

That is the AAD-only (empty-plaintext) CCM case. Current wolfCrypt accepts
NULL in/out when inSz==0; the frozen v4.1.0 wc_AesCcmEncrypt rejects in/out==NULL
unconditionally and returns BAD_FUNC_ARG. Same class as the RsaDecisionCoverage
self-test fix: the frozen module's argument-validation contract predates the
modern behaviour this test asserts.

This function's value is MC/DC of the open wolfcrypt/src/aes.c feature paths,
which is not the aes.c compiled under --enable-selftest, so under self-test it
measures nothing and only risks such divergences. The key-wrap block in this
same function already excludes HAVE_SELFTEST (and the AES *ArgMcdc tests do
too); extend that to the GCM/GMAC and CCM blocks. HAVE_FIPS is intentionally
left running -- that (newer) module honours these paths and never flagged this
test; the open MC/DC campaign builds are unaffected.

Verified: skipped cleanly under --enable-selftest=v2 (test index 278, matching
CI); open build still runs and passes it.
2026-07-09 10:02:22 +02:00
Daniele Lacamera b9925e72f7 tests: skip RsaDecisionCoverage under the self-test module
The PRB-CAVP-selftest-v2 leg (./configure --enable-selftest=v2, which overlays
frozen wolfCrypt 4.1.0 crypto) failed in test_wc_RsaDecisionCoverage.

Reproduced against that exact build; the failing assertion is:

    tests/api/test_rsa.c:1474
      ExpectIntEQ(wc_RsaSetRNG(&key, NULL), BAD_FUNC_ARG)   /* got 0 */

So the assertion is correct for current wolfCrypt but not part of the frozen
self-test module's contract. This test's whole purpose is MC/DC of the *open*
wolfcrypt/src/rsa.c decision branches, which is not even the rsa.c compiled
under --enable-selftest, so under self-test it measures nothing and only risks
divergent error codes like this one. The sibling key-gen/decision tests in this
file (test_wc_CheckProbablePrime, the RsaKeyGeneration group) exclude
HAVE_SELFTEST for the same reason; do so here too.

Guard the whole function rather than the single assertion: none of it counts
toward the (open-build) MC/DC campaign under self-test, and a whole-function
guard is robust against any other frozen-vs-current divergence in the same
body. HAVE_FIPS is intentionally left running -- that (newer) module honours
these decisions (and excludes the WC_RSA_BLINDING wc_RsaSetRNG block anyway),
and the open MC/DC campaign builds are unaffected.

Verified: with the guard, the test is cleanly skipped under --enable-selftest=v2
(test index 365, matching CI); the open build still runs and passes it.
2026-07-09 10:02:22 +02:00
Daniele Lacamera b680985328 tests: skip whole AesCcmArgMcdc under FIPS/self-test (fixes v5 segfault)
A second apple-M1 FIPS segfault (--enable-fips=v5): test_wc_AesCcmArgMcdc probes
the pure-C CCM inSz-overflow decision by calling wc_AesCcmEncrypt/Decrypt with a
1-byte dummy in/out buffer and a claimed length of 65536, relying on the pure-C
path returning AES_CCM_OVERFLOW_E *before* touching the buffer. The FIPS module's
CCM does not reject early, so it writes 65536 bytes into the 1-byte buffer and
segfaults. (The rounds=0 corruption in the same test was already skipped via
WC_TEST_AES_ROUNDS_OFFLOADED, but the two overflow blocks were not.)

Every decision this test targets lives in pure-C aes.c CCM code that is not
compiled in FIPS/self-test builds, so guard the whole function on
!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) rather than patching each unsafe
block. The other *ArgMcdc tests only corrupt rounds (macro-skipped) and have no
oversized-buffer calls, so they need no further change.

Verified: --enable-all still builds and test_wc_AesCcmArgMcdc passes; the 65536
overflow calls are present non-FIPS and absent when HAVE_FIPS is defined.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 479659fa96 tests: guard Gmac/AesGcmSetExtIV tests for the self-test module
The CAVP self-test build (--enable-selftest) failed to compile test_aes.c:
wc_AesGcmSetExtIV (test_wc_AesGcmDecisionCoverage) and wc_Gmac/wc_GmacVerify
(test_wc_AesGmacArgMcdc) are declared only under !WC_NO_RNG in mainline and are
absent from the frozen self-test module's headers (they are present under FIPS -
the apple-M1 FIPS build compiled and passed both), so -Werror=implicit-function-
declaration aborted the build.

Gate those specific calls (and the now-otherwise-unused iv buffer) on
!defined(WC_NO_RNG) && !defined(HAVE_SELFTEST). wc_GmacSetKey stays available, so
its coverage is retained under self-test. FIPS builds are unaffected.

Verified: --enable-all still builds and both tests pass; preprocessing test_aes.c
with -DHAVE_SELFTEST leaves no wc_AesGcmSetExtIV/wc_Gmac/wc_GmacVerify calls in
any always-compiled function (remaining ones are in the WOLFSSL_AESGCM_STREAM
stream test, which the self-test config disables).
2026-07-09 10:02:22 +02:00
Daniele Lacamera 4755bb21c5 tests: skip AES rounds-corruption under FIPS/self-test (fixes CCM segfault)
test_wc_AesCcmArgMcdc segfaulted on the FIPS builds (apple-M1 config A, CAVP
self-test), exit 139. The AES *ArgMcdc tests reach the post-key-setup "ret != 0"
checkpoints by corrupting aes->rounds = 0 and calling wc_AesCcmEncrypt/Decrypt.
That relies on the pure-C AesEncryptBlocks_C guard (if r==0 return KEYUSAGE_E) to
turn the corruption into a clean error return. Under the FIPS / self-test module
the AES implementation has no such guard, so rounds=0 runs AES with a zero-round
key schedule and dereferences past the key schedule -> SIGSEGV.

The corruption is already gated by WC_TEST_AES_ROUNDS_OFFLOADED (crypto-cb / asm
offload). FIPS and self-test are the same situation - the pure-C guard is not in
the compiled path - so add HAVE_FIPS / HAVE_SELFTEST to that macro. The three
function-level FIPS-guarded tests (SetKey/Modes/Cmac ArgMcdc) were already
skipped; test_wc_AesCcmArgMcdc is not, and its non-corruption CCM coverage now
still runs under FIPS while only the rounds-corruption blocks are skipped.

Verified: --enable-all (non-FIPS) still runs and passes all rounds-corruption
tests; the corruption blocks compile out only under FIPS/self-test.
2026-07-09 10:02:22 +02:00
Daniele Lacamera e63555a924 tests/unit-mcdc: white-box the AES-NI internal pointer guards
Adds a wb_aesni() supplement covering the AES-NI-only file-static helpers that
the aesni build variant instruments: AES_set_{en,de}crypt_key_AESNI's
!userKey/!aes guard and the AesGcm{AadUpdate,EncryptUpdate,DecryptUpdate}_aesni
NULL/size guards, using the same "call the static with both halves of the pair"
idiom as the classic GHASH/GHASH_UPDATE supplements.

Closes 6 of the 8 AES-NI null-guard residuals (aesni_wb 14->20, union
384->390/397). The remaining pair is AES_set_decrypt_key_AESNI's !userKey/!aes:
its valid-argument (false) half needs an AES-NI decrypt-key setup that the
current aesni test set does not exercise; left as a documented residual.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 27b1a40bdd tests: fix AUTHORITY_INFO_ACCESS leak under OPENSSL_EXTRA-only builds
This branch widened test_wolfSSL_X509V3_EXT's guard from OPENSSL_ALL to
(OPENSSL_EXTRA || OPENSSL_ALL). The Authority Info Access sub-test frees its
aia stack with wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL), relying on the
stack's type-based element free - but wolfssl_sk_get_free_func() only wires up
wolfSSL_ACCESS_DESCRIPTION_free for STACK_TYPE_ACCESS_DESCRIPTION under
OPENSSL_ALL. In an OPENSSL_EXTRA-only build (now reachable) the NULL callback
frees the stack nodes but leaks each ACCESS_DESCRIPTION (struct + method OBJ +
location GENERAL_NAME + URI string): 370 bytes, caught by ASAN/valgrind.

Pass wolfSSL_ACCESS_DESCRIPTION_free explicitly (available under OPENSSL_EXTRA);
correct under OPENSSL_ALL too. Verified leak-free under ASAN with the failing
config (--enable-opensslextra --enable-crl ... --disable-fastmath).
2026-07-09 10:02:22 +02:00
Daniele Lacamera e3a6d4a0e6 build: register HAVE_PQC in known-macro extras
The branch's Falcon signature test (tests/api/test_signature.c) guards on
HAVE_PQC, which current wolfSSL no longer defines anywhere, so check-source-text
flags it as unknown. Register it alongside the other PQC/MLKEM extras.
2026-07-09 10:02:22 +02:00
Daniele Lacamera ba2e52ae02 tests: zero-init ccmTag to satisfy clang-tidy
clang-tidy (all-c89, async-quic, intelasm) flagged `ccmTag[0] ^= 0x01` as a use
of an uninitialized value: the analyzer does not model wc_AesCcmEncrypt writing
the tag buffer. Zero-initialize ccmTag; the subsequent encrypt still overwrites
it before the tamper, so behavior is unchanged.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 9d0c6cb89c tests: guard AesModes/AesGcm ArgMcdc tests for the older FIPS API
Same FIPS-header mismatch as the earlier AesSetKey/Cmac guard: the FIPS v2/v5
modules lack AES_IV_FIXED_SZ and GCM_NONCE_MIN/MID/MAX_SZ and declare
wc_AesEncryptDirect as void, so test_wc_AesModesArgMcdc and test_wc_AesGcmArgMcdc
fail to compile there (fatal under -Werror). Gate both on the modern API with
the same idiom used by the other AES-DIRECT tests.
2026-07-09 10:02:22 +02:00
Daniele Lacamera a0dbe59597 tests: guard AesSetKey/Cmac ArgMcdc tests for the older FIPS API
The apple-m1 "known config A" (FIPS) build broke: the FIPS module's frozen
headers declare wc_AesEncryptDirect/wc_AesDecryptDirect as void (not int) and
omit wc_CmacFree, so the new tests' ExpectIntEQ(wc_AesEncryptDirect(...)) and
wc_CmacFree() usages don't compile.

Gate test_wc_AesSetKeyArgMcdc and test_wc_AesCmacArgMcdc on the modern API with
the same idiom test_wc_AesEncryptDecryptDirect_WithKey already uses:
  (!defined(HAVE_FIPS) || !defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION > 6))
  && !defined(HAVE_SELFTEST)
The campaign runs non-FIPS, so no coverage is lost where it is measured.

Verified: --enable-all still builds and both tests run.
2026-07-09 10:02:22 +02:00
Daniele Lacamera a9299732d9 tests: fix AesKeyExport lifecycle-tag leak and server-only session-cache test
The last two red PR jobs, both in the branch's new tests:

- intelasm (ASAN): test_wc_AesKeyExportArgMcdc calls wc_AesInit_Id() and
  wc_AesInit_Label() which succeed (allocating the WC_DEBUG_CIPHER_LIFECYCLE
  tag) but were never freed -> 8-byte LeakSanitizer leak. Add wc_AesFree()
  to both blocks.
- no-client-no-client-auth (minimal server-only build):
  test_wolfSSL_session_cache_api_direct's wolfSSL_new() returned NULL because
  a certless server CTX has no usable cipher suite. Load the test server
  cert/key (file, with a USE_CERT_BUFFERS_2048 fallback) before wolfSSL_new()
  in the server-only path; the client path is cert-free as before.

Verified: --enable-all + ASAN run of the aes group is leak-free, and
CPPFLAGS="-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH" now passes.
2026-07-09 10:02:22 +02:00
Daniele Lacamera ba3fd1203b tests: skip AES rounds-corruption checks under WOLFSSL_ARMASM
The aes.rounds-validity check that returns KEYUSAGE_E lives only in the
pure-C block encrypt (AesEncryptBlocks_C). On ARMv8 with crypto extensions,
--enable-all auto-enables WOLFSSL_ARMASM, whose asm wc_AesEncrypt bypasses
that check, so corrupting aes.rounds no longer fails the op (returns 0).
This broke the SetKey/CTR/CFB/OFB/CCM/CMAC rounds-corruption assertions on
the arm64 CI runners.

Extend WC_TEST_AES_ROUNDS_OFFLOADED to also cover WOLFSSL_ARMASM (joining
WOLF_CRYPTO_CB_FIND / WOLF_CRYPTO_CB_ONLY_AES). MC/DC of that decision is
still obtained from the pure-C configs in the variant union. x86 (incl.
AES-NI, which does validate rounds) is unaffected.
2026-07-09 10:02:22 +02:00
Daniele Lacamera bd8730543c tests: fix X509V3_EXT leak, C++ build, and no-client link
Three more failures in the branch's added tests, found via the ASAN, C++
and no-client CI configs:

- test_wolfSSL_X509V3_EXT leaked 2296 bytes: the added
  X509_get_ext_d2i(x509, NID, &critical, NULL) calls (used to exercise the
  critical-flag output) discarded their allocated result. Free each per its
  actual return type: BASIC_CONSTRAINTS, ASN1_STRING (key usage),
  AUTHORITY_KEYID, AUTHORITY_INFO_ACCESS, and - for subject_key_identifier -
  a STACK_OF(ASN1_OBJECT) (wolfSSL_X509_get_ext_d2i wraps a lone obj in a
  stack). This was the real cause of the sanitize-asan / intelasm / krb-asan
  job failures (the read_write_ex/ECH/dtls13 asserts printed there are
  retry-masked and fail identically on master).
- C++ build (all-pq-cxx): void* from X509_get_ext_d2i does not implicitly
  convert; add explicit WOLFSSL_X509_EXTENSION* casts.
- no-client link (all-no-client): wolfSSL[_CTX]_UseOCSPStapling[V2] (CSR/CSR2)
  are client-side APIs; guard those blocks with !NO_WOLFSSL_CLIENT.

Verified: full --enable-all + ASAN run is leak-free and passes; --enable-all
-DNO_WOLFSSL_CLIENT builds and links.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 9165eb0e4d tests: guard AES tests for cryptocb-only and no-AES-192/256 configs
Three more config-matrix failures in the AES coverage tests:

- Rounds-corruption checks (aes.rounds/cmac.aes.rounds = 0/17 -> expect
  KEYUSAGE_E) also break under WOLF_CRYPTO_CB_ONLY_AES, which strips the
  software AES so the op is serviced by the callback and ignores the
  corrupted struct (same net effect as WOLF_CRYPTO_CB_FIND). Introduce
  WC_TEST_AES_ROUNDS_OFFLOADED = (WOLF_CRYPTO_CB_FIND || _ONLY_AES), replace
  the previous WOLF_CRYPTO_CB_FIND-only guards with it, and extend it to the
  wc_AesEncryptDirect/wc_AesDecryptDirect checks in AesSetKeyArgMcdc (which
  the ONLY_AES path also offloads).
- test_wc_AesFeatureCoverage's GCM-streaming block uses a hardcoded 256-bit
  key; guard it with WOLFSSL_AES_256 (failed under -DNO_AES_256).
- Its AES-KeyWrap block uses a 192-bit key; guard with WOLFSSL_AES_192
  (failed under -DNO_AES_192).

Verified: --enable-swdev --enable-cryptocb ... -DWOLF_CRYPTO_CB_ONLY_AES and
--enable-all -DNO_AES_192 -DNO_AES_256 now both build and pass; a normal
--enable-all build still runs the rounds checks.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 4880b27d55 tests: skip AES rounds-corruption checks under WOLF_CRYPTO_CB_FIND
Several AES ArgMcdc tests corrupt aes.rounds (or cmac.aes.rounds) and
expect the subsequent op to fail with KEYUSAGE_E from the in-process
software AES path. Under WOLF_CRYPTO_CB_FIND (e.g. --enable-swdev), the
"devId != INVALID_DEVID" guard is removed, so CTR/CCM/CMAC ops are
offloaded to the registered crypto callback even for INVALID_DEVID; the
callback re-derives the key and ignores the corrupted struct, returning 0
instead of KEYUSAGE_E and failing the assertion.

Guard those internal-failure checks with #ifndef WOLF_CRYPTO_CB_FIND
(wc_AesCtrEncrypt, wc_AesCfb/OfbEncrypt/Decrypt, wc_AesCcmEncrypt/Decrypt,
wc_CmacUpdate); the raw-block wc_AesEncryptDirect path in SetKey does not
route through cryptocb, so it stays. (void)-cast the locals only used by
the guarded checks to keep -Werror clean. MC/DC is unioned across configs,
so no union coverage is lost.

Verified: --enable-swdev ... (WOLF_CRYPTO_CB_FIND) now passes, and a
non-CB_FIND build with all these modes still runs and passes the checks.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 09e4888e43 tests: replace non-ASCII chars in MC/DC test comments/docs
The check-source-text CI job flags non-ASCII (8-bit) bytes in source. The
new MC/DC tests and README used UTF-8 punctuation in comments/prose
(em-dash, ellipsis, left-right arrow). Replace with ASCII equivalents
(-, ..., <->). Verified: ./.github/scripts/check-source-text.sh on the
changed files reports clean.
2026-07-09 10:02:22 +02:00
Daniele Lacamera 8324b67fae tests: fix -Werror/config-gating failures in MC/DC coverage tests
The new MC/DC coverage tests broke many CI configs under -Werror (which is
auto-enabled for in-git-tree builds). Fixes, each verified with a real
-Werror build of the relevant config:

- test_aes.c: wrap the whole test_wc_AesSivArgMcdc definition in
  WOLFSSL_AES_SIV && WOLFSSL_AES_128 (was body-only guarded while its
  prototype is guarded) -> fixes -Wmissing-prototypes when SIV is off.
- test_aes.c: mark key/in/out (void) in test_wc_AesModesArgMcdc; they are
  used only by the per-mode (CTR/CFB/OFB) blocks -> fixes -Wunused-variable
  when no such mode is enabled.
- api.c: guard the test_CryptoCb_* callback helpers with
  WOLF_CRYPTO_CB && WOLFSSL_TEST_STATIC_BUILD to match their only caller
  -> fixes -Wunused-function in cryptocb non-static builds.
- api.c: register test_wc_CryptoCb_registry under its actual definition
  condition (WOLF_CRYPTO_CB && HAVE_IO_TESTS_DEPENDENCIES && !ONLY_*) and
  keep test_wc_CryptoCb registered unconditionally (as on master)
  -> fixes undeclared / defined-but-unused across cryptocb configs.
- api.c: declare session-cache 'mode' under OPENSSL_EXTRA (its only uses)
  -> fixes -Wunused-variable without opensslextra.
- api.c: guard the Enable/DisableOCSPStapling calls in
  test_wolfSSL_crl_ocsp_object_api with HAVE_CERTIFICATE_STATUS_REQUEST[_V2]
  -> fixes undefined references with OCSP but no stapling.

Verified clean under: --enable-ocsp --enable-ocspstapling, --enable-ocsp
(no stapling), and --enable-all; unit.test runs pass.
2026-07-09 10:02:22 +02:00
Daniele Lacamera a3b3ee829b tests: fix config-dependent AES-CTR rounds-check coverage assertion
test_wc_AesModesArgMcdc asserted that wc_AesCtrEncrypt() with corrupted
aes.rounds returns KEYUSAGE_E, but used sz = 32 (an exact block multiple).
When in != out, the full blocks are consumed by a batch path that does not
surface the per-block rounds error - the AES-NI batch, or the HAVE_AES_ECB
fast path which ignores wc_AesEcbEncrypt()'s return - leaving no trailing
partial block, so the function returns 0 and the assertion fails. This was
latent (the whole test binary failed to link before the visibility fix) and
reproduces in --disable-aesni --enable-aesecb builds.

Use a non-block-multiple size (WC_AES_BLOCK_SIZE + 4) so the
"(ret == 0) && sz" leftover-handling call runs and fails on the corrupted
rounds via wc_AesEncrypt() in every backend. Reported by Copilot review on
PR #10845.

Verified: test_wc_AesModesArgMcdc now passes under --disable-aesni
--enable-aesecb (previously failed) and under --enable-aesni --enable-aesecb.
2026-07-09 10:02:22 +02:00
Daniele Lacamera e8cad24798 tests: guard internal-symbol MC/DC tests with WOLFSSL_TEST_STATIC_BUILD
Several MC/DC coverage tests called WOLFSSL_LOCAL (hidden-visibility)
library functions directly from the in-tree unit.test:
  - wc_AesCcmCheckTagSize()                         (test_aes.c)
  - wc_CryptoCb_Init/Cleanup/GetDevIdAtIndex()      (api.c)

These only link when the library is built with test-static visibility, so
normal (shared) builds failed at link with "undefined reference", breaking
essentially every CI build job. Gate the affected assertions on
WOLFSSL_TEST_STATIC_BUILD (in addition to the existing feature guards) so
they compile out where the symbols are hidden, matching the existing
wolfSSL convention for internal-symbol tests.

Verified: ./configure --enable-all (no WOLFSSL_TEST_STATIC_BUILD) now
builds tests/unit.test cleanly and the full suite passes.
2026-07-09 10:02:21 +02:00
Daniele Lacamera e7cd2b773e tests: AES MC/DC white-box supplement + api decision/feature coverage
Add tests/unit-mcdc/, a standalone white-box program that compiles
wolfcrypt/src/aes.c directly to reach static/WOLFSSL_LOCAL helpers
(GHASH/GHASH_UPDATE ptr guards, _AesNew_common cross-arg checks) that
are structurally unreachable through the public API, closing 19 of the
AES MC/DC residuals. Extend tests/api/test_aes.{c,h} with the
decision/feature coverage cases these build on.

These are for the external ISO 26262 per-module MC/DC campaign; they do
not change library behaviour and are not part of the wolfSSL build.
2026-07-09 10:02:21 +02:00
Daniele Lacamera 8b5abe54c1 tests: add MC/DC decision/feature coverage tests
Add MC/DC-targeted unit tests exercising decision and feature coverage
across AES (key wrap, GCM, feature), ASN.1, RSA, signature (falcon),
and CryptoCb registry surfaces.
2026-07-09 10:02:21 +02:00
David Garske a03cd09dc0 Merge pull request #10868 from SparkiDev/tsp_staticmem_fix
Time-Stamping Protocol testing: fix CI loop static-memory
2026-07-08 20:26:39 -07:00
Yosuke Shimizu 51aa3fb5f5 Preserve DTLS association on invalid record headers during handshake 2026-07-09 10:02:56 +09:00
Sean Parkinson b3a9c18839 Time-Stamping Protocol testing: fix CI loop static-memory
Static-memory CI loop failed as tests were using too much memory.
Tests changed.
Name of loop change to tsp-staticmemory to make more sense.
2026-07-09 09:59:01 +10:00
Anthony Hu d52ff68832 bit of back and forth 2026-07-08 19:50:38 -04:00
Yosuke Shimizu 768a98088d Lock globalRNGMutex around all shared globalRNG access in OpenSSL-compat RNG 2026-07-09 08:43:22 +09:00
Zackery Backman e2f1c54ab4 Add workflows to check other wolfSSL products still build
For each product (wolfSSH, wolfCLU, wolfTPM, wolfMQTT, wolfPKCS11, wolfProvider) this builds wolfSSL and then builds the product against it, at both the product's latest release tag and its master branch. It only checks that they compile, it does not run any tests. If a wolfSSL change breaks a product's latest release on purpose, you say so in a commit message with breaks-<product>=<tag>. A break on a product's master is not allowed and has to be fixed.

breaks-wolfssh=v1.5.0-stable

Note: wolfSSH v1.5.0-stable does not currently compile against wolfSSL. This commit did not break it, it adds the cross-library check that discovered the break. The token above declares it so the new check tracks it as a known break instead of failing red, until wolfSSH ships a fixed release.
2026-07-08 16:39:00 -06:00
David Garske a4aab71ffe Merge pull request #10861 from padelsbach/asn-integer-overflow-copy
Fix possible memcpy length overflow in wolfSSL_d2i_ASN1_INTEGER
2026-07-08 15:20:05 -07:00
Daniel Pouzzner a5dbbf80f5 Merge pull request #10864 from danielinux/riscv-port-null-checks
Riscv port bug fixes
2026-07-08 17:06:56 -05:00
David Garske 95f337ada4 Merge pull request #10831 from padelsbach/ci-json-dry
CI: unify repeated flags using existing python script
2026-07-08 14:00:05 -07:00
David Garske fdfba83c38 Merge pull request #10788 from aidangarske/fenrir-tls-batch-2026-06
Various hardening fixes across sniffer, QUIC, PKCS#11, TLS and tooling
2026-07-08 13:58:14 -07:00
David Garske 1e6f266e47 Merge pull request #10760 from Frauschi/pkcs7-server-encode
PKCS#7 improvements
2026-07-08 13:55:52 -07:00
Mattia Moffa 207b8c137c Continue without ticket rather than failing handshake 2026-07-08 22:44:33 +02:00
Anthony Hu 93722d0aab whitespace 2026-07-08 15:51:19 -04:00