Merge pull request #8242 from mpg/ecc-bn-wrapup

Driver-only ECC: wrap-up
This commit is contained in:
Gilles Peskine 2023-09-28 14:34:52 +00:00 committed by GitHub
commit 3243539f0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 106 additions and 100 deletions

View file

@ -6,8 +6,10 @@ Features
TLS 1.2 (ECDHE-ECDSA key exchange) are not supported in those builds yet,
as PSA does not have an API for restartable ECDH yet.
* When all of ECDH, ECDSA and EC J-PAKE are either disabled or provided by
a driver, it is possible to disable MBEDTLS_ECP_C and still get support
for ECC keys and algorithms in PSA. See docs/driver-only-builds.txt.
a driver, it is possible to disable MBEDTLS_ECP_C (and MBEDTLS_BIGNUM_C
if not required by another module) and still get support for ECC keys and
algorithms in PSA, with some limitations. See docs/driver-only-builds.txt
for details.
API changes
* Mbed TLS 3.4 introduced support for omitting the built-in implementation
of ECDSA and/or EC J-PAKE when those are provided by a driver. However,

View file

@ -104,33 +104,61 @@ It is possible to have most ECC operations provided only by a driver:
- the ECDH, ECDSA and EC J-PAKE algorithms;
- key import, export, and random generation.
More precisely:
- you can enable `PSA_WANT_ALG_ECDH` without `MBEDTLS_ECDH_C` provided
`MBEDTLS_PSA_ACCEL_ALG_ECDH` is enabled;
- you can enable `PSA_WANT_ALG_ECDSA` without `MBEDTLS_ECDSA_C` provided
More precisely, if:
- you have driver support for ECC public and using private keys (that is,
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY` and
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC` are enabled), and
- you have driver support for all ECC curves that are enabled (that is, for
each `PSA_WANT_ECC_xxx` macro enabled, the corresponding
`MBEDTLS_PSA_ACCEL_ECC_xxx` macros is enabled as well);
then you can:
- enable `PSA_WANT_ALG_ECDH` without `MBEDTLS_ECDH_C`, provided
`MBEDTLS_PSA_ACCEL_ALG_ECDH` is enabled
- enable `PSA_WANT_ALG_ECDSA` without `MBEDTLS_ECDSA_C`, provided
`MBEDTLS_PSA_ACCEL_ALG_ECDSA` is enabled;
- you can enable `PSA_WANT_ALG_JPAKE` without `MBEDTLS_ECJPAKE_C` provided
- enable `PSA_WANT_ALG_JPAKE` without `MBEDTLS_ECJPAKE_C`, provided
`MBEDTLS_PSA_ACCEL_ALG_JPAKE` is enabled.
In addition, if none of `MBEDTLS_ECDH_C`, `MBEDTLS_ECDSA_C`,
`MBEDTLS_ECJPAKE_C` are enabled, you can enable:
- `PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE`;
without `MBEDTLS_ECP_C` provided the corresponding
`MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx` are enabled.
In addition, if:
- none of `MBEDTLS_ECDH_C`, `MBEDTLS_ECDSA_C`, `MBEDTLS_ECJPAKE_C` are enabled
(see conditions above), and
- you have driver support for all enabled ECC key pair operations - that is,
for each `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx` macro enabled, the
corresponding `MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_xxx` macros is also
enabled,
[Coming soon] If `MBEDTLS_ECP_C` is disabled and `ecp.c` is fully removed (see
"Limitations regarding fully removing `ecp.c`" below), and you're not using
RSA or FFDH, then you can also disable `MBEDTLS_BIGNUM_C` for further code
size saving.
then you can also disable `MBEDTLS_ECP_C`. However, a small subset of it might
still be included in the build, see limitations sub-section below.
[Coming soon] As noted in the "Limitations regarding the selection of curves"
section below, there is an upcoming requirement for all the required curves to
also be accelerated in the PSA driver in order to exclude the builtin algs
support.
In addition, if:
- `MBEDTLS_ECP_C` is fully removed (see limitation sub-section below), and
- support for RSA key types and algorithms is fully disabled, and
- support for DH key types and the FFDH algorithm is either disabled, or
fully provided by a driver,
then you can also disable `MBEDTLS_BIGNUM_C`.
In such builds, all crypto operations via the PSA Crypto API will work as
usual, as well as the PK, X.509 and TLS modules if `MBEDTLS_USE_PSA_CRYPTO` is
enabled, with the following exceptions:
- direct calls to APIs from the disabled modules are not possible;
- PK, X.509 and TLS will not support restartable ECC operations (see
limitation sub-section below).
If you want to check at compile-time whether a certain curve is available in
the present build of Mbed TLS, regardless of whether ECC is provided by a
driver or built-in, you should use the following macros:
- for code that uses only the PSA Crypto API: `PSA_WANT_ECC_xxx` from
`psa/crypto.h`;
- for code that may also use non-PSA crypto APIs: `MBEDTLS_ECP_HAVE_xxx` from
`mbedtls/build_info.h` where xxx can take the same values as for
`MBEDTLS_ECP_DP_xxx` macros.
Note that for externally-provided drivers, the integrator is responsible for
ensuring the appropriate `MBEDTLS_PSA_ACCEL_xxx` macros are defined. However,
for the p256-m driver that's provided with the library, those macros are
automatically defined when enabling `MBEDTLS_PSA_P256M_DRIVER_ENABLED`.
### Limitations regarding fully removing `ecp.c`
@ -155,7 +183,7 @@ let us know, so we can take it into consideration in our planning.
### Limitations regarding restartable / interruptible ECC operations
At the moment, there is not driver support for interruptible operations
At the moment, there is no driver support for interruptible operations
(see `psa_sign_hash_start()` + `psa_sign_hash_complete()` etc.) so as a
consequence these are not supported in builds without `MBEDTLS_ECDSA_C`.
@ -167,18 +195,6 @@ documentation](use-psa-crypto.md).
Again, we have plans to support this in the future but not with an established
timeline, please let us know if you're interested.
### Limitations regarding the selection of curves
There is ongoing work which is trying to establish the links and constraints
between the list of supported curves and supported algorithms both in the
builtin and PSA sides. In particular:
- #8014 ensures that the curves supported on the PSA side (`PSA_WANT_ECC_xxx`)
are always a superset of the builtin ones (`MBEDTLS_ECP_DP_xxx`)
- #8016 forces builtin alg support as soon as there is at least one builtin
curve. In other words, in order to exclue all builtin algs, all the required
curves should be supported and accelerated by the PSA driver.
### Limitations regarding "mixed" builds (driver and built-in)
In order for a build to be driver-only (no built-in implementation), all the

