diff options
Diffstat (limited to 'docs/driver-only-builds.md')
-rw-r--r-- | docs/driver-only-builds.md | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/docs/driver-only-builds.md b/docs/driver-only-builds.md new file mode 100644 index 00000000000..4095d8ee774 --- /dev/null +++ b/docs/driver-only-builds.md @@ -0,0 +1,460 @@ +This document explains how to create builds of Mbed TLS where some +cryptographic mechanisms are provided only by PSA drivers (that is, no +built-in implementation of those algorithms), from a user's perspective. + +This is useful to save code size for people who are using either a hardware +accelerator, or an alternative software implementation that is more +aggressively optimized for code size than the default one in Mbed TLS. + +General considerations +---------------------- + +This document assumes that you already have a working driver. +Otherwise, please see the [PSA driver example and +guide](psa-driver-example-and-guide.md) for information on writing a +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 +and want them to have access to the algorithms provided by your driver. (See +[the dedicated document](use-psa-crypto.md) for details.) +- `MBEDTLS_PSA_CRYPTO_CONFIG` (disabled by default) - this enables + configuration of cryptographic algorithms using `PSA_WANT` macros in +`include/psa/crypto_config.h`. See [Conditional inclusion of cryptographic +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 + defined in `psa/crypto_config.h` or your compiler's command line. This +informs the PSA code that an accelerator is available for this mechanism. +- Undefine / comment out the corresponding `MBEDTLS_xxx_C` macro in + `mbedtls/mbedtls_config.h`. This ensures the built-in implementation is not +included in the build. + +For example, if you want SHA-256 to be provided only by a driver, you'll want +`PSA_WANT_ALG_SHA_256` and `MBEDTLS_PSA_ACCEL_SHA_256` defined, and +`MBEDTLS_SHA256_C` undefined. + +In addition to these compile-time considerations, at runtime you'll need to +make sure you call `psa_crypto_init()` before any function that uses the +driver-only mechanisms. Note that this is already a requirement for any use of +the PSA Crypto API, as well as for use of the PK, X.509 and TLS modules when +`MBEDTLS_USE_PSA_CRYPTO` is enabled, so in most cases your application will +already be doing this. + +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 +- Unauthenticated ciphers: + - key types: AES, ARIA, Camellia, DES + - modes: ECB, CBC, CTR, CFB, OFB, XTS + +For each family listed above, all the mentioned alorithms/key types are also +all the mechanisms that exist in PSA API. + +Supported means that when those are provided only by drivers, everything +(including PK, X.509 and TLS if `MBEDTLS_USE_PSA_CRYPTO` is enabled) should +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. + +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`, + `SHA_1`, `SHA_224`, `SHA_256`, `SHA_384`, `SHA_512`, `SHA3_224`, `SHA3_256`, +`SHA3_384`, `SHA3_512`. + +In such a build, all crypto operations (via the PSA Crypto API, or non-PSA +APIs), as well as X.509 and TLS, will work as usual, except that direct calls +to low-level hash APIs (`mbedtls_sha256()` etc.) are not possible for the +modules that are disabled. + +You need to call `psa_crypto_init()` before any crypto operation that uses +a hash algorithm that is provided only by a driver, as mentioned in [General +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 + `mbedtls/config_adjust_legacy_crypto.h`. + +### HMAC + +In addition to accelerated hash operations, it is also possible to accelerate +HMAC by enabling and accelerating: +- HMAC algorithm and key type, i.e. `[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_HMAC` and + `[PSA_WANT|MBEDTLS_PSA_ACCEL]KEY_TYPE_HMAC`. +- Required hash algorithm(s) as explained in [Hashes](#hashes) section. + +In such a build it is possible to disable legacy HMAC support by disabling +`MBEDTLS_MD_C` and still getting crypto operations, X.509 and TLS to work as +usual. Exceptions are: +- As mentioned in [Hashes](#hashes) direct calls to legacy lo-level hash APIs + (`mbedtls_sha256()` etc.) will not be possible for the legacy modules that + are disabled. +- Legacy HMAC support (`mbedtls_md_hmac_xxx()`) won't be possible. +- `MBEDTLS_PKCS[5|7]_C`, `MBEDTLS_HMAC_DRBG_C` and `MBEDTLS_HKDF_C` since they + depend on the legacy implementation of HMAC. + - disabling HMAC_DRBG_C cause deterministic ECDSA (i.e. + `MBEDTLS_DETERMINISTIC_ECDSA` on the legacy side and + `PSA_WANT_ALG_DETERMINISTIC_ECDSA` on the PSA one) to be not available. + +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 +- 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; +- 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 + (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, + +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 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`. + +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` + +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 + curve is identified not by name, but by explicit parameters; +- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE` - support for deterministic + derivation of an ECC keypair with `psa_key_derivation_output_key()`. + +Note: when any of the above options is enabled, a subset of `ecp.c` will +automatically be included in the build in order to support it. Therefore +you can still disable `MBEDTLS_ECP_C` in `mbedtls_config.h` and this will +result in some code size savings, but not as much as when none of the +above features are enabled. + +We do have plans to support each of these with `ecp.c` fully removed in the +future, however there is no established timeline. If you're interested, please +let us know, so we can take it into consideration in our planning. + +### Limitations regarding restartable / interruptible ECC 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`. + +Similarly, there is no PSA support for interruptible ECDH operations so these +are not supported without `ECDH_C`. See also limitations regarding +restartable operations with `MBEDTLS_USE_PSA_CRYPTO` in [its +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 "mixed" builds (driver and built-in) + +In order for a build to be driver-only (no built-in implementation), all the +requested algorithms, key types (key operations) and curves must be +accelerated (plus a few other restrictions, see "Limitations regarding fully +removing `ecp.c`" above). However, what if you have an accelerator that only +supports some algorithms, some key types (key operations), or some curves, but +want to have more enabled in you build? + +It is possible to have acceleration for only a subset of the requested +algorithms. In this case, the built-in implementation of the accelerated +algorithms will be disabled, provided all the requested curves and key types +that can be used with this algorithm are also declared as accelerated. + +There is very limited support for having acceleration for only a subset of the +requested key type operations. The only configuration that's tested is that of +a driver accelerating `PUBLIC_KEY`, `KEY_PAIR_BASIC`, `KEY_PAIR_IMPORT`, +`KEY_PAIR_EXPORT` but not `KEY_PAIR_GENERATE`. (Note: currently the driver +interface does not support `KEY_PAIR_DERIVE`.) + +There is limited support for having acceleration for only a subset of the +requested curves. In such builds, only the PSA API is currently tested and +working; there are known issues in PK, and X.509 and TLS are untested. + +Finite-field Diffie-Hellman +--------------------------- + +Support is pretty similar to the "Elliptic-curve cryptography (ECC)" section +above. +Key management and usage can be enabled by means of the usual `PSA_WANT` + +`MBEDTLS_PSA_ACCEL` pairs: + +- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_PUBLIC_KEY`; +- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_BASIC`; +- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_IMPORT`; +- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_EXPORT`; +- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_GENERATE`; + +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`, + - `PSA_WANT_KEY_TYPE_CAMELLIA`, + - `PSA_WANT_KEY_TYPE_CHACHA20`, + - `PSA_WANT_KEY_TYPE_DES`. +- Enable desired PSA algorithm(s): + - Unauthenticated ciphers modes: + - `PSA_WANT_ALG_CBC_NO_PADDING`, + - `PSA_WANT_ALG_CBC_PKCS7`, + - `PSA_WANT_ALG_CCM_STAR_NO_TAG`, + - `PSA_WANT_ALG_CFB`, + - `PSA_WANT_ALG_CTR`, + - `PSA_WANT_ALG_ECB_NO_PADDING`, + - `PSA_WANT_ALG_OFB`, + - `PSA_WANT_ALG_STREAM_CIPHER`. + - AEADs: + - `PSA_WANT_ALG_CCM`, + - `PSA_WANT_ALG_GCM`, + - `PSA_WANT_ALG_CHACHA20_POLY1305`. +- Enable `MBEDTLS_PSA_ACCEL_[KEY_TYPE_xxx|ALG_yyy]` symbol(s) which correspond + to the `PSA_WANT_KEY_TYPE_xxx` and `PSA_WANT_ALG_yyy` of the previous steps. +- Disable builtin support of key types: + - `MBEDTLS_AES_C`, + - `MBEDTLS_ARIA_C`, + - `MBEDTLS_CAMELLIA_C`, + - `MBEDTLS_DES_C`, + - `MBEDTLS_CHACHA20_C`. + and algorithms/modes: + - `MBEDTLS_CBC_C`, + - `MBEDTLS_CFB_C`, + - `MBEDTLS_CTR_C`, + - `MBEDTLS_OFB_C`, + - `MBEDTLS_XTS_C`, + - `MBEDTLS_CCM_C`, + - `MBEDTLS_GCM_C`, + - `MBEDTLS_CHACHAPOLY_C`, + - `MBEDTLS_NULL_CIPHER`. + +Once a key type and related algorithm are accelerated, all the PSA Crypto APIs +will work, as well as X.509 and TLS (with `MBEDTLS_USE_PSA_CRYPTO` enabled) but +some non-PSA APIs will be absent or have reduced functionality, see +[Restrictions](#restrictions) for details. + +### Restrictions + +- If an algorithm other than CCM and GCM (see + ["Partial acceleration for CCM/GCM"](#partial-acceleration-for-ccmgcm) below) + is enabled but not accelerated, then all key types that can be used with it + will need to be built-in. +- If a key type is enabled but not accelerated, then all algorithms that can be + used with it will need to be built-in. + +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 + `MBEDTLS_AES_C` and `MBEDTLS_DES_C` are both disabled. When only one of them + is enabled, then only the corresponding cipher will be available at runtime + for use with `mbedtls_cipher_cmac_xxx`. (Note: if there is driver support for + CMAC and all compatible key types, then `PSA_WANT_ALG_CMAC` can be enabled + without `MBEDTLS_CMAC_C` and CMAC will be usable with `psa_max_xxx` APIs.) +- `MBEDTLS_CIPHER_C`: the `mbedtls_cipher_xxx()` APIs will only work with + ciphers that are built-in - that is, both the underlying cipher + (eg `MBEDTLS_AES_C`) and the mode (eg `MBEDTLS_CIPHER_MODE_CBC` or + `MBEDTLS_GCM_C`). +- `MBEDTLS_PKCS5_C`: encryption/decryption (PBES2, PBE) will only work with + ciphers that are built-in. +- PEM decryption will only work with ciphers that are built-in. +- PK parse will only be able to parse encrypted keys using built-in ciphers. + +Note that if you also disable `MBEDTLS_CIPHER_C`, there will be additional +restrictions, see [Disabling `MBEDTLS_CIPHER_C`](#disabling-mbedtls_cipher_c). + +### Legacy <-> PSA matching + +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`. +- In the legacy API, `MBEDTLS_CHACHA20_C` enables the ChaCha20 stream cipher, and + enabling `MBEDTLS_CHACHAPOLY_C` also enables the ChaCha20-Poly1305 AEAD. In the + PSA API, you need to enable `PSA_KEY_TYPE_CHACHA20` for both, plus + `PSA_ALG_STREAM_CIPHER` or `PSA_ALG_CHACHA20_POLY1305` as desired. +- The legacy symbol `MBEDTLS_CCM_C` adds support for both cipher and AEAD, + whereas in PSA there are 2 different symbols: `PSA_WANT_ALG_CCM_STAR_NO_TAG` + and `PSA_WANT_ALG_CCM`, respectively. + +### Partial acceleration for CCM/GCM + +[This section depends on #8598 so it might be updated while that PR progresses.] + +In case legacy CCM/GCM algorithms are enabled, it is still possible to benefit +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()` (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. + +ChaChaPoly has no such feature, so it requires full acceleration (key type + +algorithm) in order to work with a driver. + +### CTR-DRBG + +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`. + +### Disabling `MBEDTLS_CIPHER_C` + +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). +- Either TLS is disabled, or `MBEDTLS_USE_PSA_CRYPTO` is enabled. +- `MBEDTLS_NIST_KW` is disabled. +- `MBEDTLS_CMAC_C` is disabled. (Note: support for CMAC in PSA can be provided by + 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. + +Note: AEAD ciphers (CCM, GCM, ChachaPoly) do not have a dependency on +MBEDTLS_CIPHER_C even when using the built-in implementations. + +If you also have some ciphers fully accelerated and the built-ins removed, see +[Restrictions](#restrictions) for restrictions related to removing the built-ins. + + + |