Merge pull request #8680 from mpg/ciphers-wrapup

Driver-only ciphers wrapup
This commit is contained in:
Manuel Pégourié-Gonnard 2024-01-10 12:04:50 +00:00 committed by GitHub
commit 3eb9025275
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 120 additions and 57 deletions

View file

@ -1,4 +0,0 @@
Features
* The CCM and GCM modules no longer depend on MBEDTLS_CIPHER_C. People who
use CCM and GCM but don't need the Cipher API can now disable
MBEDTLS_CIPHER_C in order to save code size.

View file

@ -1,8 +0,0 @@
Features
* It is now possible to have AEADs support (CCM, GCM and ChaChaPoly) without
MBEDTLS_CIPHER_C. This holds both for the builtin suport (MBEDTLS_CCM_C,
MBEDTLS_GCM_C and MBEDTLS_CHACHAPOLY_C) as well as the PSA one
(PSA_WANT_ALG_CCM, PSA_WANT_ALG_GCM, PSA_WANT_ALG_CHACHA20_POLY1305).
On the PSA side this means that it is possible to enable
MBEDTLS_PSA_CRYPTO_C without MBEDTLS_CIPHER_C if none of the
non-authenticated ciphers is enabled.

View file

@ -1,9 +1,11 @@
Features
* If a cipher or AEAD mechanism has a PSA driver, you can now build the
library without the corresponding built-in implementation. See
library without the corresponding built-in implementation. Generally
speaking that requires both the key type and algorithm to be accelerated
or they'll both be built in. However, for CCM and GCM the built-in
implementation is able to take advantage of a driver that only
accelerates the key type (that is, the block cipher primitive). See
docs/driver-only-builds.md for full details and current limitations.
* It is possible to disable MBEDTLS_CIPHER_C in some circumstances, please
see docs/driver-only-builds.md for full details and current limitations.
* The CTR_DRBG module will now use AES from a PSA driver if MBEDTLS_AES_C is
disabled. This requires PSA_WANT_ALG_ECB_NO_PADDING in addition to
MBEDTLS_PSA_CRYPTO_C and PSA_WANT_KEY_TYPE_AES.

View file

@ -0,0 +1,9 @@
Features
* Fewer modules depend on MBEDTLS_CIPHER_C, making it possible to save code
size by disabling it in more circumstances. In particular, the CCM and
GCM modules no longer depend on MBEDTLS_CIPHER_C. Also,
MBEDTLS_PSA_CRYPTO can now be enabled without MBEDTLS_CIPHER_C if all
unauthenticated (non-AEAD) ciphers are disabled, or if they're all
fully provided by drivers. See docs/driver-only-builds.md for full
details and current limitations; in particular, NIST_KW and PKCS5/PKCS12
decryption still unconditionally depend on MBEDTLS_CIPHER_C.

View file