View file

@ -146,11 +146,11 @@ The Mbed TLS build system includes the instructions needed to build p256-m. To b
python3 scripts/config.py set MBEDTLS_PSA_P256M_DRIVER_ENABLED
make
(You need extra steps if you want to disable the built-in implementation of ECC algorithms, which includes more features than p256-m. Refer to the documentation of `MBEDTLS_PSA_P256M_DRIVER_ENABLED` for more information.)
(You need extra steps if you want to disable the built-in implementation of ECC algorithms, which includes more features than p256-m. Refer to the documentation of `MBEDTLS_PSA_P256M_DRIVER_ENABLED` and [`driver-only-builds.md`](driver-only-builds.md) for more information.)
The driver prefix for p256-m is `P256`/`p256`.
The p256-m driver implements four entry points: `generate_key`, `key_agreement`, `sign_hash`, `verify_hash`.
There are no entry points for `sign_message` and `verify_message`, which are not necessary for a sign-and-hash algorithm. The core still implements these functions by doing the hashes and then calling the sign/verify-hash entry points.
The p256-m driver implements the following entry points: `"import_key"`, `"export_public_key"`, `"generate_key"`, `"key_agreement"`, `"sign_hash"`, `"verify_hash"`.
There are no entry points for `"sign_message"` and `"verify_message"`, which are not necessary for a sign-and-hash algorithm. The core still implements these functions by doing the hashes and then calling the sign/verify-hash entry points.
The driver entry point functions can be found in `p256m_driver_entrypoints.[hc]`. These functions act as an interface between Mbed TLS and p256-m; converting between PSA and p256-m argument formats and performing sanity checks. If the driver's status codes differ from PSA's, it is recommended to implement a status code translation function. The function `p256_to_psa_error()` converts error codes returned by p256-m into PSA error codes.
The driver wrapper functions in `psa_crypto_driver_wrappers.h.jinja` for all four entry points have also been modified. The code block below shows the additions made to `psa_driver_wrapper_sign_hash()`. In adherence to the defined process, all code related to the driver call is placed within a check for `MBEDTLS_PSA_P256M_DRIVER_ENABLED`. p256-m only supports non-deterministic ECDSA using keys based on NIST P256; these constraints are enforced through checks (see the `if` statement). Checks that involve accessing key attributes, (e.g. checking key type or bits) **must** be performed in the driver wrapper. This is because this information is marked private and may not be accessed outside the library. Other checks can be performed here or in the entry point function. The status returned by the driver is propagated up the call hierarchy **unless** the driver does not support the operation (i.e. return `PSA_ERROR_NOT_SUPPORTED`). In that case the next available driver/built-in implementation is called.

