Commit Graph
12023 Commits
Author SHA1 Message Date
Tobias Frauenschläger 097ddc19d8 Use alignment-safe writes in ML-KEM mlkem_vec_compress_10_c
The little-endian large-code path of mlkem_vec_compress_10_c cast the
output byte buffer to word32* and issued five 32-bit stores through it.
That buffer is the caller-supplied ML-KEM ciphertext, which has no
alignment guarantee, so on strict-alignment targets the store bus-faults
and the cast violates strict aliasing. Write each word with
writeUnalignedWord32, which does an alignment-safe byte copy, matching
mldsa_encode_w1_88_c and the neighboring ML-KEM sampling code.

Fixes F-6782.
2026-08-01 13:13:00 +02:00
Tobias Frauenschläger ca449b1263 Use alignment-safe reads in ML-KEM mlkem_cbd_eta3
The little-endian large-code path of mlkem_cbd_eta3 cast the
caller-supplied byte buffer to word32* and read through it. The buffer
has no alignment guarantee, so on strict-alignment targets such as
Cortex-M3 and M4 with unaligned-access trapping enabled the read faults
or returns wrong values, and the cast violates strict aliasing. Read
each word with readUnalignedWord32, which does an alignment-safe byte
copy, matching the neighboring mlkem_cbd_eta2.

Fixes F-6781.
2026-08-01 13:13:00 +02:00
Tobias Frauenschläger af0385cb8d Avoid unaligned word32 read of RSA key id under SE050
wc_InitRsaKey_Id cast the byte array key->id to word32* and dereferenced
it to recover the SE050 key id. key->id is a byte array with no alignment
guarantee inside RsaKey, so the dereference is an unaligned 32-bit read
that faults or mis-reads on strict-alignment targets, and it violates
strict aliasing. Read the value with readUnalignedWord32 instead, which
does an alignment-safe byte copy, matching wc_ecc_init_id.

Fixes F-6624.
2026-08-01 13:13:00 +02:00
Tobias Frauenschläger 1673777231 Fix transposed register and mask in ESP32-C3 RSA unlock
The ESP32-C3 deactivation path in esp_mp_hw_unlock passed its arguments
to DPORT_REG_CLR_BIT and DPORT_REG_SET_BIT in the wrong order and added
a stray DR_REG_RSA_BASE offset. The macros take (register address, bit
mask), but the code used the bit mask as part of the register address
and the register as the bit mask. As a result the RSA clock-enable and
memory power-down bits were never updated at deactivation, and reads and
writes landed at a bogus peripheral address. The accelerator was left
powered up after every bignum and RSA operation.

Pass the register address first and the bit mask second and drop the
offset, mirroring the activation path and the other targets.

Fixes F-6779.
2026-08-01 13:13:00 +02:00
Tobias Frauenschläger c196546762 Surface hardware failures in Intel QAT sync cipher
IntelQaSymCipher ran cpaCySymPerformOp synchronously but never
translated its completion status into the return code. Only the AES-GCM
decrypt auth check, driven by verifyResult, could set an error. For
AES-CBC, AES-GCM encrypt, and 3DES-CBC a non-success status left ret at
zero, so the exit path copied the working buffer to the output and
returned success. On encrypt that buffer still holds the plaintext copy,
so a hardware failure returned success with plaintext written to the
ciphertext output.

Translate a non-success perform-op status into ASYNC_OP_E, matching the
asynchronous port, so hardware failures are surfaced instead of
returning zero with unprocessed output.

Fixes F-6623.
2026-08-01 13:13:00 +02:00
Tobias Frauenschläger fd13b11755 Use random-witness primality test for untrusted DH modulus
wc_DhSetKey_ex loads DH parameters as untrusted and validates that the
modulus is prime, but it passed no RNG, so the check fell back to a
Miller-Rabin test using the fixed small-prime bases 2 through 19. That
test is defeatable: a composite crafted as a strong pseudoprime to those
known bases passes as prime, letting an attacker supply a composite
modulus with a smooth factorization for small-subgroup recovery of the
private exponent and shared secret.

When no RNG is supplied on the untrusted path, create a temporary RNG so
mp_prime_is_prime_ex runs with random witnesses, which such crafted
composites cannot reliably pass. Named FFDHE primes still short-circuit
the check, and builds without an RNG keep the deterministic test.