@ -494,7 +494,7 @@ int psa_can_do_hash(psa_algorithm_t hash_alg);
The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA.
As a starting point, return 1 if PSA crypto has been initialized. This will be refined later (to return 1 if the [accelerator subsystem](https://github.com/Mbed-TLS/mbedtls/issues/6007) has been initialized).
As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
Usage note: for algorithms that are not enabled via PSA, calling `psa_can_do_hash` is generally safe: whether it returns 0 or 1, you can call a PSA hash function on the algorithm and it will return `PSA_ERROR_NOT_SUPPORTED`.
@ -514,7 +514,7 @@ Note that this assumes that an operation that has been started via PSA can be co
#### Error code conversion
After calling a PSA function, call `mbedtls_md_error_from_psa` to convert its status code.
After calling a PSA function, MD light calls `mbedtls_md_error_from_psa` to convert its status code.
### Support all legacy algorithms in PSA
@ -566,14 +566,15 @@ The architecture can be extended to support `MBEDTLS_PSA_CRYPTO_CLIENT` with a l
* Compile-time dependencies: instead of checking `defined(MBEDTLS_PSA_CRYPTO_C)`, check `defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)`.
* Implementers of `MBEDTLS_PSA_CRYPTO_CLIENT` will need to provide `psa_can_do_hash()` (or a more general function `psa_can_do`) alongside `psa_crypto_init()`. Note that at this point, it will become a public interface, hence we won't be able to change it at a whim.
### Internal "block cipher" abstraction (Cipher light)
### Internal "block cipher" abstraction (previously known as "Cipher light")
#### Definition
The new module is automatically enabled in `build_info.h` by modules that need
it, namely: CCM, GCM, only when `CIPHER_C` is not available. Note: CCM and GCM
currently depend on the full `CIPHER_C` (enforced by `check_config.h`); this
hard dependency would be replaced by the above auto-enablement.
The new module is automatically enabled in `config_adjust_legacy_crypto.h` by modules that need
it (namely: CCM, GCM) only when `CIPHER_C` is not available, or the new module
is needed for PSA dispatch (see next section). Note: CCM and GCM currently
depend on the full `CIPHER_C` (enforced by `check_config.h`); this hard
dependency would be replaced by the above auto-enablement.
The following API functions are offered:
```
@ -593,6 +594,23 @@ The only supported ciphers are AES, ARIA and Camellia. They are identified by
an `mbedtls_cipher_id_t` in the `setup()` function, because that's how they're
identifed by callers (GCM/CCM).
#### Cipher light dual dispatch
#### Block cipher dual dispatch
This is likely to come in the future, but has not been defined yet.
Support for dual dispatch in the new internal module `block_cipher` is extremely similar to that in MD light.
A block cipher context contains either a legacy module's context (AES, ARIA, Camellia) or a PSA key identifier; it has a field indicating which one is in use. All fields are private.
The `engine` field is almost redundant with knowledge about `type`. However, when an algorithm is available both via a legacy module and a PSA accelerator, we will choose based on the runtime availability of the accelerator when the context is set up. This choice needs to be recorded in the context structure.
Support is determined at runtime using the new internal function
```
int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg);
```
The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA. As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
Each function in the module needs to know whether to dispatch via PSA or legacy. All functions consult the context's `engine` field, except `setup()` which will set it according to the key type and the return value of `psa_can_do_cipher()` as discussed above.
Note that this assumes that an operation that has been started via PSA can be completed. This implies that `mbedtls_psa_crypto_free` must not be called while an operation using PSA is in progress.
After calling a PSA function, `block_cipher` functions call `mbedtls_cipher_error_from_psa` to convert its status code.

View file

@ -16,6 +16,7 @@ driver.
In order to have some mechanism provided only by a driver, you'll want
the following compile-time configuration options enabled:
- `MBEDTLS_PSA_CRYPTO_C` (enabled by default) - this enables PSA Crypto.
- `MBEDTLS_USE_PSA_CRYPTO` (disabled by default) - this makes PK, X.509 and
TLS use PSA Crypto. You need to enable this if you're using PK, X.509 or TLS
@ -28,6 +29,7 @@ mechanism through the PSA API in Mbed
TLS](proposed/psa-conditional-inclusion-c.md) for details.
In addition, for each mechanism you want provided only by your driver:
- Define the corresponding `PSA_WANT` macro in `psa/crypto_config.h` - this
means the algorithm will be available in the PSA Crypto API.
- Define the corresponding `MBEDTLS_PSA_ACCEL` in your build. This could be
@ -52,9 +54,12 @@ Mechanisms covered
------------------
For now, only the following (families of) mechanisms are supported:
- hashes: SHA-3, SHA-2, SHA-1, MD5, etc.
- elliptic-curve cryptography (ECC): ECDH, ECDSA, EC J-PAKE, ECC key types.
- finite-field Diffie-Hellman: FFDH algorithm, DH key types.
- RSA: PKCS#1 v1.5 and v2.1 signature and encryption algorithms, RSA key types
(for now, only crypto, no X.509 or TLS support).
- AEADs:
- GCM and CCM with AES, ARIA and Camellia key types
- ChachaPoly with ChaCha20 Key type
@ -71,15 +76,13 @@ work in the same way as if the mechanisms where built-in, except as documented
in the "Limitations" sub-sections of the sections dedicated to each family
below.
Currently (mid-2023) we don't have plans to extend this to RSA. If
you're interested in driver-only support for RSA, please let us know.
Hashes
------
It is possible to have all hash operations provided only by a driver.
More precisely:
- you can enable `PSA_WANT_ALG_SHA_256` without `MBEDTLS_SHA256_C`, provided
you have `MBEDTLS_PSA_ACCEL_ALG_SHA_256` enabled;
- and similarly for all supported hash algorithms: `MD5`, `RIPEMD160`,
@ -98,6 +101,7 @@ considerations](#general-considerations) above.
If you want to check at compile-time whether a certain hash algorithm is
available in the present build of Mbed TLS, regardless of whether it's
provided by a driver or built-in, you should use the following macros:
- for code that uses only the PSA Crypto API: `PSA_WANT_ALG_xxx` from
`psa/crypto.h`;
- for code that uses non-PSA crypto APIs: `MBEDTLS_MD_CAN_xxx` from
@ -107,10 +111,12 @@ Elliptic-curve cryptography (ECC)
---------------------------------
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, 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
@ -119,6 +125,7 @@ More precisely, if:
`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
@ -127,6 +134,7 @@ then you can:
`MBEDTLS_PSA_ACCEL_ALG_JPAKE` is 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,
@ -138,9 +146,11 @@ 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.
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
- `MBEDTLS_ECP_C` is fully removed (see limitation sub-section below),
- and support for RSA key types and algorithms is either fully disabled or
fully provided by a driver,
- 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`.
@ -148,6 +158,7 @@ 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).
@ -155,6 +166,7 @@ enabled, with the following exceptions:
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
@ -170,6 +182,7 @@ automatically defined when enabling `MBEDTLS_PSA_P256M_DRIVER_ENABLED`.
A limited subset of `ecp.c` will still be automatically re-enabled if any of
the following is enabled:
- `MBEDTLS_PK_PARSE_EC_COMPRESSED` - support for parsing ECC keys where the
public part is in compressed format;
- `MBEDTLS_PK_PARSE_EC_EXTENDED` - support for parsing ECC keys where the
@ -243,12 +256,37 @@ The same holds for the associated algorithm:
`[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_FFDH` allow builds accelerating FFDH and
removing builtin support (i.e. `MBEDTLS_DHM_C`).
RSA
---
It is possible for all RSA operations to be provided only by a driver.
More precisely, if:
- all the RSA algorithms that are enabled (`PSA_WANT_ALG_RSA_*`) are also
accelerated (`MBEDTLS_PSA_ACCEL_ALG_RSA_*`),
- and all the RSA key types that are enabled (`PSA_WANT_KEY_TYPE_RSA_*`) are
also accelerated (`MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_*`),
then you can disable `MBEDTLS_RSA_C`, `MBEDTLS_PKCS1_V15` and
`MBEDTLS_PKCS1_V21`, and RSA will still work in PSA Crypto.
### Limitations on RSA acceleration
Unlike other mechanisms, for now in configurations with driver-only RSA, only
PSA Crypto works. In particular, PK, X.509 and TLS will _not_ work with
driver-only RSA even if `MBEDTLS_USE_PSA_CRYPTO` is enabled.
Currently (early 2024) we don't have plans to extend this support. If you're
interested in wider driver-only support for RSA, please let us know.
Ciphers (unauthenticated and AEAD)
----------------------------------
It is possible to have all ciphers and AEAD operations provided only by a
driver. More precisely, for each desired combination of key type and
algorithm/mode you can:
- Enable desired PSA key type(s):
- `PSA_WANT_KEY_TYPE_AES`,
- `PSA_WANT_KEY_TYPE_ARIA`,
@ -305,6 +343,7 @@ some non-PSA APIs will be absent or have reduced functionality, see
Some legacy modules can't take advantage of PSA drivers yet, and will either
need to be disabled, or have reduced features when the built-in implementations
of some ciphers are removed:
- `MBEDTLS_NIST_KW_C` needs built-in AES: it must be disabled when
`MBEDTLS_AES_C` is disabled.
- `MBEDTLS_CMAC_C` needs built-in AES/DES: it must be disabled when
@ -329,6 +368,7 @@ restrictions, see [Disabling `MBEDTLS_CIPHER_C`](#disabling-mbedtls_cipher_c).
Note that the relationship between legacy (i.e. `MBEDTLS_xxx_C`) and PSA
(i.e. `PSA_WANT_xxx`) symbols is not always 1:1. For example:
- ECB mode is always enabled in the legacy configuration for each key type that
allows it (AES, ARIA, Camellia, DES), whereas it must be explicitly enabled
in PSA with `PSA_WANT_ALG_ECB_NO_PADDING`.
@ -349,9 +389,12 @@ from PSA acceleration of the underlying block cipher by enabling support for
ECB mode (`PSA_WANT_ALG_ECB_NO_PADDING` + `MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING`)
together with desired key type(s) (`PSA_WANT_KEY_TYPE_[AES|ARIA|CAMELLIA]` +
`MBEDTLS_PSA_ACCEL_KEY_TYPE_[AES|ARIA|CAMELLIA]`).
In such configurations it is possible to:
- Use CCM and GCM via the PSA Crypto APIs.
- Use CCM and GCM via legacy functions (`mbedtls_[ccm|gcm]_xxx()`).
- Use CCM and GCM via legacy functions `mbedtls_[ccm|gcm]_xxx()` (but not the
legacy functions `mbedtls_cipher_xxx()`).
- Disable legacy key types (`MBEDTLS_[AES|ARIA|CAMELLIA]_C`) if there is no
other dependency requiring them.
@ -362,6 +405,7 @@ algorithm) in order to work with a driver.
The legacy CTR-DRBG module (enabled by `MBEDTLS_CTR_DRBG_C`) can also benefit
from PSA acceleration if both of the following conditions are met:
- The legacy AES module (`MBEDTLS_AES_C`) is not enabled and
- AES is supported on the PSA side together with ECB mode, i.e.
`PSA_WANT_KEY_TYPE_AES` + `PSA_WANT_ALG_ECB_NO_PADDING`.
@ -370,6 +414,7 @@ from PSA acceleration if both of the following conditions are met:
It is possible to save code size by disabling MBEDTLS_CIPHER_C when all of the
following conditions are met:
- The application is not using the `mbedtls_cipher_` API.
- In PSA, all unauthenticated (that is, non-AEAD) ciphers are either disabled or
fully accelerated (that is, all compatible key types are accelerated too).
@ -379,6 +424,7 @@ following conditions are met:
a driver.)
In such a build, everything will work as usual except for the following:
- Encryption/decryption functions from the PKCS5 and PKCS12 module will not be
available (only key derivation functions).
- Parsing of PKCS5- or PKCS12-encrypted keys in PK parse will fail.

View file

@ -1540,7 +1540,7 @@ component_test_crypto_full_md_light_only () {
make test
}
component_test_full_no_cipher () {
component_test_full_no_cipher_no_psa_crypto () {
msg "build: full no CIPHER no PSA_CRYPTO_C"
scripts/config.py full
scripts/config.py unset MBEDTLS_CIPHER_C
@ -1565,8 +1565,8 @@ component_test_full_no_cipher () {
}
# This is a common configurator and test function that is used in:
# - component_test_full_no_cipher_with_crypto
# - component_test_full_no_cipher_with_crypto_config
# - component_test_full_no_cipher_with_psa_crypto
# - component_test_full_no_cipher_with_psa_crypto_config
# It accepts 2 input parameters:
# - $1: boolean value which basically reflects status of MBEDTLS_PSA_CRYPTO_CONFIG
# - $2: a text string which describes the test component
@ -1614,11 +1614,11 @@ common_test_full_no_cipher_with_psa_crypto () {
make test
}
component_test_full_no_cipher_with_crypto() {
component_test_full_no_cipher_with_psa_crypto() {
common_test_full_no_cipher_with_psa_crypto 0 "full no CIPHER no CRYPTO_CONFIG"
}
component_test_full_no_cipher_with_crypto_config() {
component_test_full_no_cipher_with_psa_crypto_config() {
common_test_full_no_cipher_with_psa_crypto 1 "full no CIPHER"
}
@ -3741,9 +3741,9 @@ component_test_psa_crypto_config_accel_aead () {
}
# This is a common configuration function used in:
# - component_test_psa_crypto_config_accel_cipher_aead
# - component_test_psa_crypto_config_reference_cipher_aead
common_psa_crypto_config_accel_cipher_aead() {
# - component_test_psa_crypto_config_accel_cipher_aead_cmac
# - component_test_psa_crypto_config_reference_cipher_aead_cmac
common_psa_crypto_config_accel_cipher_aead_cmac() {
# Start from the full config
helper_libtestdriver1_adjust_config "full"
@ -3751,12 +3751,12 @@ common_psa_crypto_config_accel_cipher_aead() {
}
# The 2 following test components, i.e.
# - component_test_psa_crypto_config_accel_cipher_aead
# - component_test_psa_crypto_config_reference_cipher_aead
# - component_test_psa_crypto_config_accel_cipher_aead_cmac
# - component_test_psa_crypto_config_reference_cipher_aead_cmac
# are meant to be used together in analyze_outcomes.py script in order to test
# driver's coverage for ciphers and AEADs.
component_test_psa_crypto_config_accel_cipher_aead () {
msg "build: full config with accelerated cipher and AEAD"
component_test_psa_crypto_config_accel_cipher_aead_cmac () {
msg "build: full config with accelerated cipher inc. AEAD and CMAC"
loc_accel_list="ALG_ECB_NO_PADDING ALG_CBC_NO_PADDING ALG_CBC_PKCS7 ALG_CTR ALG_CFB \
ALG_OFB ALG_XTS ALG_STREAM_CIPHER ALG_CCM_STAR_NO_TAG \
@ -3766,7 +3766,7 @@ component_test_psa_crypto_config_accel_cipher_aead () {
# Configure
# ---------
common_psa_crypto_config_accel_cipher_aead
common_psa_crypto_config_accel_cipher_aead_cmac
# Disable the things that are being accelerated
scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC
@ -3810,29 +3810,29 @@ component_test_psa_crypto_config_accel_cipher_aead () {
# Run the tests
# -------------
msg "test: full config with accelerated cipher and AEAD"
msg "test: full config with accelerated cipher inc. AEAD and CMAC"
make test
msg "ssl-opt: full config with accelerated cipher and AEAD"
msg "ssl-opt: full config with accelerated cipher inc. AEAD and CMAC"
tests/ssl-opt.sh
msg "compat.sh: full config with accelerated cipher and AEAD"
msg "compat.sh: full config with accelerated cipher inc. AEAD and CMAC"
tests/compat.sh -V NO -p mbedTLS
}
component_test_psa_crypto_config_reference_cipher_aead () {
msg "build: full config with non-accelerated cipher and AEAD"
common_psa_crypto_config_accel_cipher_aead
component_test_psa_crypto_config_reference_cipher_aead_cmac () {
msg "build: full config with non-accelerated cipher inc. AEAD and CMAC"
common_psa_crypto_config_accel_cipher_aead_cmac
make
msg "test: full config with non-accelerated cipher and AEAD"
msg "test: full config with non-accelerated cipher inc. AEAD and CMAC"
make test
msg "ssl-opt: full config with non-accelerated cipher and AEAD"
msg "ssl-opt: full config with non-accelerated cipher inc. AEAD and CMAC"
tests/ssl-opt.sh
msg "compat.sh: full config with non-accelerated cipher and AEAD"
msg "compat.sh: full config with non-accelerated cipher inc. AEAD and CMAC"
tests/compat.sh -V NO -p mbedTLS
}

View file

@ -240,16 +240,16 @@ KNOWN_TASKS = {
}
}
},
'analyze_driver_vs_reference_cipher_aead': {
'analyze_driver_vs_reference_cipher_aead_cmac': {
'test_function': do_analyze_driver_vs_reference,
'args': {
'component_ref': 'test_psa_crypto_config_reference_cipher_aead',
'component_driver': 'test_psa_crypto_config_accel_cipher_aead',
'component_ref': 'test_psa_crypto_config_reference_cipher_aead_cmac',
'component_driver': 'test_psa_crypto_config_accel_cipher_aead_cmac',
# Modules replaced by drivers.
'ignored_suites': [
# low-level (block/stream) cipher modules
'aes', 'aria', 'camellia', 'des', 'chacha20',
# AEAD modes
# AEAD modes and CMAC
'ccm', 'chachapoly', 'cmac', 'gcm',
# The Cipher abstraction layer
'cipher',