View file

@ -28,6 +28,20 @@
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
#define MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
/* Define appropriate ACCEL macros for the p256-m driver.
* In the future, those should be generated from the drivers JSON description.
*/
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256
#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
#define MBEDTLS_PSA_ACCEL_ALG_ECDH
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE
#endif
/*
* ECC: support for a feature is controlled by a triplet or a pair:
* (curve, key_type public/basic, alg) or (curve, key_type_<action>).

View file

@ -1451,15 +1451,16 @@
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT and/or
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE as needed.
*
* \note To genuinely benefit from the smaller code size of p256-m, make
* sure that you do not enable any ECC-related option that requires
* the built-in implementation of elliptic curve arithmetic. This
* means enabling #MBEDTLS_PSA_CRYPTO_C, #MBEDTLS_PSA_CRYPTO_CONFIG,
* #PSA_WANT_ECC_SECP_R1_256 and #MBEDTLS_PSA_P256M_DRIVER_ENABLED,
* plus any of the `PSA_WANT_ALG_xxx` and `PSA_WANT_KEY_TYPE_xxx`
* options listed above, and not enabling other ECC-related options
* through `PSA_WANT_xxx` or `MBEDTLS_xxx` (in particular, not
* enabling other curves or EC-JPAKE).
* \note To benefit from the smaller code size of p256-m, make sure that you
* do not enable any ECC-related option not supported by p256-m: this
* would cause the built-in ECC implementation to be built as well, in
* order to provide the required option.
* Make sure #PSA_WANT_ALG_DETERMINISTIC_ECDSA, #PSA_WANT_ALG_JPAKE and
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE, and curves other than
* SECP256R1 are disabled as they are not supported by this driver.
* Also, avoid defining #MBEDTLS_PK_PARSE_EC_COMPRESSED or
* #MBEDTLS_PK_PARSE_EC_EXTENDED as those currently require a subset of
* the built-in ECC implementation, see docs/driver-only-builds.md.
*/
//#define MBEDTLS_PSA_P256M_DRIVER_ENABLED

View file

