1
0
mirror of https://github.com/wolfSSL/wolfssl.git synced 2026-10-24 04:09:07 +03:00

Merge pull request #11537 from SparkiDev/rsa_ecc_no_sw

RSA/ECC: no software builds
This commit is contained in:
philljj
2026-10-11 23:10:08 -05:00
committed by GitHub
15 changed files with 768 additions and 64 deletions

View File

@@ -53,6 +53,18 @@ jobs:
# vs SE050-resident key) added to wolfcrypt/test/test.c.
- name: only-key-id
extra_cflags: '-DWOLFSSL_SE050_ONLY_KEY_ID'
# Hardware-only public key: the wolfCrypt software RSA
# implementation (mod-exp, prime search, key check) and the software
# ECC implementation (point arithmetic, scalar multiply, software
# signer/ECDH/make-pub) are both left out of the build, so every RSA
# and ECC operation the test binary runs has to be served by the
# SE050. The image's ./configure enables TLS 1.3 and with it
# WC_RSA_PSS, so this leg keeps the RSA padding layer compiled; the
# padding-free variant (WOLFSSL_NO_RSA_SW_PAD, which rsa.c derives
# when RSA-PSS is off) needs --disable-rsapss --disable-tls13, which
# the simulator's Dockerfile does not expose as a build arg.
- name: no-pk-sw
extra_cflags: '-DWOLFSSL_NO_RSA_SW -DWOLFSSL_NO_ECC_SW'
steps:
- name: Checkout wolfSSL (PR source)
uses: actions/checkout@v5

View File

@@ -1049,6 +1049,7 @@ WOLFSSL_NO_DH186
WOLFSSL_NO_DILITHIUM_LEGACY_GATES
WOLFSSL_NO_DILITHIUM_LEGACY_NAMES
WOLFSSL_NO_DTLS_SIZE_CHECK
WOLFSSL_NO_ECC_SW
WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
WOLFSSL_NO_ETM_ALERT
WOLFSSL_NO_FCHMOD
@@ -1066,6 +1067,7 @@ WOLFSSL_NO_LMS_SHAKE256_256
WOLFSSL_NO_OCSP_DATE_CHECK
WOLFSSL_NO_OCSP_OPTIONAL_CERTS
WOLFSSL_NO_RSA_KEY_CHECK
WOLFSSL_NO_RSA_SW
WOLFSSL_NO_SERVER_GROUPS_EXT
WOLFSSL_NO_SESSION_STATS
WOLFSSL_NO_SHA256_N_WAY

View File

@@ -1,5 +1,32 @@
# wolfSSL Release (unreleased)
## New Features
* Added `WOLFSSL_NO_RSA_SW` and `WOLFSSL_NO_ECC_SW` for hardware-only public-key
builds on the NXP SE05x and Arm CryptoCell-310 ports. `WOLFSSL_NO_RSA_SW`
leaves out the software modular exponentiation, the prime search behind
`wc_MakeRsaKey()` and the software key consistency check (it forces
`WOLFSSL_RSA_KEY_CHECK` off), and when RSA-PSS is not enabled it drops the
PKCS#1 padding generation and the OAEP/PSS mask-generation helpers as well,
roughly halving `rsa.o`. `WOLFSSL_NO_ECC_SW` leaves out the projective point
arithmetic, the scalar multiplication, the software signer, the software ECDH
and `wc_ecc_make_pub()`, taking a 3-curve `ecc.o` from about 30 KB to 17 KB;
it extends to the SE05x port the exclusions `ecc.c` already applied to the
ATECC508A/608A, TA100, CryptoCell, SiLabs and KCAPI ports. Operations with no
hardware provider return `NOT_COMPILED_IN`: raw `wc_RsaFunction()`/
`wc_RsaDirect()`, RSA-PSS, and ECDH with a private key that is not resident
in the SE050 (PKCS#7 KARI included), and `wc_ecc_make_pub()`, which derives a
public key from an imported private scalar. In an `OPENSSL_EXTRA`
build the same applies to `EC_POINT_add()`, `EC_POINT_mul()` and
`ECDH_compute_key()`, which are built on the same curve arithmetic.
The Jacobian-to-affine conversion behind
`EC_POINT_get_affine_coordinates_GFp()` and `EC_POINT_invert()` remains but
always reports failure. Validation of an imported untrusted public key is
unaffected by either macro: rejecting the point at infinity and checking the
curve equation need no curve arithmetic, so both are still done on the host.
Both macros are documented in
`wolfcrypt/src/port/nxp/README_SE050.md` and `IDE/CRYPTOCELL/README.md`. by @SparkiDev
## Behavioral Changes
* **Behavioral change (`NO_SESSION_CACHE_REF` no longer disables the client
cache)**: the macro suppressed the `AddSession()` write to the ClientCache as
@@ -39,6 +66,24 @@
dimensions is rejected with `CACHE_MATCH_ERROR` instead of being copied in.
A saved cache from an older release cannot be restored by this one.
* **Behavioral change (CryptoCell RSA honours the padding scheme)**: the
CryptoCell arms in `RsaPublicEncryptEx()`/`RsaPrivateDecryptEx()` chose the
hardware on the operation direction and block type alone, so an OAEP, PSS or
unpadded request was handed to `CRYS_RSA_PKCS1v15_*` and served as PKCS#1
v1.5 under a different name. They now require `WC_RSA_PKCSV15_PAD` and
anything else falls through to the wolfCrypt software path, so RSA-PSS and
OAEP produce what the caller asked for. Two visible differences: an
application that both encrypted and decrypted through CryptoCell with a
non-v1.5 `pad_type` was interoperating with nothing but itself and now
changes wire format, and a private-key OAEP or PSS operation on a key pair
generated by `cc310_RSA_GenerateKeyPair()` now fails, because that generator
writes only the public half back into the `RsaKey` and the software path has
no `d` to work with. Compressed-point ECC import also builds again on the
ports that exclude `mp_sqrtmod_prime()`, which `HAVE_COMP_KEY` called
regardless. Verified on CryptoCell, where it was an implicit-declaration
compile error; the ATECC508A/608A gating is identical, and on the TA100 the
helper was declared without a definition, so that build failed at link.
## Post-Quantum Cryptography (PQC)
* Added opt-in per-key Falcon signing caches (`--enable-falcon=cache-key`, `cache-basis`), roughly doubling signing speed with the default integer fpr backend. by @Frauschi
@@ -62,6 +107,32 @@
error raised. `wc_AsconAEAD128_SetAD()` now returns `BAD_STATE_E` when the
associated data has already been set; it must be supplied in a single call.
* **Fix (ECC key marked as having a public key after a failed derivation)**:
`ecc_make_pub_ex()` promoted `ECC_PRIVATEKEY_ONLY` to `ECC_PRIVATEKEY`
whatever the outcome, so a failed `wc_ecc_make_pub(key, NULL)` left the key
claiming a public point it had never computed and a later export or verify
consumed empty ordinates. The promotion now happens only on success. This
was reachable wherever the derivation can fail: the ports that exclude it
(ATECC508A/608A, TA100, CryptoCell, SiLabs, KCAPI) and
`WOLF_CRYPTO_CB_ONLY_ECC` with no device registered, as well as a software
point multiply that simply fails.
* **Fix (compressed-point ECC import over-read the input buffer on
CryptoCell)**: `wc_ecc_import_x963()` rewrites `inLen` to the uncompressed
length and then hands the caller's own buffer to
`CRYS_ECPKI_BuildPublKeyFullCheck()`, telling CRYS the buffer holds about
twice the bytes a compressed point actually occupies. There is no
decompression on this port to build an uncompressed point from, so a
compressed point type is now rejected with `NOT_COMPILED_IN` before the
length is adjusted.
* **Fix (`make check` did not link on CryptoCell builds)**: three ECC API test
bodies in `tests/api/test_ecc.c` called `wc_ecc_mulmod()` and
`wc_ecc_point_is_at_infinity()`, which `ecc.c` excludes for the CryptoCell
port, so `unit.test` failed to link with undefined references. Their guards
now list `WOLFSSL_CRYPTOCELL` alongside the other ports that replace the
software curve arithmetic.
## Fixes
* ML-KEM and ML-DSA now keep the key's device id on their internal SHAKE hashing, so a registered crypto callback sees the SHAKE-256 Update and Final calls. by @Frauschi (PR 11544)

View File

@@ -31,6 +31,60 @@ The `IDE/CRYPTOCELL/main.c` example application provides a function to run the s
Note: All Cryptocell features are not supported. The wolfcrypt RSA API allows import and export of Private/Public keys in DER format. However, this is not possible with key pairs generated with Cryptocell because the importing/exporting Cryptocell keys has not been implemented yet.
## Build options
**`WOLFSSL_NO_RSA_SW`**
Builds RSA with no wolfCrypt software implementation: the software modular
exponentiation, the prime search behind `wc_MakeRsaKey()` and the software key
consistency check (`wc_CheckRsaKey()`, forced off along with
`WOLFSSL_RSA_KEY_CHECK`) are left out of the build, and CryptoCell performs
every RSA operation. When RSA-PSS is not enabled, the PKCS#1 padding
generation and the OAEP/PSS mask-generation and un-padding helpers are dropped
as well; on a CC310 build that takes `rsa.o` from roughly 12.8 KB to 6.1 KB.
This works because the CryptoCell arms in `rsa.c` already hand all four padded
operations to CRYS (`cc310_RsaPublicEncrypt()`, `cc310_RsaSSL_Sign()`,
`cc310_RsaPublicDecrypt()`, `cc310_RsaSSL_Verify()`), generate keys on-chip
with `cc310_RSA_GenerateKeyPair()`, and pad and unpad inside CRYS rather than
on the host.
The raw, unpadded operation (`wc_RsaFunction()` and `wc_RsaDirect()`) has no
CRYS equivalent and returns `NOT_COMPILED_IN`.
Keep in mind that the CryptoCell RSA offload is PKCS#1 v1.5 only. OAEP, PSS and
unpadded requests are not offloaded, so under this macro they have no provider
and return `NOT_COMPILED_IN`; without it they use the wolfCrypt software path,
which needs a key whose private material is in software (a key pair generated
by `cc310_RSA_GenerateKeyPair()` exports only its public part). Prefer PKCS#1
v1.5 on a CryptoCell build.
**`WOLFSSL_NO_ECC_SW`**
The ECC counterpart is accepted on CryptoCell but has no effect: `ecc.c` already
excludes the software ECC implementation - the projective point arithmetic, the
scalar multiplication, the software signer and ECDH, and `wc_ecc_make_pub()` -
for this port unconditionally, so there is nothing left for the macro to remove.
It is in the allow-list only so that a build setting both
`WOLFSSL_NO_RSA_SW` and `WOLFSSL_NO_ECC_SW` for a hardware-only public-key
target is not rejected. What the macro *does* rule out on any port is
`WOLFCRYPT_HAVE_ECCSI`, `WOLFCRYPT_HAVE_SAKKE` and
`WOLFSSL_PUBLIC_ECC_ADD_DBL`, and it drops `EC_POINT_add()`, `EC_POINT_mul()` and
`ECDH_compute_key()` from an `OPENSSL_EXTRA` build, the same way
`WOLFSSL_ATECC508A` does, leaving the Jacobian-to-affine conversion that
`EC_POINT_get_affine_coordinates_GFp()` falls back on present but always
reporting failure.
Independently of the macro, compressed-point import (`HAVE_COMP_KEY`) is now
rejected with `NOT_COMPILED_IN` on this port. `wc_ecc_import_x963()` hands
`CRYS_ECPKI_BuildPublKeyFullCheck()` the caller's buffer together with the
uncompressed length, which for a compressed point is about twice what the
buffer holds; there is no decompression on this port to build an uncompressed
point from, so the import fails up front instead.
Both macros are also available for the NXP SE05x port; see
`wolfcrypt/src/port/nxp/README_SE050.md`.
## Setup
### Setting up Nordic SDK with wolfSSL
1. Download the wolfSSL source code or a zip file from GitHub and place it under your SDK `InstallFolder/external/` directory. You can also copy or simlink to the source.

View File

@@ -1867,6 +1867,16 @@ int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group,
int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group,
WOLFSSL_EC_POINT *point)
{
#ifdef WOLFSSL_NO_ECC_SW
/* ecc_map() is part of the software point arithmetic that this build leaves
* out, so a Jacobian point cannot be converted here. Report failure, as
* wolfSSL_EC_POINT_is_at_infinity() does when its helper is compiled out;
* both callers treat a non-zero return as an error. */
(void)group;
(void)point;
WOLFSSL_MSG("ec_point_convert_to_affine compiled out");
return 1;
#else
int err = 0;
mp_digit mp = 0;
WC_DECLARE_VAR(modulus, mp_int, 1, 0);
@@ -1912,6 +1922,7 @@ int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group,
WC_FREE_VAR_EX(modulus, NULL, DYNAMIC_TYPE_BIGINT);
return err;
#endif /* WOLFSSL_NO_ECC_SW */
}
/* Get the affine coordinates of the EC point on a Prime curve.
@@ -2061,7 +2072,7 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group,
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC)
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
/* Add two points on the same together.
*
* @param [in] curveIdx Index of curve in ecc_set.
@@ -2560,7 +2571,7 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
return ret;
}
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !HAVE_SELFTEST &&
* !WOLFSSL_SP_MATH */
* !WOLFSSL_SP_MATH && !WOLFSSL_NO_ECC_SW */
/* Invert the point on the curve.
* (x, y) -> (x, -y) = (x, (prime - y) % prime)
@@ -5598,7 +5609,7 @@ int wolfSSL_ECDSA_verify(int type, const unsigned char *digest, int digestSz,
/* Start ECDH */
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
#if !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
/* Compute the shared secret (key) using ECDH.
*
* KDF not supported.
@@ -5708,7 +5719,7 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outLen,
}
return (int)len;
}
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC && !WOLFSSL_NO_ECC_SW */
/* End ECDH */