Fixes F-6776.
2026-08-01 13:13:00 +02:00
Tobias Frauenschläger c508b402ca Reject identity-point ECDH shared secret
wc_ecc_shared_secret_gen_sync ran the scalar multiplication and then
copied the x-coordinate to the output without checking whether the
result was the point at infinity. Both math backends report success for
the identity: ecc_map_ex sets x, y to zero and z to one and returns
success, and the single precision generators serialize the identity as
an all-zero x-coordinate. Either way a shared secret that computed to
infinity was handed back as an all-zero secret with a success code,
where SP 800-56Ar3 5.7.1.2 requires an error and stop.

Check the mapped point on the software path, and detect the all-zero
output after the single precision generators, returning ECC_INF_E in
both cases. The scan accumulates over the whole buffer so it does not
branch on the secret.

A key whose private value is resident in an SE050 carries no software
scalar, so the software multiply legitimately yields the identity for
it. Skip the check for those keys specifically, rather than for a zero
scalar: on a prime-order curve a zero scalar is the one way the identity
can arise, so exempting it would disable the check for the case it
exists to catch.

Fixes F-6770.
2026-08-01 13:13:00 +02:00
Tobias Frauenschläger 3b663585ea Reject unset key in wc_Chacha_Process
wc_Chacha_Process validated only its pointer arguments and then produced
keystream directly from the context state. A zero-initialized ChaCha
context, common for static or global storage, that received a nonce via
wc_Chacha_SetIV but never had wc_Chacha_SetKey called would encrypt with
an all-zero, attacker-predictable key and still return success. This is
the same fail-open class already guarded against in wc_Arc4Process.

Add a keySet flag to the ChaCha struct, set it in wc_Chacha_SetKey, and
return MISSING_KEY from wc_Chacha_Process when the key was never set.

Fixes F-6893.
2026-08-01 13:11:52 +02:00
Tobias Frauenschläger d0f5c167da Bound ECDSA r/s size in PSoC6 hardware verify path
psoc6_ecc_verify_hash_ex serialized the signature r and s components
into a fixed 132-byte stack buffer using mp_to_unsigned_bin without
checking their sizes. The values come from attacker-supplied ASN.1 in
DecodeECC_DSA_Sig with no magnitude cap beyond sp_int capacity, so an
oversized r or s wrote past signature_buf, a pre-authentication stack
overflow reachable during TLS signature verification. The generic path
guards this with wc_ecc_check_r_s_range, but that check is compiled out
on WOLFSSL_PSOC6_CRYPTO builds and the port function performed no r/s
validation of its own. Reject any r or s whose serialized size exceeds
the key size before writing into the buffer.

Fixes F-6778.
2026-08-01 13:11:52 +02:00
David GarskeandGitHub 6502cdd34c Merge pull request #10946 from night1rider/benchmark-hmac-sha3-shake256
Add hmac-sha3 to benchmark, and macro overrides.
2026-07-31 16:25:20 -07:00
David GarskeandGitHub 577f189820 Merge pull request #10964 from SparkiDev/tfm_fixes_1
TFM bounds checks for safety
2026-07-31 16:23:48 -07:00
David GarskeandGitHub 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
David GarskeandGitHub 3503d462e0 Merge pull request #10981 from SparkiDev/mlkem_avx512
ML-KEM assembly: AVX512F and AVX512VBMI
2026-07-31 14:21:20 -07:00
Daniel PouzznerandGitHub e89f63aea2 Merge pull request #9634 from SparkiDev/p521_x64_align_16
SP ECC: ecc_point - add padding when 16 byte aligned
2026-07-31 13:30:45 -05:00
Tobias FrauenschlägerandGitHub 41b7a0209a Merge pull request #11023 from SparkiDev/riscv64_label_fix
RISC-V 64-bit: fix gaurd around GCM tables
2026-07-31 11:39:38 +02:00
Sean Parkinson 0e691ddeb7 SP ECC: ecc_point - add padding when 16 byte aligned
To make 16-byte aligned points, add padding to end.
2026-07-31 16:22:10 +10:00
Sean ParkinsonandGitHub c99dafc1f7 Merge pull request #10973 from danielinux/fixes-mcdc-step4
Bug Fixes: issues discovered during MC/DC coverage step 4
2026-07-31 10:54:57 +10:00
Sean Parkinson 718bda3cc8 RISC-V 64-bit: fix gaurd around GCM tables
Missing #if guard around GCM tables.
2026-07-31 10:02:10 +10:00
Daniel PouzznerandGitHub 8ec8bd6876 Merge pull request #11015 from SparkiDev/asm_fixes_5
RISC-V 64-bit assembly: AES-GCM decrypt fix
2026-07-30 18:20:14 -05:00
David GarskeandGitHub 4f92fe3e85 Merge pull request #10988 from SparkiDev/mem_zero_fixes_1
MemZero: Add more checks of buffers.
2026-07-30 15:42:10 -07:00
David GarskeandGitHub 643d209dba Merge pull request #10961 from anhu/crl_unknown_ext
New API for CRL unknown extension callback
2026-07-30 09:00:23 -07:00
Sean Parkinson e9d411ed09 RISC-V 64-bit assembly: AES-GCM decrypt fix
Fix for when decrypting into the same buffer.

