Under DEBUG_WOLFSSL the hash->type != type check in wc_HashUpdate,
wc_HashFinal and wc_HashFree fired for an uninitialized hash
(hash->type == WC_HASH_TYPE_NONE), returning BAD_FUNC_ARG where a non-debug
build returns HASH_TYPE_E from the type switch, so the returned error code
depended on whether DEBUG_WOLFSSL was defined. Only apply the mismatch check
to initialized hashes; the genuine init-then-wrong-type misuse check is
preserved.
The LMS and XMSS X.509 generation tests persist their stateful private
keys through read/write callbacks to hardcoded /tmp paths
(/tmp/wolfssl_test_lms.key, /tmp/wolfssl_test_xmss_gen.key). When
make check runs multiple configs in parallel on a shared /tmp (CI
shards), concurrent unit.test processes clobber the same file; a
subsequent read then gets a different-sized key and signing fails with
IO_FAILED_E (e.g. test_rfc9802_xmss_x509_gen returning -291).
Give the LMS and XMSS test key-file paths a per-process name via
getpid(), guarded by HAVE_GETPID/WOLFSSL_NO_GETPID with <unistd.h>
included under the same guard and a plain-path fallback, so the file
still compiles on Windows / NO_WOLFSSL_DIR / no-OS builds. Verified by
racing six concurrent unit.test processes: 5/6 failed before, 6/6 pass
after; the HAVE_GETPID and fallback paths both compile clean under
-Werror.
```
==485951== Uninitialised value was created by a stack allocation
==485951== at 0x207D47: des3_key_wrap_test (test.c:12773)
```
and
```
==485951== Uninitialised value was created by a stack allocation
==485951== at 0x3A075E: test_wc_AesGcmArgMcdc (test_aes.c:8968)
```
test_pkcs7.c: test_wc_PKCS7_BER also accepts ret >= 0 (Bleichenbacher mitigation hides the RSA key error, making the result non-deterministic).
suites.c: skip --send-ticket cases as NOT_BUILT_IN when HAVE_SESSION_TICKET
is off (avoids port-11111 race).
The RISC-V ASM build provides its own AES-GCM implementation
(wolfcrypt/src/port/riscv/riscv-64-aes.c) rather than AES_GCM_decrypt_C, so
it does not clear the output buffer on authentication failure. Exclude it
from the zero-check, matching the other non-C decrypt paths. Fixes the
riscv64 multi-arch testwolfcrypt failure.
Skoll review of the auth-fail zero-check test in aesgcm_test:
- The guard listed WOLFSSL_ARMASM_NO_HW_CRYPTO and __aarch64__, which are
defined on default x86-64 builds, so the zero-check block was compiled out
and the assertion never actually ran there. They are subsumed by
WOLFSSL_ARMASM (the condition under which AES_GCM_decrypt_C is not the
decrypt path), so use that instead and the check runs on the C path.
- Exclude WC_AES_GCM_DEC_AUTH_EARLY (out is not written on an early-auth
failure) and WOLFSSL_ASYNC_CRYPT (a real async device may offload the
decrypt and not clear the output).
Verified: default make check passes with the zero-check now executing;
testwolfcrypt AES-GCM passes with --enable-aesni and with
-DWC_AES_GCM_DEC_AUTH_EARLY.
check-source-text reports these as unneeded because the macros are now
defined in the checked build config, so their known-extra whitelist entries
are redundant:
WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
WOLFSSL_ASYNC_CERT_YIELD
WOLFSSL_MLKEM_DYNAMIC_KEYS
Review follow-ups for the constant-time AES-GCM decrypt output clear:
- Guard the output-masking pass with #ifndef WC_AES_GCM_DEC_AUTH_EARLY. In
that configuration the tag is verified before decryption and a mismatch
returns before any output is written, so the masking pass is a guaranteed
no-op; skipping it avoids a wasted O(sz) pass.
- Add a test in aesgcm_test: decrypt with a corrupted tag into a pre-filled
buffer and assert wc_AesGcmDecrypt returns AES_GCM_AUTH_E and, on the
software C path, that the output buffer is cleared to zero. The AES-NI/asm
decrypt paths and the FIPS module do not clear the output on auth failure,
so the zero check forces the C path (use_aesni = 0) and is limited to it
(and skipped under HAVE_FIPS). The AES_GCM_AUTH_E comparison uses
WC_NO_ERR_TRACE().
Verified (gcc 15.2): make check passes on the default (C path) build;
testwolfcrypt AES-GCM passes with --enable-aesni and with
-DWC_AES_GCM_DEC_AUTH_EARLY; ct-valgrind aes_gcm reports 0 errors.
AES_GCM_decrypt_C cleared the output on a tag mismatch with
'if (ret != 0) ForceZero(out, sz)'. That is a conditional branch on the
secret-dependent authentication result, which is not constant time and is
flagged by the ct-valgrind constant-time test (Conditional jump depends on
uninitialised value in AES_GCM_decrypt_C).
Mask the output with 'res' (already computed as all-ones on tag mismatch,
zero on match) instead of branching, matching the constant-time idiom used
for the tag comparison itself. C path only; the AES-NI/ASM paths are
unaffected.
linuxkm/lkcapi_aes_glue.c: zero the ephemeral ivOut in AesGcmCrypt_1().
wolfcrypt/src/port/kcapi/kcapi_aes.c: tighten the test on the return value from kcapi_aead_decrypt().
wc_RsaFunction is declared WOLFSSL_API but the FIPS module does not export
it, so test_wc_RsaDecisionCoverage's 7-condition wc_RsaFunction arg-check
block fails to link (undefined reference) across the FIPS legs. Exclude the
block under HAVE_FIPS; cipher/plain/key/rng stay used by the other checks,
so no unused-variable. Not frozen under self-test, so it stays there.
check-source-text flags error-code operands compared without
WC_NO_ERR_TRACE(). Wrap them in the ed25519 and cmac white-box binaries
(same fix already applied to the curve25519 white-box).
The frozen FIPS/self-test hmac's wc_HmacSizeByType returns HMAC_KAT_FIPS_E
(-206) for any type it doesn't accept - not just the invalid 9999 case but
also MD5 (not a FIPS HMAC type), which returned -206 instead of the digest
size. Rather than chase each type, exclude the whole function under
HAVE_SELFTEST/HAVE_FIPS (the campaign measures MC/DC on open builds only).