View File

@@ -844,7 +844,8 @@ int test_wc_ecc_shared_secret_ex_peer_point(void)
!defined(NO_ECC256) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(PLUTON_CRYPTO_ECC) && !defined(WOLFSSL_CRYPTOCELL) && \
!defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
!defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
!defined(WOLFSSL_NO_ECC_SW)
/* P-256 base point G, uncompressed X9.63 encoding. Not const: older
* wc_ecc_import_point_der() takes byte*. */
byte g[] = {
@@ -3165,7 +3166,8 @@ int test_wc_ecc_pointFns(void)
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
!defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
!defined(WOLFSSL_MICROCHIP_TA100)
!defined(WOLFSSL_MICROCHIP_TA100) && !defined(WOLFSSL_CRYPTOCELL) && \
!defined(WOLFSSL_NO_ECC_SW)
ecc_key key;
WC_RNG rng;
int ret;
@@ -3269,7 +3271,7 @@ int test_wc_ecc_shared_secret_ssh(void)
!defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(PLUTON_CRYPTO_ECC) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
!defined(WOLFSSL_MICROCHIP_TA100)
!defined(WOLFSSL_MICROCHIP_TA100) && !defined(WOLFSSL_NO_ECC_SW)
ecc_key key;
ecc_key key2;
WC_RNG rng;
@@ -3444,7 +3446,8 @@ int test_wc_ecc_mulmod(void)
defined(WOLFSSL_MICROCHIP_TA100) || \
defined(WOLFSSL_VALIDATE_ECC_IMPORT)) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(HAVE_SELFTEST) && \
!defined(HAVE_FIPS)
!defined(HAVE_FIPS) && !defined(WOLFSSL_CRYPTOCELL) && \
!defined(WOLFSSL_NO_ECC_SW)
ecc_key key1;
ecc_key key2;
ecc_key key3;
@@ -3700,7 +3703,8 @@ int test_wc_EccDecisionCoverage(void)
#if defined(HAVE_ECC) && !defined(WC_NO_RNG) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
!defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW)
WC_RNG rng;
ecc_key key;
int ret = WC_NO_ERR_TRACE(MEMORY_E);

View File