Also fixed test on PPC64/32.
2026-07-30 16:50:52 +10:00
Sean Parkinson f79d42eddd ML-KEM assembly: AVX512F and AVX512VBMI.
New assembly for ML-KEM for Intel x64 machines that support AVX512 extensions.
Update how much is added to the stack of others.
2026-07-30 13:04:16 +10:00
Daniel PouzznerandGitHub f69903778f Merge pull request #11001 from SparkiDev/regression_fixes_28
Regression testing fixes
2026-07-29 22:02:19 -05:00
Sean Parkinson bbb0743dbd Generated Assembly/SP: regeneration and fixes
The assembly/SP generators had been modified but not all output files were
generated.

All files now are up to date with the latest generator scripts, that were fixed.
2026-07-30 10:52:44 +10:00
Sean Parkinson 1106d593fb MemZero: Add more checks of buffers.
Added wc_MemZero_Add calls and wc_MemZero_Check calls wheter ForceZero is used.
Fixed a couple of places that had the wrong size.
2026-07-30 10:50:52 +10:00
Daniel PouzznerandGitHub e882e1dc74 Merge pull request #10996 from danielinux/falcon-kernel-fixes
Falcon: enable fast backends for use in Linux kernel
2026-07-29 13:27:42 -05:00
Anthony Hu 686ab1d857 Validate CRL entry-extension OID encoding before decoding 2026-07-29 12:05:39 -04:00
Daniele Lacamera f0c28b84ea autoconf: build wolfevent.c under --enable-usersettings
wolfevent.c (the wolfEvent completion queue) only compiled under
--enable-asynccrypt: AM_CONDITIONAL([BUILD_WOLFEVENT],...) tested only
ENABLED_ASYNCCRYPT. But HAVE_WOLF_EVENT is a user-settable macro that
internal.c/ssl.c gate their wolfEventQueue_* references on, so a
--enable-usersettings build that defines HAVE_WOLF_EVENT referenced the
queue API while the object was never built -> link error (undefined
wolfEventQueue_Init/Free). BUILD_WOLFEVENT was also the only BUILD_*
conditional missing the standard "|| ENABLED_USERSETTINGS = yes" escape
hatch that lets a header-driven build compile a source and defer the
decision to the file's own #ifdef.

Add that clause (matching BUILD_FALCON/BUILD_MLKEM/etc.) so usersettings
builds compile wolfevent.c; its internal #ifdef HAVE_WOLF_EVENT still
gates whether the code is active, so non-event builds get an empty object.

Also silence wolfEvent_Poll's unused-parameter -Werror in non-async builds
(event/flags are consumed only by the async hardware poll), which the
above change surfaces now that the file compiles without WOLFSSL_ASYNC_CRYPT.
2026-07-29 08:09:12 +02:00
Daniele Lacamera 94014ee5ca rsa: address review - drop XMEMSET, free uninitialized temporaries instead
Restore the original short-circuit XMALLOC chains and leave the zeroing to
mp_init_multi(). On a partial allocation failure mp_init_multi() is skipped,
so nothing is initialized: free whatever was allocated right there and NULL
the pointers, so the shared cleanup at the end of the function never calls
mp_clear()/mp_forcezero() on an allocated-but-uninitialized mp_int.