@ -1503,7 +1503,7 @@ struct mbedtls_ssl_config {
const uint16_t *MBEDTLS_PRIVATE(sig_algs); /*!< allowed signature algorithms */
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
const mbedtls_ecp_group_id *MBEDTLS_PRIVATE(curve_list); /*!< allowed curves */
#endif
@ -3651,7 +3651,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
unsigned int bitlen);
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#if defined(MBEDTLS_ECP_C)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/**
* \brief Set the allowed curves in order of preference.
@ -3697,7 +3697,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
void MBEDTLS_DEPRECATED mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
const mbedtls_ecp_group_id *curves);
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#endif /* MBEDTLS_ECP_C */
/**
* \brief Set the allowed groups in order of preference.

View file

@ -1150,7 +1150,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
* mbedtls_ssl_conf_curves returns void and so can't return
* any error codes.
*/
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#if defined(MBEDTLS_ECP_C)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/* Heap allocate and translate curve_list from internal to IANA group ids */
if (ssl->conf->curve_list != NULL) {
@ -1185,7 +1185,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
ssl->handshake->group_list_heap_allocated = 0;
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
@ -2921,7 +2921,7 @@ void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf,
}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#if defined(MBEDTLS_ECP_C)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/*
* Set the allowed elliptic curves
@ -2938,7 +2938,7 @@ void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
conf->group_list = NULL;
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#endif /* MBEDTLS_ECP_C */
/*
* Set the allowed groups
@ -2946,7 +2946,7 @@ void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf,
const uint16_t *group_list)
{
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
conf->curve_list = NULL;
#endif
conf->group_list = group_list;
@ -5321,7 +5321,7 @@ int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
conf->sig_algs = ssl_preset_suiteb_sig_algs;
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
conf->curve_list = NULL;
#endif
conf->group_list = ssl_preset_suiteb_groups;
@ -5347,7 +5347,7 @@ int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
conf->sig_algs = ssl_preset_default_sig_algs;
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED)
conf->curve_list = NULL;
#endif
conf->group_list = ssl_preset_default_groups;

View file

@ -1138,19 +1138,6 @@ component_test_full_cmake_gcc_asan () {
msg "test: context-info.sh (full config, ASan build)" # ~ 15 sec
tests/context-info.sh
msg "test: check direct ECP dependencies in TLS and X.509"
docs/architecture/psa-migration/syms.sh full
# TODO: replace "mbedtls_ecp_curve" with "mbedtls_ecp" also for
# "full-tls-external" once Issue6839 is completed
not grep mbedtls_ecp_curve full-libmbedtls-external
not grep mbedtls_ecp full-libmbedx509-external
rm full-libmbedtls-external \
full-libmbedtls-modules \
full-libmbedx509-external \
full-libmbedx509-modules
}
@ -1175,19 +1162,6 @@ component_test_full_cmake_gcc_asan_new_bignum () {
msg "test: context-info.sh (full config, ASan build)" # ~ 15 sec
tests/context-info.sh
msg "test: check direct ECP dependencies in TLS and X.509"
docs/architecture/psa-migration/syms.sh full
# TODO: replace "mbedtls_ecp_curve" with "mbedtls_ecp" also for
# "full-tls-external" once Issue6839 is completed
not grep mbedtls_ecp_curve full-libmbedtls-external
not grep mbedtls_ecp full-libmbedx509-external
rm full-libmbedtls-external \
full-libmbedtls-modules \
full-libmbedx509-external \
full-libmbedx509-modules
}
component_test_full_cmake_gcc_asan_new_bignum_test_hooks () {
@ -3177,21 +3151,8 @@ component_test_tfm_config_p256m_driver_accel_ec () {
common_tfm_config
# Set the list of accelerated components in order to remove them from
# builtin support.
loc_accel_list="ALG_ECDSA \
ALG_ECDH \
ECC_SECP_R1_256 \
KEY_TYPE_ECC_KEY_PAIR_BASIC \
KEY_TYPE_ECC_KEY_PAIR_IMPORT \
KEY_TYPE_ECC_KEY_PAIR_EXPORT \
KEY_TYPE_ECC_KEY_PAIR_GENERATE \
KEY_TYPE_ECC_PUBLIC_KEY"
loc_accel_flags="$( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
# Build crypto library specifying we want to use P256M code for EC operations
make CFLAGS="$ASAN_CFLAGS $loc_accel_flags -DMBEDTLS_PSA_P256M_DRIVER_ENABLED -I../tests/include/spe" LDFLAGS="$ASAN_CFLAGS"
make CFLAGS="$ASAN_CFLAGS -DMBEDTLS_PSA_P256M_DRIVER_ENABLED -I../tests/include/spe" LDFLAGS="$ASAN_CFLAGS"
# Make sure any built-in EC alg was not re-enabled by accident (additive config)
not grep mbedtls_ecdsa_ library/ecdsa.o

View file

@ -271,6 +271,9 @@ TASKS = {
'PSA key derivation: HKDF-SHA-256 -> ECC secp521r1 #0',
'PSA key derivation: HKDF-SHA-256 -> ECC secp521r1 #1',
],
'test_suite_ssl': [
'Test configuration of groups for DHE through mbedtls_ssl_conf_curves()',
],
}
}
},
@ -330,6 +333,9 @@ TASKS = {
'Parse Public EC Key #8a (RFC 5480, brainpoolP384r1, compressed)',
'Parse Public EC Key #9a (RFC 5480, brainpoolP512r1, compressed)',
],
'test_suite_ssl': [
'Test configuration of groups for DHE through mbedtls_ssl_conf_curves()',
],
}
}
},
@ -423,6 +429,9 @@ TASKS = {
'Debug print mbedtls_mpi: 764 bits #1',
'Debug print mbedtls_mpi: 764 bits #2',
],
'test_suite_ssl': [
'Test configuration of groups for DHE through mbedtls_ssl_conf_curves()',
],
}
}
},
@ -517,6 +526,9 @@ TASKS = {
'Debug print mbedtls_mpi: 764 bits #1',
'Debug print mbedtls_mpi: 764 bits #2',
],
'test_suite_ssl': [
'Test configuration of groups for DHE through mbedtls_ssl_conf_curves()',
],
}
}
},

View file

@ -3059,7 +3059,7 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:!MBEDTLS_DEPRECATED_REMOVED:!MBEDTLS_DEPRECATED_WARNING:MBEDTLS_ECP_HAVE_SECP192R1:MBEDTLS_ECP_HAVE_SECP224R1:MBEDTLS_ECP_HAVE_SECP256R1 */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_C:!MBEDTLS_DEPRECATED_REMOVED:!MBEDTLS_DEPRECATED_WARNING:MBEDTLS_ECP_HAVE_SECP192R1:MBEDTLS_ECP_HAVE_SECP224R1:MBEDTLS_ECP_HAVE_SECP256R1 */
void conf_curve()
{