@@ -431,7 +431,7 @@ int test_wolfSSL_EC_POINT(void)
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC)
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
ExpectIntEQ(EC_POINT_add(NULL, NULL, NULL, NULL, ctx), 0);
ExpectIntEQ(EC_POINT_add(group, NULL, NULL, NULL, ctx), 0);
ExpectIntEQ(EC_POINT_add(NULL, new_point, NULL, NULL, ctx), 0);
@@ -514,16 +514,22 @@ int test_wolfSSL_EC_POINT(void)
ExpectNotNull(dup_point = EC_POINT_dup(set_point, group));
ExpectIntEQ(EC_POINT_cmp(group, dup_point, set_point, ctx), 0);
/* Test inverting */
/* Test inverting.
* Skipped under WOLFSSL_NO_ECC_SW: inverting a point whose z-ordinate is
* not one needs the Jacobian-to-affine conversion, which reports failure
* without the software point arithmetic. The block below that relies on
* new_point having been inverted is excluded by the same macro. */
#ifndef WOLFSSL_NO_ECC_SW
ExpectIntEQ(EC_POINT_invert(NULL, NULL, ctx), 0);
ExpectIntEQ(EC_POINT_invert(NULL, new_point, ctx), 0);
ExpectIntEQ(EC_POINT_invert(group, NULL, ctx), 0);
ExpectIntEQ(EC_POINT_invert(group, new_point, ctx), 1);
#endif
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC)
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
{
EC_POINT* orig_point = NULL;
ExpectNotNull(orig_point = EC_POINT_new(group));
@@ -544,7 +550,10 @@ int test_wolfSSL_EC_POINT(void)
}
#endif
/* Test getting affine converts from projective. */
/* Test getting affine converts from projective.
* Skipped under WOLFSSL_NO_ECC_SW: the conversion is built on ecc_map(),
* which that build leaves out, so the get below reports failure. */
#ifndef WOLFSSL_NO_ECC_SW
ExpectIntEQ(EC_POINT_copy(set_point, new_point), 1);
/* Force non-affine coordinates */
ExpectIntEQ(BN_add(new_point->Z, (WOLFSSL_BIGNUM*)BN_value_one(),
@@ -558,6 +567,7 @@ int test_wolfSSL_EC_POINT(void)
/* check if point ordinates have changed. */
ExpectIntNE(BN_cmp(X, set_point->X), 0);
ExpectIntNE(BN_cmp(Y, set_point->Y), 0);
#endif
/* Test check for infinity */
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
@@ -876,7 +886,7 @@ int test_wolfSSL_SPAKE(void)
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(WOLFSSL_ATECC508A) \
&& !defined(WOLFSSL_ATECC608A) && !defined(HAVE_SELFTEST) && \
!defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_MICROCHIP_TA100) && !defined(WOLFSSL_NO_ECC_SW) && \
!defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
BIGNUM* x = NULL; /* kdc priv */
BIGNUM* y = NULL; /* client priv */
@@ -1653,7 +1663,7 @@ int test_ECDH_compute_key(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_ECC256) && !defined(NO_ECC_SECP) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC)
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
EC_KEY* key1 = NULL;
EC_KEY* key2 = NULL;
EC_POINT* pub1 = NULL;

View File

@@ -421,7 +421,7 @@ int test_wc_CheckProbablePrime(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) && \
!defined(HAVE_FIPS) && defined(WC_RSA_BLINDING)
!defined(HAVE_FIPS) && defined(WC_RSA_BLINDING) && !defined(WOLFSSL_NO_RSA_SW)
#define CHECK_PROBABLE_PRIME_KEY_BITS 2048
RsaKey key;
WC_RNG rng;
@@ -1465,7 +1465,8 @@ int test_wc_RsaDecisionCoverage(void)
* that (newer) module honours these decisions and the harness gains coverage
* from it. */
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
!defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_SELFTEST)
!defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_SELFTEST) && \
!defined(WOLFSSL_NO_RSA_SW)
RsaKey key;
WC_RNG rng;
const char inStr[] = TEST_STRING;

View File

@@ -32,6 +32,10 @@
#undef WOLF_CRYPTO_CB_ONLY_CURVE448
#undef WOLF_CRYPTO_CB_ONLY_SLHDSA
#undef WOLF_CRYPTO_CB_ONLY_MLKEM
/* swdev is the software provider, so it needs the software implementations
* that these leave out of the library. */
#undef WOLFSSL_NO_RSA_SW
#undef WOLFSSL_NO_ECC_SW
#ifndef WOLF_CRYPTO_CB
#error "wc_swdev requires the main build to define WOLF_CRYPTO_CB"

View File

@@ -328,7 +328,8 @@ ECC Curve Sizes:
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
!defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB)
!defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \
!defined(WOLFSSL_NO_ECC_SW)
#undef HAVE_ECC_MAKE_PUB
#define HAVE_ECC_MAKE_PUB
#endif
@@ -1554,7 +1555,7 @@ static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
#if defined(HAVE_ECC_DHE) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC)
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
static int ecc_shared_secret_point(ecc_key* private_key, ecc_point* point,
byte* out, word32* outlen, int checkPoint);
#endif
@@ -1562,7 +1563,7 @@ static int ecc_shared_secret_point(ecc_key* private_key, ecc_point* point,
#ifdef HAVE_COMP_KEY
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_CRYPTOCELL)
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW)
#ifndef WOLFSSL_SP_MATH
#if !defined(SQRTMOD_USE_MOD_EXP)
@@ -2054,7 +2055,7 @@ static void alt_fp_init(mp_int* a)
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_CRYPTOCELL) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW) && \
(!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
defined(WOLFSSL_IMXRT1170_CAAM))
@@ -4890,8 +4891,13 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
if (private_key->keyIdSet)
err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
else
#ifdef WOLFSSL_NO_ECC_SW
/* No software ECDH compiled in, so there is nothing to fall back to. */
err = NOT_COMPILED_IN;
#else
err = ecc_shared_secret_point(private_key, &public_key->pubkey, out,
outlen, 0);
#endif
#else
/* No point check: the key got whatever its import ran, in full under
* WOLFSSL_VALIDATE_ECC_IMPORT. */
@@ -4907,7 +4913,7 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC)
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
byte* out, word32* outlen)
@@ -5522,6 +5528,9 @@ int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
!defined(WOLFSSL_CRYPTOCELL) && \
(!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
defined(WOLFSSL_IMXRT1170_CAAM))
/* Deliberately not excluded under WOLFSSL_NO_ECC_SW: this is two mp_iszero()
* calls, not curve arithmetic, and the untrusted public key validation below
* needs it. */
/* return 1 if point is at infinity, 0 if not, < 0 on error */
int wc_ecc_point_is_at_infinity(ecc_point* p)
{
@@ -5877,8 +5886,16 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
err = NOT_COMPILED_IN;
#endif /* HAVE_ECC_MAKE_PUB */
/* change key state if public part is cached */
if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
/* Change key state if the public part is cached. Only on success: a failed
* derivation (no software implementation compiled in, no device registered,
* or the point multiply itself failing) leaves key->pubkey empty, and
* marking the key ECC_PRIVATEKEY would have a later export or verify
* consume those empty ordinates. */
if ((err == MP_OKAY
#ifdef WOLFSSL_ASYNC_CRYPT
|| err == WC_NO_ERR_TRACE(WC_PENDING_E)
#endif
) && key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
key->type = ECC_PRIVATEKEY;
}
@@ -7355,7 +7372,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
!defined(WOLFSSL_NO_ECC_SW)
#ifndef WOLFSSL_SP_MATH
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
ecc_curve_spec* curve, mp_int* e, mp_int* r,
@@ -8780,6 +8798,7 @@ int wc_ecc_free(ecc_key* key)
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
!defined(WOLFSSL_NO_ECC_SW) && \
(!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
defined(WOLFSSL_IMXRT1170_CAAM))
/* Set a point to the representation of infinity, (0, 0, 1). */
@@ -8965,7 +8984,7 @@ int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW) && \
!defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
#ifdef ECC_SHAMIR
@@ -10509,7 +10528,12 @@ int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
else
#endif
#endif
#if !defined(WOLFSSL_SP_MATH)
/* Recovering y needs mp_sqrtmod_prime(), which is only compiled in
* alongside the rest of the software ECC math. Ports that replace it fall
* to the #else below rather than calling a function that is not there. */
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW)
{
int did_init = 0;
#ifdef WOLFSSL_SMALL_STACK
@@ -11758,10 +11782,16 @@ static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
}
if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
#ifdef HAVE_COMP_KEY
compressed = 1;
#else
#ifndef HAVE_COMP_KEY
err = NOT_COMPILED_IN;
#elif defined(WOLFSSL_CRYPTOCELL)
/* CRYS_ECPKI_BuildPublKeyFullCheck() below is handed the caller's own
* buffer together with the uncompressed length derived here, so a
* compressed point would have CRYS read past the end of a buffer that
* only holds the x ordinate. */
err = NOT_COMPILED_IN;
#else
compressed = 1;
#endif
}
@@ -11822,7 +11852,13 @@ static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
#ifdef HAVE_COMP_KEY
if (err == MP_OKAY && compressed == 1) { /* build y */
#if !defined(WOLFSSL_SP_MATH)
/* Recovering y needs mp_sqrtmod_prime(), which is only compiled in alongside
* the rest of the software ECC math. Ports that replace it use the SP
* uncompress helpers below, or fail with WC_KEY_SIZE_E when those are absent
* too. */
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW)
#ifdef WOLFSSL_SMALL_STACK
mp_int* t1 = NULL;
mp_int* t2 = NULL;
@@ -11915,6 +11951,10 @@ static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
wc_ecc_curve_free(curve);
FREE_CURVE_SPECS();
#else
/* The SP helpers only exist when SP ECC is compiled in; without them (a
* hardware port with no software math and no SP) there is no way to
* recover y. */
#ifdef WOLFSSL_HAVE_SP_ECC
#ifndef WOLFSSL_SP_NO_256
if (key->dp->id == ECC_SECP256R1) {
err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
@@ -11942,6 +11982,7 @@ static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
}
else
#endif
#endif /* WOLFSSL_HAVE_SP_ECC */
{
err = WC_KEY_SIZE_E;
}
@@ -11999,6 +12040,9 @@ static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
if (err == MP_OKAY)
err = wc_ecc_check_key(key);
#endif
/* Deliberately not excluded under WOLFSSL_NO_ECC_SW: both checks below are
* plain modular arithmetic that stays compiled in, so an untrusted peer key is
* still rejected on the host rather than relying on the hardware to do it. */
#if (!defined(WOLFSSL_VALIDATE_ECC_IMPORT) || \
!defined(HAVE_ECC_CHECK_PUBKEY_ORDER)) && \
!defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
@@ -16896,7 +16940,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#ifdef HAVE_COMP_KEY
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_CRYPTOCELL)
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW)
#ifndef WOLFSSL_SP_MATH
#if !defined(SQRTMOD_USE_MOD_EXP)

