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:
12
.github/workflows/se050-sim.yml
vendored
12
.github/workflows/se050-sim.yml
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
71
ChangeLog.md
71
ChangeLog.md
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
19
src/pk_ec.c
19
src/pk_ec.c
@@ -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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user