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.
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.
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.
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.
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.
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.
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.
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.
- Break out of the chain-build loop after the partial-chain fallback accepts
a caller-trusted terminus, so it is pushed to ctx->chain once instead of
twice; X509StoreCheckPathLen's anchor-skip is now defensive, not load-bearing.
- Drop the now-dead cert == anchor guard and refresh the comment.
- Rework the pathLen regression tests: reuse the existing certs/test-pathlen
chains (chainF rejects, chainB verifies) instead of inlined report certs.
tests/api/api.h: always use FIPS 186-4 settings if defined(HAVE_SELFTEST).
wolfssl/wolfcrypt/settings.h: if defined(HAVE_SELFTEST), #define WC_FIPS_186_4.
* remove FIPS 186-5 sign-mode restrictions from WC_HASH_CUSTOM_MIN_DIGEST_SIZE.
* set up WC_MIN_DIGEST_SIZE_FOR_SIGN and WC_MIN_DIGEST_SIZE_FOR_VERIFY, derived from WC_HASH_CUSTOM_MIN_DIGEST_SIZE, but enforcing FIPS 186-5 sign-mode restrictions only for WC_MIN_DIGEST_SIZE_FOR_SIGN.
* replace all uses of WC_MIN_DIGEST_SIZE with WC_MIN_DIGEST_SIZE_FOR_SIGN or WC_MIN_DIGEST_SIZE_FOR_VERIFY as appropriate.
wolfcrypt/test/test.c: in cryptocb_test(), don't expect callback execution in FIPS builds.
wolfssl/wolfcrypt/settings.h: in WOLFSSL_LINUXKM section, if defined(NO_SHA) while registering ECDSA handlers, force WC_MIN_DIGEST_SIZE_FOR_VERIFY to 20 for SHA-1 verify support.
Add a new option to require that an external Pre-Shared Key is negotiated
for a handshake to succeed, configured via the new APIs
wolfSSL_CTX_require_psk()/wolfSSL_require_psk(). When set, a handshake
that completes without negotiating an external PSK is aborted with
PSK_MISSING_ERROR instead of falling back to a certificate handshake, so
the PSK acts as an additional security factor.
This is a TLS 1.3 / DTLS 1.3 feature. In (D)TLS 1.2 the use of a PSK is
determined by the negotiated cipher suite, so a mandatory PSK is instead
configured there by restricting the cipher suite list to PSK suites; the
new APIs therefore reject non-TLS-1.3 contexts with BAD_FUNC_ARG.
To keep the requirement fail-closed, the APIs also disable version
downgrade on the object so a downgrade-capable context (e.g. one created
from a v23 method) cannot silently fall back to (D)TLS 1.2 and complete
without a PSK; a peer that does not support (D)TLS 1.3 fails to connect.
The requirement applies to external PSKs only (not session tickets):
session-ticket resumption is exempt. To preserve forward secrecy a
mandatory external PSK must also use an (EC)DHE key exchange; a pure
psk_ke handshake is rejected with PSK_KEY_ERROR. When used with
WOLFSSL_CERT_WITH_EXTERN_PSK, it also ensures that peers are properly
authenticated with both the PSK and via certificates.
The new APIs live alongside the existing wolfSSL_[CTX_]no_dhe_psk()/
only_dhe_psk() PSK options and do not depend on certificate support, so
the feature is usable in NO_CERTS (PSK-only) builds.
Added unit tests for the new APIs and enforcement.