View File

@@ -307,6 +307,139 @@ regardless of `keyIdSet`. The SE050 port's "import a software key into the
SE050 on first use" behavior is disabled under this macro, so a software key is
never silently moved into hardware.
**`WOLFSSL_NO_RSA_SW`**
Builds RSA with no wolfCrypt software implementation at all: the software
modular exponentiation (including the SP and non-blocking variants and the
800-56B input bounds check), the prime search behind `wc_MakeRsaKey()` and the
software key consistency check (`wc_CheckRsaKey()`, which is forced off along
with `WOLFSSL_RSA_KEY_CHECK`) are left out of the build, and every RSA
operation is performed by the SE050. The macro is not SE050-specific; the rest
of this section describes what it means for the SE050.
Requires an RSA hardware implementation that pads in hardware and generates
keys on-chip: `WOLFSSL_SE050` without `WOLFSSL_SE050_NO_RSA`, or Arm
CryptoCell-310 (`WOLFSSL_CRYPTOCELL`, documented in
`IDE/CRYPTOCELL/README.md`). It is rejected at
compile time together with `WOLFSSL_SE050_ONLY_KEY_ID` and
`WOLFSSL_SE050_NO_RSA_VERIFY` (both route some operations to wolfCrypt
software by design), `WOLF_CRYPTO_CB_ONLY_RSA`, `WC_RSA_NONBLOCK` and
asynchronous RSA.
Still available: PKCS#1 v1.5 sign/verify, public encrypt and private decrypt
with PKCS#1 v1.5 or OAEP padding, key generation inside the SE050, the key
insert/use-by-ID helpers, DER encode/decode, `wc_RsaEncryptSize()` and
`wc_RsaFlattenPublicKey()`/`wc_RsaExportKey()`.
Not available: the raw, unpadded operation (`wc_RsaFunction()` and
`wc_RsaDirect()`) and RSA-PSS. The SE050 PSS API hashes the message itself, so
it cannot serve wolfCrypt's sign-a-digest PSS interface; both return
`NOT_COMPILED_IN`. TLS 1.3 authenticates RSA certificates with RSA-PSS, so a
TLS 1.3 build still compiles but any RSA handshake fails at run time; use ECC
certificates for TLS 1.3, and TLS 1.2 (or wolfCrypt on its own) for RSA.
The PKCS#1 v1.5 un-pad helper (`wc_RsaUnPad_ex()`) stays in the build: the
SE050 verify path performs the raw public operation in hardware and unpads on
the host so that `wc_RsaSSL_Verify()` can hand the decoded DigestInfo back to
the caller.
For the smallest build, also configure RSA-PSS out (`--disable-rsapss`, which
in turn needs `--disable-tls13`). With `WC_RSA_PSS` undefined, `rsa.c` drops
the padding generation and the OAEP/PSS mask-generation and un-padding helpers
as well, roughly halving its object size; with RSA-PSS enabled those stay
compiled in even though the operation has no provider. For the same reason do
not select an SP variant that includes RSA (`--enable-sp=yes`,
`--enable-sp=rsa2048`, ...) - the SP RSA code would only be dead weight.
**`WOLFSSL_NO_ECC_SW`**
The ECC counterpart of `WOLFSSL_NO_RSA_SW`. Builds ECC with no wolfCrypt
software implementation: the projective point add/double and mapping, the
scalar multiplication (including Shamir's trick, used only by the software
verify), the software signer, the software ECDH and the software derivation of
a public key from a private scalar are all left out, and every keyed ECC
operation is performed by the SE050.
`ecc.c` already excludes that code for the ATECC508A/608A, TA100, CryptoCell,
SiLabs and KCAPI ports and for `WOLF_CRYPTO_CB_ONLY_ECC`; this macro extends
the same treatment to the SE05x port, which offloads every keyed ECC operation
but otherwise still compiled the software curve math. On a 3-curve build
(P-256/P-384/P-521) that takes `ecc.o` from roughly 30 KB to 17 KB. The macro
does not remove the SP ECC code, so also select an SP variant without ECC if
that is compiled in - otherwise it stays as dead weight.
Requires `WOLFSSL_SE050` (or `WOLFSSL_CRYPTOCELL`, where the exclusions are
already unconditional, so the macro is accepted but changes nothing). It is
rejected at compile time together with `WOLFSSL_SE050_ONLY_KEY_ID`,
`WOLFSSL_SE050_NO_ECDHE` (which also puts key generation back in software),
`WOLFSSL_SE050_NO_ECDSA_VERIFY`, `WOLF_CRYPTO_CB_ONLY_ECC` and asynchronous
ECC.
The library and the application must be built with the same setting. Unlike the
other macros in this section, this one is visible in a public header:
`wolfssl/wolfcrypt/ecc.h` aliases `wc_ecc_shared_secret_ssh()` to
`wc_ecc_shared_secret()` when it is defined and to `wc_ecc_shared_secret_ex()`
when it is not, and those two take a different second argument type. There is
no `./configure` option for it, so a generated `wolfssl/options.h` does not
record it - put it in the `user_settings.h` that both the library and the
application compile against.
Still available: ECDSA sign and verify, ECDH between an SE050-resident private
key and a peer public key, key generation inside the SE050, the key
insert/use-by-ID helpers, x963 and DER key import/export, the raw key
accessors, `wc_ecc_size()`/`wc_ecc_sig_size()` and the curve lookups.
Not available, the same way they are absent on the ports listed above. Where a
`NOT_COMPILED_IN` return is called out the function is still there and reports
that; the rest are not compiled at all, and since their prototypes are
unguarded a caller gets an undefined reference at link time.
- `wc_ecc_make_pub()`/`wc_ecc_make_pub_ex()` - deriving `Q = d*G` for an
imported bare private key needs the software base-point multiply. These stay
in the build and return `NOT_COMPILED_IN`, which is what they already do on
the ports listed above.
- ECDH where the private key is *not* resident in the SE050 (`keyIdSet == 0`,
for example one decoded from DER). The software fallback in
`wc_ecc_shared_secret()` returns `NOT_COMPILED_IN` instead. **This includes
PKCS#7 KARI** (`wc_PKCS7_EncodeEnvelopedData()` /
`wc_PKCS7_DecodeEnvelopedData()` with a key-agreement RecipientInfo), which
derives with an ephemeral key decoded from DER, and ECIES
(`wc_ecc_encrypt()`/`wc_ecc_decrypt()`) whenever the key it derives with is
not SE050-resident.
- The public APIs over the curve arithmetic: `wc_ecc_mulmod()`,
`wc_ecc_mulmod_ex()`,
`wc_ecc_shared_secret_ex()` (`wc_ecc_shared_secret_ssh()` aliases to
`wc_ecc_shared_secret()` as it already does for those ports) and
`wc_ecc_check_key()`'s public-key order check.
- Compressed-point import (`HAVE_COMP_KEY`) unless SP ECC provides the
uncompress helper for the curve; otherwise it returns `WC_KEY_SIZE_E`.
- In an `OPENSSL_EXTRA` build, `EC_POINT_add()`, `EC_POINT_mul()` and
`ECDH_compute_key()`, which are built on the same curve arithmetic. They are
dropped as they already are for the ATECC ports, so an application calling
them fails to link. `EC_POINT_is_at_infinity()` keeps working. The
Jacobian-to-affine conversion that
`EC_POINT_get_affine_coordinates_GFp()` and `EC_POINT_invert()` fall back on
for a point whose z-ordinate is not one is built on `ecc_map()`, so it is
still there but always reports failure, which is what it already does under
`WOLF_CRYPTO_CB_ONLY_ECC`.
`WOLFCRYPT_HAVE_ECCSI`, `WOLFCRYPT_HAVE_SAKKE`, `WOLFSSL_PUBLIC_ECC_ADD_DBL`
and `WC_ECC_NONBLOCK` are rejected at compile time: all four are built directly
on the software point arithmetic and have no hardware path to fall back to.
Public-key point validation is **not** affected by this macro. Importing an
untrusted public key (`wc_ecc_import_x963()`, `wc_ecc_import_x963_ex()`, and
the peer key-share and ECDHE paths in TLS that call them) still rejects the
point at infinity and still checks that the point satisfies the curve equation
before the key is used, as SP 800-56A Rev. 3 sections 5.6.2.3.3 and 5.6.2.3.4
require. Neither check needs the software curve arithmetic: the first is a pair
of `mp_iszero()` calls and the second evaluates `y^2 = x^3 + ax + b mod p`
directly, so both stay compiled in and an invalid peer point is rejected on the
host before it ever reaches the SE05x. That is a deliberate difference from the
ATECC508A/608A and CryptoCell ports, which keep their public keys in a raw
hardware buffer rather than as `mp_int` ordinates and so cannot run these
checks.
## wolfSSL HostCrypto Support
The NXP SE05x Plug & Trust Middleware by default can use either OpenSSL or