No extra mp_init() calls, no XMEMSET, and the returned error codes are
unchanged.
2026-07-29 08:02:02 +02:00
Daniele Lacamera 2e985f46c3 math: guard fp_cnt_lsb/mp_cnt_lsb digit scan
Return 0 when all used digits are zero instead of scanning past them.
2026-07-29 08:02:02 +02:00
Daniele Lacamera 6a6d4b12ac rsa: fix cleanup of mp_int temporaries in probable-prime checks
Initialize the mp_int temporaries as soon as they are allocated in
wc_CompareDiffPQ(), _CheckProbablePrime() and wc_CheckProbablePrime_ex(),
so the cleanup path handles them consistently in all cases.
2026-07-29 08:02:02 +02:00
Daniele Lacamera a11d7f449a ascon: handle empty input in wc_AsconAEAD128_DecryptUpdate
Return early when inSz == 0, mirroring the other Ascon Update functions.
2026-07-29 08:02:02 +02:00
Sean Parkinson 119901c227 Regression testing fixes
wc_mlkem.h/test_mlkem.c: Respect WC_NO_CONSTRUCTORS guard.

settings.h, fe_operations.h: move WOLFSSL_CURVE25519_USE_ED25519 derivation into settings.h so the assembler sees it; fixes fe_cmov_table undefined on ARM32.

ge_448.c: shift the product instead of the byte in six sc448_* loops, dodging a GCC ARM32 NEON miscompile that produced wrong ed448 signatures; table shrunk [56]→[28].
2026-07-29 14:59:47 +10:00
Sean ParkinsonandGitHub 9c5436b853 Merge pull request #10968 from Frauschi/fenrir_tls
Fenrir fixes
2026-07-28 11:31:19 +10:00
David GarskeandGitHub 27aaf47284 Merge pull request #10979 from aidangarske/mldsa-signctx-cryptocb-devkey
Route wc_MlDsaKey_SignCtx through the crypto callback before the prvKeySet check for device keys
2026-07-27 16:28:18 -07:00
Daniele Lacamera c03d48ea93 Falcon: save/restore vector/FP registers around signing and keygen
Every fpr backend except the default integer-emulated one runs on the FP/vector
register file: WOLFSSL_FALCON_FPR_DOUBLE (C double -> SSE) and the generated
x86-64 fpr asm use xmm, and the folded AVX2/NEON FFT uses ymm / Q registers. All
of them must save and restore those registers around the work that uses fpr --
kernel FPU state under WOLFSSL_LINUXKM and the DEBUG_VECTOR_REGISTER_ACCESS
check. A single gate, WOLFSSL_FALCON_SAVE_VREGS (set for FPR_DOUBLE, FPR_ASM,
FFT_AVX2 or FFT_NEON), drives the wrapping so the emulated integer build stays
untouched.

The saves sit at the two int-returning orchestrators (falcon_native_make_key
around falcon_keygen; falcon_native_sign_msg around the tree build + ffSampling
loop) and read like every other fallible step: "ret = SAVE_VECTOR_REGISTERS2();
if (ret != 0) goto out;", propagating a save failure through normal cleanup.
Nested saves inside SHAKE256 are reference-counted. Verified with
DEBUG_VECTOR_REGISTER_ACCESS (+ABORT_ON_FAIL and fuzzing) on the double, asm and
avx2 backends: balanced counts, no unsaved FP/SIMD, graceful failure path.
2026-07-27 23:48:44 +02:00
night1rider 59c79512e3 benchmark: build and run the wolfCrypt benchmark in Windows ARM64 CI 2026-07-24 16:42:44 -06:00
Daniel Pouzzner 6325c48030 fixes from AI review:
linuxkm/lkcapi_aes_glue.c and linuxkm/lkcapi_sha_glue.c: add CMAC and SHA-3 to algs warned for incompatibility with kernels <5.6;

linuxkm/lkcapi_aes_glue.c, wolfcrypt/src/aes.c, wolfcrypt/src/memory.c, and wolfssl/wolfcrypt/memory.h: fix WC_DEBUG_CIPHER_LIFECYCLE in kernel mode (km_AesGet() and km_AesCmacMaterialize()), add WARN_UNUSED_RESULT to wc_debug_CipherLifecycle*(), and fix an unchecked wc_debug_CipherLifecycleFree() in wc_AesFree();

