Extend the swdev callback to handle ECC operations: keygen, ECDH, sign,
verify, get-size, get-sig-size.
Relax WOLF_CRYPTO_CB_ONLY_ECC guards in the test suite so that tests run
under swdev, and wire wc_SwDev_Init/Cleanup into testsuite, client, and
server. Two tests are intentionally kept excluded even with swdev because
they call raw ECC math primitives (wc_ecc_mulmod, on-curve validation in
wc_ecc_import_x963) that are stripped below the cryptocb dispatch layer:
- ecc_mulmod_test (wolfcrypt/test/test.c)
- test_wc_ecc_import_x963_off_curve (tests/api/test_ecc.c)
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)
which force on BUILDING_WOLFSSL and do boilerplate includes, and update library
sources to include them at the top.
wolfssl_sources.h includes types.h, error-crypt.h, and logging.h, and
conditionally, config.h. settings.h and wc_port.h are unconditionally
included at the top of types.h.
wolfssl_sources_asm.h includes settings.h, and conditionally, config.h.
Add wolfssl_sources*.h to wolfcrypt/src/include.am, and to several IDE/ project
files.
Also added a TEST_WOLFSSL_SOURCES_INCLUSION_SEQUENCE clause in
wolfssl/wolfcrypt/settings.h to allow coverage testing.
In wolfcrypt/src/misc.c, retain existing ad hoc boilerplate includes, and use
them if WOLFSSL_VIS_FOR_TESTS, otherwise include the new wolfssl_sources.h.
Define WOLFSSL_VIS_FOR_TESTS at top of wolfcrypt/test/test.c.
Also renamed WOLFSSL_NEED_LINUX_CURRENT to WOLFSSL_LINUXKM_NEED_LINUX_CURRENT,
for clarity.
Improved testing of random APIs.
wolfmath tests moved out.
Public key algorithm testing moved out: RSA, DSA, DH, ECC, SM2,
Curve25519, Ed25519, Curve448, Ed448, ML-DSA.
Signature API tests moved out.
Fix for OCSP testing to ensure RSA is available.
Added group names to API test cases.
Can select groups to run with --group <name>. --groups lists all known
group names.
Added option to stop API testing on first failure: --stopOnFail.