View File

@@ -116,6 +116,7 @@ RSA keys can be used to encrypt, decrypt, sign and verify data.
* WOLFSSL_AFALG_XILINX_RSA: AF_ALG Xilinx RSA acceleration default: off
* WOLFSSL_SE050_NO_RSA: Disable SE050 RSA default: off
* WOLFSSL_XILINX_CRYPT: Xilinx crypto RSA acceleration default: off
* WOLFSSL_NO_RSA_SW: No software RSA, hardware only default: off
*/
@@ -139,6 +140,22 @@ RSA keys can be used to encrypt, decrypt, sign and verify data.
}
#endif
/* The software padding generation (and with it the OAEP/PSS mask generation
* and un-padding helpers) is only reachable when an RSA operation can fall
* through to the software implementation. WOLFSSL_NO_RSA_SW removes that
* fall-through, so drop the padding layer too - apart from the PKCS#1 v1.5
* un-pad helper, which the SE050 verify path calls to hand the decoded
* DigestInfo back to the caller. (CryptoCell unpads inside CRYS and does not
* need it, but it is small and shared with every other build.)
*
* RSA-PSS is the exception: neither backend serves wolfCrypt's PSS interface,
* which hands over a pre-computed digest (the SE050 API hashes the input
* itself; the CryptoCell dispatch only does PKCS#1 v1.5), so a build that
* enables RSA-PSS keeps the whole padding layer. */
#if defined(WOLFSSL_NO_RSA_SW) && !defined(WC_RSA_PSS)
#define WOLFSSL_NO_RSA_SW_PAD
#endif
enum {
RSA_STATE_NONE = 0,
@@ -1065,7 +1082,8 @@ int wc_CheckRsaKey(RsaKey* key)
#endif /* WOLFSSL_RSA_KEY_CHECK */
#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_PSS)
#if (!defined(WC_NO_RSA_OAEP) || defined(WC_RSA_PSS)) && \
!defined(WOLFSSL_NO_RSA_SW_PAD)
/* Uses MGF1 standard as a mask generation function
hType: hash type used
seed: seed to use for generating mask
@@ -1361,11 +1379,11 @@ static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out,
return ret;
}
#endif /* !WC_NO_RSA_OAEP || WC_RSA_PSS */
#endif /* (!WC_NO_RSA_OAEP || WC_RSA_PSS) && !WOLFSSL_NO_RSA_SW_PAD */
/* Padding */
#ifndef WOLFSSL_RSA_VERIFY_ONLY
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_NO_RSA_SW_PAD)
#ifndef WC_NO_RNG
#ifndef WC_NO_RSA_OAEP
static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
@@ -1843,11 +1861,12 @@ int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
return ret;
}
#endif /* WOLFSSL_RSA_VERIFY_ONLY */
#endif /* !WOLFSSL_RSA_VERIFY_ONLY && !WOLFSSL_NO_RSA_SW_PAD */
/* UnPadding */
#if !defined(WC_NO_RSA_OAEP) && !defined(NO_HASH_WRAPPER)
#if !defined(WC_NO_RSA_OAEP) && !defined(NO_HASH_WRAPPER) && \
!defined(WOLFSSL_NO_RSA_SW_PAD)
/* UnPad plaintext, set start to *output, return length of plaintext,
* < 0 on error */
static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
@@ -2225,7 +2244,7 @@ int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
padValue);
break;
#ifndef WC_NO_RSA_OAEP
#if !defined(WC_NO_RSA_OAEP) && !defined(WOLFSSL_NO_RSA_SW_PAD)
case WC_RSA_OAEP_PAD:
WOLFSSL_MSG("wolfSSL Using RSA OAEP un-padding");
ret = RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out,
@@ -2855,7 +2874,7 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
}
#else
#ifndef WOLF_CRYPTO_CB_ONLY_RSA
#if !defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLFSSL_NO_RSA_SW)
#ifdef WOLFSSL_HAVE_SP_RSA
static int RsaFunction_SP(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
@@ -3340,7 +3359,7 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
return RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
#endif /* WOLFSSL_SP_MATH */
} /* wc_RsaFunctionSync */
#endif /* WOLF_CRYPTO_CB_ONLY_RSA */
#endif /* !WOLF_CRYPTO_CB_ONLY_RSA && !WOLFSSL_NO_RSA_SW */
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
@@ -3615,7 +3634,7 @@ int cc310_RsaSSL_Verify(const byte* in, word32 inLen, byte* sig,
}
#endif /* WOLFSSL_CRYPTOCELL */
#ifndef WOLF_CRYPTO_CB_ONLY_RSA
#if !defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLFSSL_NO_RSA_SW)
#if !defined(NO_RSA_BOUNDS_CHECK)
/* Check that 1 < in < n-1. (Requirement of 800-56B.) */
int RsaFunctionCheckIn(const byte* in, word32 inLen, RsaKey* key,
@@ -3664,13 +3683,15 @@ int RsaFunctionCheckIn(const byte* in, word32 inLen, RsaKey* key,
return ret;
}
#endif /* !NO_RSA_BOUNDS_CHECK */
#endif /* WOLF_CRYPTO_CB_ONLY_RSA */
#endif /* !WOLF_CRYPTO_CB_ONLY_RSA && !WOLFSSL_NO_RSA_SW */
static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng,
int checkSmallCt)
{
#if !defined(WOLFSSL_NO_RSA_SW) || defined(WOLF_CRYPTO_CB)
int ret = 0;
#endif
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
RsaPadding padding;
#endif
@@ -3714,7 +3735,13 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
}
#endif
#ifdef WOLF_CRYPTO_CB_ONLY_RSA
#ifdef WOLFSSL_NO_RSA_SW
/* No software modular exponentiation is compiled in. The hardware
* implementation is driven from RsaPublicEncryptEx()/RsaPrivateDecryptEx()
* with the padding it performs itself, so the raw operation offered by
* wc_RsaFunction()/wc_RsaDirect() has no provider here. */
return NOT_COMPILED_IN;
#elif defined(WOLF_CRYPTO_CB_ONLY_RSA)
return NO_VALID_DEVID;
#else /* !WOLF_CRYPTO_CB_ONLY_RSA */
@@ -3795,7 +3822,7 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
wc_RsaCleanup(key);
}
return ret;
#endif /* !WOLF_CRYPTO_CB_ONLY_RSA */
#endif /* !WOLFSSL_NO_RSA_SW && !WOLF_CRYPTO_CB_ONLY_RSA */
}
int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
@@ -3893,13 +3920,23 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
}
}
#elif defined(WOLFSSL_CRYPTOCELL)
/* CRYS does the padding itself and only implements PKCS#1 v1.5, so
* only a v1.5 request may be offloaded. OAEP, PSS and unpadded
* requests fall through to the software path - handing them to
* CRYS_RSA_PKCS1v15_* would apply v1.5 padding while the caller asked
* for something else. Note that a key generated by
* cc310_RSA_GenerateKeyPair() holds only the public part in software,
* so a private-key operation on such a key fails on the software path
* rather than silently producing v1.5 output. */
if (rsa_type == RSA_PUBLIC_ENCRYPT &&
pad_value == RSA_BLOCK_TYPE_2) {
pad_value == RSA_BLOCK_TYPE_2 &&
pad_type == WC_RSA_PKCSV15_PAD) {
return cc310_RsaPublicEncrypt(in, inLen, out, outLen, key);
}
else if (rsa_type == RSA_PRIVATE_ENCRYPT &&
pad_value == RSA_BLOCK_TYPE_1) {
pad_value == RSA_BLOCK_TYPE_1 &&
pad_type == WC_RSA_PKCSV15_PAD) {
return cc310_RsaSSL_Sign(in, inLen, out, outLen, key,
cc310_hashModeRSA(hash, 0));
}
@@ -3947,6 +3984,22 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
}
#endif /* RSA CRYPTO HW */
#ifdef WOLFSSL_NO_RSA_SW_PAD
/* Hardware only build with no software padding compiled in: whatever
* the hardware dispatch above did not take has no provider here, the
* same way wc_RsaFunction() has none. Not every hardware arm consumes
* the padding arguments, so discard them all here. */
(void)pad_type;
(void)hash;
(void)mgf;
(void)label;
(void)labelSz;
(void)saltLen;
(void)rng;
ret = NOT_COMPILED_IN;
break;
#else
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
if (key->devId != INVALID_DEVID) {
XMEMSET(&padding, 0, sizeof(RsaPadding));
@@ -3995,6 +4048,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
}
FALL_THROUGH;
#endif /* !WOLFSSL_NO_RSA_SW_PAD */
case RSA_STATE_ENCRYPT_RES:
ret = (int)key->dataLen;
@@ -4048,7 +4102,9 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
WC_RNG* rng)
{
int ret = WC_NO_ERR_TRACE(RSA_WRONG_TYPE_E);
#ifndef WOLFSSL_NO_RSA_SW_PAD
byte* pad = NULL;
#endif
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
RsaPadding padding;
#endif
@@ -4083,15 +4139,18 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
}
}
#elif defined(WOLFSSL_CRYPTOCELL)
/* PKCS#1 v1.5 only - see the matching note in RsaPublicEncryptEx(). */
if (rsa_type == RSA_PRIVATE_DECRYPT &&
pad_value == RSA_BLOCK_TYPE_2) {
pad_value == RSA_BLOCK_TYPE_2 &&
pad_type == WC_RSA_PKCSV15_PAD) {
ret = cc310_RsaPublicDecrypt(in, inLen, out, outLen, key);
if (outPtr != NULL)
*outPtr = out; /* for inline */
return ret;
}
else if (rsa_type == RSA_PUBLIC_DECRYPT &&
pad_value == RSA_BLOCK_TYPE_1) {
pad_value == RSA_BLOCK_TYPE_1 &&
pad_type == WC_RSA_PKCSV15_PAD) {
return cc310_RsaSSL_Verify(in, inLen, out, key,
cc310_hashModeRSA(hash, 0));
}
@@ -4144,6 +4203,21 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
}
#endif /* RSA CRYPTO HW */
#ifdef WOLFSSL_NO_RSA_SW_PAD
/* Hardware only build with no software padding compiled in: whatever
* the hardware dispatch above did not take has no provider here, the
* same way wc_RsaFunction() has none. Not every hardware arm consumes
* the padding arguments, so discard them all here. */
(void)pad_type;
(void)hash;
(void)mgf;
(void)label;
(void)labelSz;
(void)saltLen;
(void)rng;
ret = NOT_COMPILED_IN;
break;
#else
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE) && \
!defined(WOLFSSL_NO_MALLOC)
@@ -4298,6 +4372,7 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
key->state = RSA_STATE_DECRYPT_RES;
FALL_THROUGH;
#endif /* !WOLFSSL_NO_RSA_SW_PAD */
case RSA_STATE_DECRYPT_RES:
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
@@ -5311,6 +5386,7 @@ int wc_RsaExportKey(const RsaKey* key,
#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
#ifndef WOLFSSL_NO_RSA_SW
/* Check that |p-q| > 2^((size/2)-100) */
static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size, int* valid)
{
@@ -5431,6 +5507,7 @@ static const byte lower_bound[] = {
0x4D, 0x7C, 0x60, 0xA5, 0xE6, 0x33, 0xE3, 0xE1
/* 4096 */
};
#endif /* !WOLFSSL_NO_RSA_SW */
/* returns 1 on key size ok and 0 if not ok */
@@ -5470,6 +5547,7 @@ static WC_INLINE int RsaSizeCheck(int size)
}
#ifndef WOLFSSL_NO_RSA_SW
static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen,
int* isPrime, WC_RNG* rng)
{
@@ -5686,6 +5764,7 @@ int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz,
return wc_CheckProbablePrime_ex(pRaw, pRawSz, qRaw, qRawSz,
eRaw, eRawSz, nlen, isPrime, NULL);
}
#endif /* !WOLFSSL_NO_RSA_SW */
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))

