utilities for generic SetKey and ExportKey operations on HMAC, RSA, ECC,
and AES. Add wc_ecc_size/wc_ecc_sig_size callback hooks for hardware-only
keys. Integrate into configure.ac as --enable-cryptocbutils=setkey,export
options with CI test configurations in os-check.yml.
Add test handlers in test.c and api.c with export/import delegation
pattern, small-stack-safe allocations, custom curve support, and
DEBUG_CRYPTOCB helpers.
- se050_rsa_verify: when the function uploads only the public part of the key (keyCreated == 1), erase the transient SE050 object and don't persist keyIdSet = 1. A subsequent sign on the same RsaKey was reusing the public-only SE050 object and failing. Pre-existing bindings (from wc_RsaUseKeyId or a prior sign that uploaded a keypair) are preserved untouched.
- rsa_keygen_test: add WOLFSSL_SE050 to the existing WOLFSSL_CRYPTOCELL guard around the export-then-decode round-trip. SE050-generated keys keep their private components in the secure element, so wc_RsaKeyToDer + wc_RsaPrivateKeyDecode cannot complete. Matching guard on the idx declaration to avoid an unused-variable warning.
- se050_ed25519_verify_msg: initialize *res = 0 at entry so failures don't leak a stale res = 1 from a prior good verify.
- Ed25519 import functions: reset keyIdSet / keyId under WOLFSSL_SE050 in wc_ed25519_import_private_key_ex, wc_ed25519_import_private_only, wc_ed25519_import_public_ex so overwriting host-side key material invalidates any prior SE050 object binding.
- New workflow .github/workflows/se050-sim.yml: builds wolfSSL against the NXP Plug&Trust SDK and runs the wolfCrypt tests against the SE050Sim simulator. Patches the upstream Dockerfile to use the PR's wolfSSL source.
- ed25519_test SE050 adjustments:
- Cap the RFC 8032 loop at 5 iters — iter 5's 1023 B msg exceeds NXP SDK SE05X_TLV_BUF_SIZE_CMD = 900.
- rareEd verifies and private-only sign: expect WC_HW_E (SE050 delegates malformed-input rejection to the secure element) instead of BAD_FUNC_ARG / SIG_VERIFY_E.
- Skip ed25519ctx_test / ed25519ph_test — SE050 port drops the context/prehash params so RFC 8032 ctx/ph vectors can't byte-match.
Refactor CMAC init to common function, add wc_AesNew_Id/Label API, do same for RSA new
functions, and add test init helpers for id[] support along with some test disable options
Add PKCS#11 integration for ML-KEM with key generation,
encapsulation and decapsulation support through the crypto
callback path.
Includes ML-KEM PKCS#11 constants/types, key store handling,
token object lifecycle management, and ML-KEM key init helpers
for private-key ID/label workflows.
Align implementation details with current upstream conventions
and review feedback:
- internal wolfCrypt ML-KEM path only for PKCS#11
- inline ML-KEM key-type/flag checks in PKCS#11 code
- proper key template formatting and enum placement
- ensure TLS ML-KEM object storage behavior is compatible with
PKCS#11 ephemeral-key decapsulation flow
* implement legacy compatibility in settings.h and configure.ac (adds --enable-blake2b while retaining --enable-blake2);
* fix incorrect Blake2 gates in wolfcrypt/src/hash.c wc_HashGetDigestSize() and wc_HashGetBlockSize();
* in wolfcrypt/test/test.c hash_test(), backfill missing Blake2 test coverage and separate blake2b from blake2s in typesHashBad[];
* in tests/api/test_hash.c, separate blake2b from blake2s in notCompiledHash[], sizeSupportedHash[], and sizeNotCompiledHash[].
wc_ecc_import_x963_ex2 only checked whether an imported public point
lies on the intended curve when both USE_ECC_B_PARAM was compiled in
and the caller passed untrusted=1. In a default ./configure build,
USE_ECC_B_PARAM is not defined, so the check was compiled out entirely.
Additionally, the legacy wrapper wc_ecc_import_x963_ex unconditionally
passed untrusted=0, meaning ECIES (wc_ecc_decrypt), PKCS#7 KARI, and
the EVP ECDH layer never triggered the check even when the macro was
present. In the OpenSSL compatibility layer, wolfSSL_ECPoint_d2i
guarded its on-curve check behind !wolfSSL_BN_is_one(point->Z), but
wc_ecc_import_point_der_ex always sets Z=1 for uncompressed points,
making the check dead code.
An attacker who can supply an EC public key (e.g. via an ECIES
ciphertext, PKCS#7 enveloped-data, EVP_PKEY_derive, or
EC_POINT_oct2point + ECDH_compute_key) can choose a point on a twist
of the target curve with a smooth-order subgroup. Each ECDH query
leaks the victim's static private scalar modulo a small prime; CRT
reconstruction across enough queries recovers the full key
(Biehl-Meyer-Müller invalid-curve attack). Static-key ECIES and PKCS#7
KARI are directly affected; TLS is affected in default builds because
the USE_ECC_B_PARAM gate defeated the untrusted=1 flag that the
handshake does pass.
Four changes close the attack:
1. Remove the USE_ECC_B_PARAM gate completely in the code base so that
wc_ecc_point_is_on_curve() is compiled in all builds, not only
those with HAVE_COMP_KEY or OPENSSL_EXTRA (only set for legacy FIPS
builds in settings.h).
2. wc_ecc_import_x963_ex: pass untrusted=1 to wc_ecc_import_x963_ex2
so that ECIES, PKCS#7 KARI, and EVP callers that go through the
four-argument wrapper always validate the imported point.
3. wc_ecc_import_x963_ex2: use the lightweight sp_ecc_is_point_NNN
helpers (curve-equation check only) instead of sp_ecc_check_key_NNN
(which additionally performs a full point*order scalar multiply).
For prime-order curves (P-256, P-384, P-521, SM2) the on-curve
equation check y^2 = x^3 + ax + b is sufficient to defeat
invalid-curve attacks — every non-identity point on a prime-order
curve has the full group order, so the expensive order-multiply
check is unnecessary. This avoids the ~50% ECDH performance
regression caused by the redundant scalar multiplication.
4. wolfSSL_ECPoint_d2i (pk_ec.c): add unconditional on-curve
validation via wolfSSL_EC_POINT_is_on_curve after import. The
existing check was gated on !wolfSSL_BN_is_one(point->Z) and
therefore dead code for all uncompressed-point imports. This closes
the OpenSSL compat layer attack path (EC_POINT_oct2point followed
by ECDH_compute_key).
Non-SP curves fall back to wc_ecc_point_is_on_curve which performs the
same equation check using mp_int arithmetic.
Reported by: Nicholas Carlini (Anthropic) & Thai Duong (Calif.io)
* wc_rng_bank_default_set()
* wc_rng_bank_default_checkout()
* wc_rng_bank_default_checkin()
* wc_rng_bank_default_clear()
* Added additional argument error checking to existing APIs, with a new
rng_inst_matches_bank() helper function.
* Implemented feature gates WC_RNG_BANK_DEFAULT_SUPPORT and
WC_RNG_BANK_NO_DEFAULT_SUPPORT. When WC_RNG_BANK_DEFAULT_SUPPORT, the new
APIs are available, and a NULL bank passed to APIs implicitly refers to the
default bank.
wolfcrypt/test/test.c: in random_bank_test() add comprehensive smoke test coverage of new APIs and argument checking.
wolfssl/wolfcrypt/wc_port.h and wolfcrypt/src/wc_port.c:
* Add wolfSSL_RefInc2(), wolfSSL_RefDec2(), wolfSSL_RefWithMutexInc2(), and
wolfSSL_RefWithMutexDec2(), returning the atomically determined new count in
the second arg;
* Fix type of second arg in the fallback definition of
wolfSSL_Atomic_Ptr_CompareExchange().
linuxkm/lkcapi_sha_glue.c:
Refactor the _REGISTER_HASH_DRBG / _REGISTER_HASH_DRBG_DEFAULT facility around
the new wc_rng_bank_default facility, eliminating post-init use of
kernel-native crypto_default_rng, crypto_get_default_rng(), and
crypto_put_default_rng(), and eliminating all use on kernel 7.1+ (where these
will become unexported kernel-native statics). With the refactor, the
LINUXKM_DRBG_GET_RANDOM_BYTES facility uses only direct native wolfCrypt
objects and calls to fulfill requests.
wolfssl/wolfcrypt/error-crypt.h, wolfcrypt/src/error.c, wolfcrypt/test/test.c, tests/api.c: add WC_SUCCESS = 0 "wolfCrypt generic success".
* add WC_FIPS_186_4, WC_FIPS_186_4_PLUS, WC_FIPS_186_5, and WC_FIPS_186_5_PLUS feature macros.
* add support for WC_HASH_CUSTOM_MIN_DIGEST_SIZE, WC_HASH_CUSTOM_MAX_DIGEST_SIZE, and
WC_HASH_CUSTOM_MAX_BLOCK_SIZE, for use with custom digest algorithms.
* add SigOidMatchesKeyOid() helper function and WC_MIN_DIGEST_SIZE macro.
* add additional size and OID agreement checks for sig gen and verify ops.
* update ecc_test_vector() with FIPS 186-5 vectors.
Co-authored-by: Tobias Frauenschläger <tobias@wolfssl.com>
wc_PKCS7_DecodeAuthEnvelopedData() accepted an attacker-controlled GCM tag
length from the mac OCTET STRING and did not validate it against the
parsed aes-ICVlen parameter. In parallel, wc_AesGcmDecrypt() accepted
very short tags on decrypt while encrypt enforced WOLFSSL_MIN_AUTH_TAG_SZ.
This made short-tag verification reachable through CMS AuthEnvelopedData
and weakened integrity checks by allowing tag truncation.
Fixes:
- validate parsed macSz range in AuthEnvelopedData decode
- require authTagSz to match parsed macSz
- reject undersized GCM tags in PKCS7 decode
- enforce WOLFSSL_MIN_AUTH_TAG_SZ in wc_AesGcmDecrypt() and
wc_AesGcmDecryptFinal()
Also add a regression test in pkcs7authenveloped vectors that truncates
the final MAC OCTET STRING length from 16 to 1 and verifies decode fails.
Reported by: Nicholas Carlini (Anthropic) & Thai Duong (Calif.io)