linuxkm/lkcapi_aes_glue.c: fix unsafe wc_CmacFree() call in km_AesCmacSetKey();

linuxkm/lkcapi_sha_glue.c: in km_hmac_export(), avoid unlocked access to snapshot->desc_id (possible UAF under extreme pressure).
2026-07-24 16:39:55 -05:00
Daniel Pouzzner c3277317db wolfcrypt/src/aes.c: implement WC_C_DYNAMIC_FALLBACK for AES-NI in wc_AesGcmInit(). 2026-07-24 16:39:55 -05:00
Daniel Pouzzner 01a4a393fb wolfcrypt/src/cpuid.c: in cpuid_flag(), refactor out XMEMSET() to fix SEGV from gcc misoptimization. 2026-07-24 16:39:55 -05:00
Daniel Pouzzner 3d46cf4980 wolfcrypt/src/sha{256,512}.c, wolfssl/wolfcrypt/sha{256,512}.h, wolfssl/wolfcrypt/settings.h:
* Revert earlier changes adding WC_SHA256_W_SIZE and WC_SHA512_W_SIZE.

* Add WC_SHA2_NO_SMALL_STACK to allow the W work buffer to move back onto the
  stack.

* In wolfssl/wolfcrypt/settings.h, define WC_SHA2_NO_SMALL_STACK by default when
  WOLFSSL_KERNEL_MODE, and add a clause to #undef WOLFSSL_SMALL_STACK when
  building the SHA-2 implementations.

linuxkm/lkcapi_sha_glue.c:

* Refactor out superfluous struct km_sha_state.

* Clean up some macro dynamics.

* Add static asserts on HASH_MAX_STATESIZE to WC_LINUXKM_SHA1_IMPLEMENT() and
  WC_LINUXKM_SHA2_IMPLEMENT().
2026-07-24 16:39:54 -05:00
Daniel Pouzzner dc16169cd3 linuxkm/lkcapi_sha_glue.c: fix sha.W lifecycle management to prevent leaks:
* separate WC_LINUXKM_SHA_IMPLEMENT() into WC_LINUXKM_SHA1_IMPLEMENT() (no fixes
  needed) and WC_LINUXKM_SHA2_IMPLEMENT() (with associated new helpers
  WC_LINUXKM_SHA2_FREE_W(), WC_LINUXKM_SHA2_DECL_W(), WC_LINUXKM_SHA2_PUSH_W(),
  and WC_LINUXKM_SHA2_POP_W(), that move .W to a stack buffer).

* Reimplement SHA-2 one-shot digest callback to use only direct wolfCrypt calls
  rather than proxy to other callbacks.
2026-07-24 16:39:54 -05:00
JacobBarthelmehandGitHub 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
night1rider 3062dea0b6 Use the existing KEY32 macro and a named fake overhead constant in the new ECIES tests 2026-07-24 10:21:20 -06:00
night1rider 09444c84f6 Address ECIES review feedback: reuse aes.h GCM size constants, factor output size into ecc_ecies_total_size helper,
gate the AES-GCM ctx default on a usable IV mode, and name the benchmark ECIES desc buffer size
2026-07-24 10:21:20 -06:00
night1rider 97ab34c41a Fix ECIES clang-tidy dead-store and whitelist WOLFSSL_ECIES_STATIC_GCM_NONCE 2026-07-24 10:19:40 -06:00
night1rider 5460180f9b Small fix to address wrong assignment 2026-07-24 10:19:40 -06:00
night1rider e04b8c74da Enforce the ECIES single-use REQ/RESP state on the hardware CryptoCb path so a device that services encrypt/decrypt without a software fallback cannot reuse the ctx.
Add a testwolfcrypt case that services ECIES entirely in the callback and checks a second op on the same ctx is rejected with BAD_STATE_E.
2026-07-24 10:19:40 -06:00
night1rider a89ba18e7d Fix the ECIES DEM devId threading to compile where ecc_key has no devId field by reading it into a guarded local (PLUTON_CRYPTO_ECC/WOLF_CRYPTO_CB) that defaults to INVALID_DEVID 2026-07-24 10:19:40 -06:00