View File

@@ -969,7 +969,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sm4_test(void);
#ifdef WOLFSSL_PUF
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t puf_test(void);
#endif
#ifdef WC_RSA_NO_PADDING
#if defined(WC_RSA_NO_PADDING) && !defined(WOLFSSL_NO_RSA_SW)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_no_pad_test(void);
#endif
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void);
@@ -3285,7 +3285,7 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
#endif
#if !defined(NO_RSA) && !defined(HAVE_RENESAS_SYNC)
#ifdef WC_RSA_NO_PADDING
#if defined(WC_RSA_NO_PADDING) && !defined(WOLFSSL_NO_RSA_SW)
if ( (ret = rsa_no_pad_test()) != 0)
TEST_FAIL("RSA NOPAD test failed!\n", ret);
else
@@ -36290,11 +36290,62 @@ done:
}
#endif
#ifdef WOLFSSL_NO_RSA_SW
/* WOLFSSL_NO_RSA_SW leaves out the software modular exponentiation, so the raw
* (unpadded) operation behind wc_RsaFunction()/wc_RsaDirect() has no provider:
* the hardware is driven from the padded entry points instead. Check it reports
* that rather than, say, running with an uninitialized result buffer. */
static wc_test_ret_t rsa_no_sw_test(RsaKey* key)
{
wc_test_ret_t ret;
int keySz;
word32 outLen;
WC_DECLARE_VAR(in, byte, RSA_TEST_BYTES, HEAP_HINT);
WC_DECLARE_VAR(out, byte, RSA_TEST_BYTES, HEAP_HINT);
WC_ALLOC_VAR(in, byte, RSA_TEST_BYTES, HEAP_HINT);
WC_ALLOC_VAR(out, byte, RSA_TEST_BYTES, HEAP_HINT);
#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
if (in == NULL || out == NULL)
ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), exit_rsa_no_sw);
#endif
keySz = wc_RsaEncryptSize(key);
if (keySz <= 0 || keySz > (int)RSA_TEST_BYTES)
ERROR_OUT(WC_TEST_RET_ENC_NC, exit_rsa_no_sw);
XMEMSET(in, 1, (size_t)keySz);
XMEMSET(out, 0, (size_t)keySz);
outLen = (word32)keySz;
ret = (wc_test_ret_t)wc_RsaFunction(in, (word32)keySz, out, &outLen,
RSA_PUBLIC_ENCRYPT, key, NULL);
/* A registered crypto callback is consulted first, but the example one in
* this test has no software implementation behind it either: it returns
* NOT_COMPILED_IN, wc_CryptoCb_Rsa() turns that into CRYPTOCB_UNAVAILABLE
* and wc_RsaFunction_ex() then takes the same no-software exit. So the
* result is NOT_COMPILED_IN whichever way the call was routed. */
if (ret != WC_NO_ERR_TRACE(NOT_COMPILED_IN))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa_no_sw);
ret = 0;
exit_rsa_no_sw:
WC_FREE_VAR(in, HEAP_HINT);
WC_FREE_VAR(out, HEAP_HINT);
return ret;
}
#endif /* WOLFSSL_NO_RSA_SW */
#if defined(WC_RSA_PSS) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0)) && \
!defined(WC_NO_RNG)
/* Need to create known good signatures to test with this. */
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
!defined(WOLFSSL_NO_RSA_SW) && \
(!defined(WOLF_CRYPTO_CB_ONLY_RSA) || defined(WOLFSSL_SWDEV))
static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key)
{
@@ -36635,7 +36686,7 @@ exit_rsa_pss:
#endif /* WC_RSA_PSS && (!HAVE_FIPS || FIPS_VERSION_GE(5,0)) && !WC_NO_RNG */
#ifdef WC_RSA_NO_PADDING
#if defined(WC_RSA_NO_PADDING) && !defined(WOLFSSL_NO_RSA_SW)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_no_pad_test(void)
{
WC_RNG rng;
@@ -39078,11 +39129,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void)
ta100_rsa_pss_only:
#endif
#ifdef WOLFSSL_NO_RSA_SW
ret = rsa_no_sw_test(key);
if (ret != 0)
goto exit_rsa;
#endif
#if defined(WC_RSA_PSS) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0)) && \
!defined(WC_NO_RNG)
/* Need to create known good signatures to test with this. */
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
!defined(WOLFSSL_NO_RSA_SW) && \
(!defined(WOLF_CRYPTO_CB_ONLY_RSA) || defined(WOLFSSL_SWDEV))
ret = rsa_pss_test(&rng, key);
if (ret != 0)
@@ -49089,14 +49147,17 @@ static wc_test_ret_t ecc_test_make_pub(WC_RNG* rng)
if (pubPoint == NULL) {
ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
}
#if !defined(WOLFSSL_CRYPTOCELL)
/* WOLFSSL_NO_ECC_SW leaves out the software base-point multiply, so
* ecc_make_pub_ex() reports NOT_COMPILED_IN the same way it does for
* CryptoCell. The fresh key made below covers the rest of this test. */
#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_NO_ECC_SW)
ret = wc_ecc_make_pub(key, pubPoint);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
#endif /* !WOLFSSL_CRYPTOCELL */
#endif /* !WOLFSSL_CRYPTOCELL && !WOLFSSL_NO_ECC_SW */
TEST_SLEEP();
#ifdef HAVE_ECC_KEY_EXPORT
@@ -50449,7 +50510,7 @@ done:
#if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
!defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP)
!defined(WOLFSSL_MICROCHIP) && !defined(WOLFSSL_NO_ECC_SW)
static wc_test_ret_t ecc_mulmod_test(ecc_key* key1)
{
wc_test_ret_t ret;
@@ -50555,7 +50616,8 @@ done:
defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(PLUTON_CRYPTO_ECC) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_MICROCHIP_TA100)
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_MICROCHIP_TA100) && \
!defined(WOLFSSL_NO_ECC_SW)
static wc_test_ret_t ecc_ssh_test(ecc_key* key, WC_RNG* rng)
{
wc_test_ret_t ret;
@@ -50653,7 +50715,8 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng)
#if defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(PLUTON_CRYPTO_ECC) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_MICROCHIP)
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_MICROCHIP) && \
!defined(WOLFSSL_NO_ECC_SW)
ret = ecc_ssh_test(key, rng);
if (ret < 0)
goto done;
@@ -50708,7 +50771,7 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng)
#if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
!defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP)
!defined(WOLFSSL_MICROCHIP) && !defined(WOLFSSL_NO_ECC_SW)
ret = ecc_mulmod_test(key);
if (ret < 0)
goto done;
@@ -52913,11 +52976,103 @@ done:
#endif /* WOLFSSL_SE050 && WOLFSSL_SE050_ONLY_KEY_ID && sign && verify &&
* key export */
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_NO_ECC_SW) && \
defined(HAVE_ECC_DHE) && \
(!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
defined(HAVE_ECC_KEY_IMPORT)
/* WOLFSSL_NO_ECC_SW leaves out the software scalar multiplication, so ECDH can
* only be served for a private key that is resident in the hardware. A key
* imported into software (keyIdSet == 0, as when one is decoded from DER for
* PKCS#7 KARI) is the case the software fallback in wc_ecc_shared_secret()
* used to cover, and must now say it has no provider rather than return an
* uninitialized secret. Guarded to WOLFSSL_SE050 because that keyIdSet test,
* and so the NOT_COMPILED_IN below, is specific to the SE050 arm of
* wc_ecc_shared_secret(). NIST CAVS P-256 values, the key material is
* arbitrary here. */
static wc_test_ret_t ecc_no_sw_test(void)
{
wc_test_ret_t ret;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
ecc_key* privKey = (ecc_key*)XMALLOC(sizeof(*privKey), HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
ecc_key* pubKey = (ecc_key*)XMALLOC(sizeof(*pubKey), HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
#else
ecc_key privKey[1];
ecc_key pubKey[1];
#endif
int privInit = 0, pubInit = 0;
byte out[MAX_ECC_BYTES];
word32 outLen = (word32)sizeof(out);
WOLFSSL_SMALL_STACK_STATIC const char* dIUT =
"7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534";
WOLFSSL_SMALL_STACK_STATIC const char* QIUTx =
"ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230";
WOLFSSL_SMALL_STACK_STATIC const char* QIUTy =
"28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141";
WOLFSSL_SMALL_STACK_STATIC const char* QCAVSx =
"700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287";
WOLFSSL_SMALL_STACK_STATIC const char* QCAVSy =
"db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac";
ret = 0;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
if ((privKey == NULL) || (pubKey == NULL))
ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), done);
#endif
ret = wc_ecc_init_ex(privKey, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
privInit = 1;
ret = wc_ecc_init_ex(pubKey, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
pubInit = 1;
ret = wc_ecc_import_raw(privKey, QIUTx, QIUTy, dIUT, "SECP256R1");
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
ret = wc_ecc_import_raw(pubKey, QCAVSx, QCAVSy, NULL, "SECP256R1");
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
ret = (wc_test_ret_t)wc_ecc_shared_secret(privKey, pubKey, out, &outLen);
if (ret != WC_NO_ERR_TRACE(NOT_COMPILED_IN))
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
ret = 0;
done:
if (pubInit)
wc_ecc_free(pubKey);
if (privInit)
wc_ecc_free(privKey);
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
XFREE(pubKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
#endif /* WOLFSSL_NO_ECC_SW && HAVE_ECC_DHE && ECC256 && HAVE_ECC_KEY_IMPORT */
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void)
{
wc_test_ret_t ret;
WC_RNG rng;
WOLFSSL_ENTER("ecc_test");
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_NO_ECC_SW) && \
defined(HAVE_ECC_DHE) && \
(!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
defined(HAVE_ECC_KEY_IMPORT)
ret = ecc_no_sw_test();
if (ret != 0)
return ret;
#endif
#if defined(ECC_MIN_KEY_SZ)
WOLFSSL_MSG_EX("ecc_test ECC_MIN_KEY_SZ = %d\n", ECC_MIN_KEY_SZ);
#else
@@ -79432,7 +79587,8 @@ static wc_test_ret_t pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256) && \
defined(HAVE_ECC) && defined(WOLFSSL_SHA512) && \
defined(HAVE_AES_KEYWRAP) && defined(HAVE_X963_KDF)
defined(HAVE_AES_KEYWRAP) && defined(HAVE_X963_KDF) && \
!defined(WOLFSSL_NO_ECC_SW)
byte optionalUkm[] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
};
@@ -79541,7 +79697,10 @@ static wc_test_ret_t pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz,
#endif
/* key agreement key encryption technique*/
#if defined(HAVE_ECC) && defined(HAVE_AES_KEYWRAP) && defined(HAVE_X963_KDF)
/* KARI derives with a private key decoded from DER, so it needs the software
* ECDH that WOLFSSL_NO_ECC_SW leaves out. */
#if defined(HAVE_ECC) && defined(HAVE_AES_KEYWRAP) && \
defined(HAVE_X963_KDF) && !defined(WOLFSSL_NO_ECC_SW)
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
#if !defined(NO_SHA) && defined(WOLFSSL_AES_128)
ADD_PKCS7ENVELOPEDVECTOR(
@@ -80054,7 +80213,8 @@ static wc_test_ret_t pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCer
0x72,0x6c,0x64
};
byte senderNonce[PKCS7_NONCE_SZ + 2];
#ifdef HAVE_ECC
/* Only the KARI vectors below use these, and WOLFSSL_NO_ECC_SW drops them. */
#if defined(HAVE_ECC) && !defined(WOLFSSL_NO_ECC_SW)
#if !defined(NO_AES) && defined(HAVE_AESGCM) && \
defined(HAVE_AES_KEYWRAP) && defined(HAVE_X963_KDF)
#if !defined(NO_SHA256) && defined(WOLFSSL_AES_256)
@@ -80073,7 +80233,8 @@ static wc_test_ret_t pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCer
#if !defined(NO_AES) && defined(WOLFSSL_AES_256) && defined(HAVE_ECC) && \
defined(WOLFSSL_SHA512) && defined(HAVE_AESGCM) && \
defined(HAVE_AES_KEYWRAP) && defined(HAVE_X963_KDF)
defined(HAVE_AES_KEYWRAP) && defined(HAVE_X963_KDF) && \
!defined(WOLFSSL_NO_ECC_SW)
WOLFSSL_SMALL_STACK_STATIC const byte optionalUkm[] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
};
@@ -80187,7 +80348,8 @@ static wc_test_ret_t pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCer
#endif
/* key agreement key encryption technique*/
#ifdef HAVE_ECC
/* See the KARI note in pkcs7enveloped_test(). */
#if defined(HAVE_ECC) && !defined(WOLFSSL_NO_ECC_SW)
#if !defined(NO_AES) && defined(HAVE_AESGCM) && \
defined(HAVE_AES_KEYWRAP) && defined(HAVE_X963_KDF)
#if !defined(NO_SHA) && defined(WOLFSSL_AES_128)
@@ -96532,13 +96694,16 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
PRIVATE_KEY_LOCK();
}
#endif
/* WOLFSSL_NO_ECC_SW is excluded: wc_CryptoCb_EccMakePub() is called from
* inside ecc_make_pub_ex()'s HAVE_ECC_MAKE_PUB arm, which that macro compiles
* out, so nothing can reach the make-pub callback for the counter to see. */
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_MICROCHIP_TA100) && !defined(WOLFSSL_STM32_PKA) && \
!defined(WOLFSSL_SILABS_SE_ACCEL) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
!defined(NO_ECC_SECP) && !defined(WOLFSSL_NO_MALLOC) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(NO_ECC256) && \
defined(HAVE_ECC_KEY_EXPORT) && \
!defined(HAVE_FIPS)
!defined(HAVE_FIPS) && !defined(WOLFSSL_NO_ECC_SW)
if (ret == 0 && myCtx.eccMakePubCount == 0)
ret = WC_TEST_RET_ENC_NC;
#endif

View File

@@ -807,7 +807,8 @@ int wc_ecc_shared_secret_gen_sync(ecc_key* private_key,
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
defined(WOLFSSL_MICROCHIP_TA100) || \
defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL)
defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
defined(WOLFSSL_NO_ECC_SW)
#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret
#else
#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret_ex /* For backwards compat */

View File

@@ -6160,6 +6160,119 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS."
#error "WOLF_CRYPTO_CB_ONLY_SLHDSA requires WOLFSSL_HAVE_SLHDSA"
#endif
/*
* WOLFSSL_NO_RSA_SW omits the wolfCrypt software RSA implementation: the
* modular exponentiation, the prime search used by key generation and the
* software key consistency check. Every RSA operation is then performed by a
* hardware implementation that does the PKCS#1 padding itself and generates
* keys on-chip. Two ports qualify today: the NXP SE05x one (see
* wolfcrypt/src/port/nxp/README_SE050.md) and Arm CryptoCell-310
* (WOLFSSL_CRYPTOCELL). rsa.c additionally drops the software padding
* generation when nothing else needs it. Operations with no hardware provider
* (raw wc_RsaFunction()/wc_RsaDirect(), and RSA-PSS, which neither port can
* serve from a pre-computed digest) return NOT_COMPILED_IN.
*/
#if defined(WOLFSSL_NO_RSA_SW) && !defined(NO_RSA)
#if (!defined(WOLFSSL_SE050) || defined(WOLFSSL_SE050_NO_RSA)) && \
!defined(WOLFSSL_CRYPTOCELL)
#error "WOLFSSL_NO_RSA_SW requires an RSA hardware implementation " \
"(WOLFSSL_SE050 without WOLFSSL_SE050_NO_RSA, " \
"or WOLFSSL_CRYPTOCELL)"
#endif
#ifdef WOLFSSL_SE050
#ifdef WOLFSSL_SE050_ONLY_KEY_ID
/* Per-key runtime routing needs the software implementation for
* keys that are not resident in the SE050. */
#error "WOLFSSL_NO_RSA_SW is incompatible with " \
"WOLFSSL_SE050_ONLY_KEY_ID"
#endif
#ifdef WOLFSSL_SE050_NO_RSA_VERIFY
#error "WOLFSSL_NO_RSA_SW is incompatible with " \
"WOLFSSL_SE050_NO_RSA_VERIFY"
#endif
#endif
#ifdef WOLF_CRYPTO_CB_ONLY_RSA
#error "WOLFSSL_NO_RSA_SW is incompatible with WOLF_CRYPTO_CB_ONLY_RSA"
#endif
#ifdef WC_RSA_NONBLOCK
#error "WOLFSSL_NO_RSA_SW is incompatible with WC_RSA_NONBLOCK"
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
#error "WOLFSSL_NO_RSA_SW is incompatible with asynchronous RSA"
#endif
/* wc_CheckRsaKey() re-does the key arithmetic in software, which a
* hardware-only build has no key material for. */
#undef WOLFSSL_RSA_KEY_CHECK
#endif
/*
* WOLFSSL_NO_ECC_SW is the ECC counterpart of WOLFSSL_NO_RSA_SW: it omits the
* wolfCrypt software ECC implementation - the projective point arithmetic, the
* scalar multiplication (including Shamir's trick), the software signer, the
* software ECDH and the software derivation of a public key from a private
* scalar. Every keyed ECC operation is then performed by hardware. ecc.c
* already excludes all of that for the ATECC508A/608A, TA100, CryptoCell,
* SiLabs and KCAPI ports and for WOLF_CRYPTO_CB_ONLY_ECC; this macro extends
* the same treatment to the NXP SE05x port, which offloads every keyed ECC
* operation but otherwise still compiles the software curve math.
*
* What goes with it: wc_ecc_make_pub() (deriving Q = d*G needs the software
* base-point multiply), the public APIs over that math (wc_ecc_mulmod(),
* wc_ecc_mulmod_ex(), ...) and compressed-point import, exactly as on the
* ports listed above. The curve tables, the mp_int key storage and the
* key/signature import and export paths all stay, and so does the validation
* of an imported untrusted public key - rejecting the point at infinity and
* checking the curve equation are plain modular arithmetic, not curve
* arithmetic, so they are still done on the host.
*/
#if defined(WOLFSSL_NO_ECC_SW) && defined(HAVE_ECC)
#if !defined(WOLFSSL_SE050) && !defined(WOLFSSL_CRYPTOCELL)
#error "WOLFSSL_NO_ECC_SW requires an ECC hardware implementation " \
"(WOLFSSL_SE050 or WOLFSSL_CRYPTOCELL)"
#endif
#ifdef WOLFSSL_SE050
#ifdef WOLFSSL_SE050_ONLY_KEY_ID
/* Per-key runtime routing needs the software implementation for
* keys that are not resident in the SE050. */
#error "WOLFSSL_NO_ECC_SW is incompatible with " \
"WOLFSSL_SE050_ONLY_KEY_ID"
#endif
#ifdef WOLFSSL_SE050_NO_ECDHE
/* This also puts ECC key generation back on the software path. */
#error "WOLFSSL_NO_ECC_SW is incompatible with " \
"WOLFSSL_SE050_NO_ECDHE"
#endif
#ifdef WOLFSSL_SE050_NO_ECDSA_VERIFY
#error "WOLFSSL_NO_ECC_SW is incompatible with " \
"WOLFSSL_SE050_NO_ECDSA_VERIFY"
#endif
#endif
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
#error "WOLFSSL_NO_ECC_SW is incompatible with WOLF_CRYPTO_CB_ONLY_ECC"
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
#error "WOLFSSL_NO_ECC_SW is incompatible with asynchronous ECC"
#endif
#ifdef WC_ECC_NONBLOCK
/* Non-blocking ECC is the software SP state machine being driven a
* slice at a time; there is nothing to yield from in hardware. */
#error "WOLFSSL_NO_ECC_SW is incompatible with WC_ECC_NONBLOCK"
#endif
/* ECCSI (RFC 6507) and SAKKE (RFC 6508) are built directly on the software
* point arithmetic and have no hardware path to fall back to. */
#ifdef WOLFCRYPT_HAVE_ECCSI
#error "WOLFSSL_NO_ECC_SW is incompatible with WOLFCRYPT_HAVE_ECCSI"
#endif
#ifdef WOLFCRYPT_HAVE_SAKKE
#error "WOLFSSL_NO_ECC_SW is incompatible with WOLFCRYPT_HAVE_SAKKE"
#endif
/* Nothing is left to export. */
#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL
#error "WOLFSSL_NO_ECC_SW is incompatible with " \
"WOLFSSL_PUBLIC_ECC_ADD_DBL"
#endif
#endif
/* Early Data / Session Rules */
#if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_EARLY_DATA) && \
!defined(WOLFSSL_TLS13)