From 2c1de04e9d00080133ad6efdf01b4d3e86cfcf1e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 13 Sep 2024 16:45:07 +0200 Subject: [PATCH 1/8] adjust_legacy_crypto: move auto-enabling of CRYPTO_CLIENT when CRYPTO_C Move the auto-enabling of CRYPTO_CLIENT when CRYPTO_C at the beginning of the file so that all that becomes later is aware of this. Signed-off-by: Valerio Setti --- include/mbedtls/config_adjust_legacy_crypto.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h index 3ba987ebb..fe05c1a4b 100644 --- a/include/mbedtls/config_adjust_legacy_crypto.h +++ b/include/mbedtls/config_adjust_legacy_crypto.h @@ -48,6 +48,13 @@ #endif #endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */ +/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT + * is defined as well to include all PSA code. + */ +#if defined(MBEDTLS_PSA_CRYPTO_C) +#define MBEDTLS_PSA_CRYPTO_CLIENT +#endif /* MBEDTLS_PSA_CRYPTO_C */ + /* Auto-enable CIPHER_C when any of the unauthenticated ciphers is builtin * in PSA. */ #if defined(MBEDTLS_PSA_CRYPTO_C) && \ @@ -352,13 +359,6 @@ #define MBEDTLS_PK_CAN_ECDSA_SOME #endif -/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT - * is defined as well to include all PSA code. - */ -#if defined(MBEDTLS_PSA_CRYPTO_C) -#define MBEDTLS_PSA_CRYPTO_CLIENT -#endif /* MBEDTLS_PSA_CRYPTO_C */ - /* Helpers to state that each key is supported either on the builtin or PSA side. */ #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521) #define MBEDTLS_ECP_HAVE_SECP521R1 From c516307ad90d24de7f6f83e6b2fd825329ce5824 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 13 Sep 2024 10:55:22 +0200 Subject: [PATCH 2/8] md: allow dispatch to PSA whenever CRYPTO_CLIENT is enabled Instead of allowing PSA dispatching only when CRYPTO_C is set and some MBEDTLS_PSA_ACCEL_ALG_xxx is set, we enable dispatching when CRYPTO_CLIENT and PSA_WANT_ALG_xxx are set. This makes the feature more useful in cases where the PSA support is provided externally, like for example TF-M in Zephyr. This commit also add proper guards for tests trying to use MD+PSA dispatch. Signed-off-by: Valerio Setti --- include/mbedtls/config_adjust_legacy_crypto.h | 26 +++++++++---------- tests/suites/test_suite_md.function | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h index fe05c1a4b..2777f7d05 100644 --- a/include/mbedtls/config_adjust_legacy_crypto.h +++ b/include/mbedtls/config_adjust_legacy_crypto.h @@ -108,64 +108,64 @@ */ /* PSA accelerated implementations */ -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5) +#if defined(PSA_WANT_ALG_MD5) #define MBEDTLS_MD_CAN_MD5 #define MBEDTLS_MD_MD5_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) +#if defined(PSA_WANT_ALG_SHA_1) #define MBEDTLS_MD_CAN_SHA1 #define MBEDTLS_MD_SHA1_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) +#if defined(PSA_WANT_ALG_SHA_224) #define MBEDTLS_MD_CAN_SHA224 #define MBEDTLS_MD_SHA224_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) +#if defined(PSA_WANT_ALG_SHA_256) #define MBEDTLS_MD_CAN_SHA256 #define MBEDTLS_MD_SHA256_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) +#if defined(PSA_WANT_ALG_SHA_384) #define MBEDTLS_MD_CAN_SHA384 #define MBEDTLS_MD_SHA384_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) +#if defined(PSA_WANT_ALG_SHA_512) #define MBEDTLS_MD_CAN_SHA512 #define MBEDTLS_MD_SHA512_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) +#if defined(PSA_WANT_ALG_RIPEMD160) #define MBEDTLS_MD_CAN_RIPEMD160 #define MBEDTLS_MD_RIPEMD160_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224) +#if defined(PSA_WANT_ALG_SHA3_224) #define MBEDTLS_MD_CAN_SHA3_224 #define MBEDTLS_MD_SHA3_224_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256) +#if defined(PSA_WANT_ALG_SHA3_256) #define MBEDTLS_MD_CAN_SHA3_256 #define MBEDTLS_MD_SHA3_256_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384) +#if defined(PSA_WANT_ALG_SHA3_384) #define MBEDTLS_MD_CAN_SHA3_384 #define MBEDTLS_MD_SHA3_384_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512) +#if defined(PSA_WANT_ALG_SHA3_512) #define MBEDTLS_MD_CAN_SHA3_512 #define MBEDTLS_MD_SHA3_512_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#endif /* MBEDTLS_PSA_CRYPTO_C */ +#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ /* Built-in implementations */ #if defined(MBEDTLS_MD5_C) diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function index 4e62154f2..4497d042e 100644 --- a/tests/suites/test_suite_md.function +++ b/tests/suites/test_suite_md.function @@ -420,7 +420,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */ void md_psa_dynamic_dispatch(int md_type, int pre_psa_ret, int post_psa_engine) { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); From 460d2ee3633946590a2c0f3d486142873c8130e7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 17 Sep 2024 11:40:40 +0200 Subject: [PATCH 3/8] adjust_legacy_crypto: improve enablement of MBEDTLS_MD_xxx_VIA_PSA The previous change that replaced CRYPTO_C with CRYPTO_CLIENT caused an increase of the mbedtls_md struct in scenarios where the hash related PSA_WANTs were enabled, but not accelerated. This caused an ABI-API break which is not allowed for an LTS branch. Since the main goal here is to allow PSA dispatch in a "pure crypto client" scenario, we partially revert the previous change to config_adjust_legacy_crypto.h and add an extra condition for "CRYPTO_CLIENT && !CRYPTO_C". This commit also reverts changes done in analyze_outcomes.py because they are no more necessary. Signed-off-by: Valerio Setti --- include/mbedtls/config_adjust_legacy_crypto.h | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h index 2777f7d05..331ac9b2d 100644 --- a/include/mbedtls/config_adjust_legacy_crypto.h +++ b/include/mbedtls/config_adjust_legacy_crypto.h @@ -108,7 +108,65 @@ */ /* PSA accelerated implementations */ -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#if defined(MBEDTLS_PSA_CRYPTO_C) + +#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5) +#define MBEDTLS_MD_CAN_MD5 +#define MBEDTLS_MD_MD5_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) +#define MBEDTLS_MD_CAN_SHA1 +#define MBEDTLS_MD_SHA1_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) +#define MBEDTLS_MD_CAN_SHA224 +#define MBEDTLS_MD_SHA224_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) +#define MBEDTLS_MD_CAN_SHA256 +#define MBEDTLS_MD_SHA256_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) +#define MBEDTLS_MD_CAN_SHA384 +#define MBEDTLS_MD_SHA384_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) +#define MBEDTLS_MD_CAN_SHA512 +#define MBEDTLS_MD_SHA512_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) +#define MBEDTLS_MD_CAN_RIPEMD160 +#define MBEDTLS_MD_RIPEMD160_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224) +#define MBEDTLS_MD_CAN_SHA3_224 +#define MBEDTLS_MD_SHA3_224_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256) +#define MBEDTLS_MD_CAN_SHA3_256 +#define MBEDTLS_MD_SHA3_256_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384) +#define MBEDTLS_MD_CAN_SHA3_384 +#define MBEDTLS_MD_SHA3_384_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512) +#define MBEDTLS_MD_CAN_SHA3_512 +#define MBEDTLS_MD_SHA3_512_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif + +#elif defined(MBEDTLS_PSA_CRYPTO_CLIENT) #if defined(PSA_WANT_ALG_MD5) #define MBEDTLS_MD_CAN_MD5 @@ -165,7 +223,8 @@ #define MBEDTLS_MD_SHA3_512_VIA_PSA #define MBEDTLS_MD_SOME_PSA #endif -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ + +#endif /* !MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */ /* Built-in implementations */ #if defined(MBEDTLS_MD5_C) From 1a2d07d83ac0cd2abf0d1fad12a7dfab5998dfac Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 23 Jan 2025 11:10:48 +0100 Subject: [PATCH 4/8] docs: update md-cipher-dispatch Signed-off-by: Valerio Setti --- .../psa-migration/md-cipher-dispatch.md | 84 ++++++++++--------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/docs/architecture/psa-migration/md-cipher-dispatch.md b/docs/architecture/psa-migration/md-cipher-dispatch.md index eda65a348..89b7b61ef 100644 --- a/docs/architecture/psa-migration/md-cipher-dispatch.md +++ b/docs/architecture/psa-migration/md-cipher-dispatch.md @@ -17,36 +17,44 @@ A difference between the original strategy and the current one is that in this w #### Backward compatibility user story -As a developer of an application that uses Mbed TLS's interfaces (including legacy crypto), -I want Mbed TLS to preserve backward compatibility, +As a developer of an application that uses Mbed TLS's interfaces (including legacy crypto), +I want Mbed TLS to preserve backward compatibility, so that my code keeps working in new minor versions of Mbed TLS. #### Interface design user story -As a developer of library code that uses Mbed TLS to perform cryptographic operations, -I want to know which functions to call and which feature macros to check, +As a developer of library code that uses Mbed TLS to perform cryptographic operations, +I want to know which functions to call and which feature macros to check, so that my code works in all Mbed TLS configurations. Note: this is the same problem we face in X.509 and TLS. #### Hardware accelerator vendor user stories -As a vendor of a platform with hardware acceleration for some crypto, -I want to build Mbed TLS in a way that uses my hardware wherever relevant, +As a vendor of a platform with hardware acceleration for some crypto, +I want to build Mbed TLS in a way that uses my hardware wherever relevant, so that my customers maximally benefit from my hardware. -As a vendor of a platform with hardware acceleration for some crypto, -I want to build Mbed TLS without software that replicates what my hardware does, +As a vendor of a platform with hardware acceleration for some crypto, +I want to build Mbed TLS without software that replicates what my hardware does, to minimize the code size. +#### Integrators of Mbed TLS alongside a PSA Crypto provider + +I have a platform where the PSA Crypto is already provided "externally" from +Mbed TLS (ex: through TF-M in Zephyr) and I would like Mbed TLS to make use +of it whenever possible in order to benefit from higher performances (if some +hardware acceleration is supported in the provider) and/or higher isolation/security +(if the PSA provider is running in a completetly separated/inaccessible context). + #### Maintainer user stories -As a maintainer of Mbed TLS, -I want to have clear rules for when to use which interface, +As a maintainer of Mbed TLS, +I want to have clear rules for when to use which interface, to avoid bugs in “unusual” configurations. -As a maintainer of Mbed TLS, -I want to avoid duplicating code, +As a maintainer of Mbed TLS, +I want to avoid duplicating code, because this is inefficient and error-prone. ### Use PSA more @@ -55,8 +63,8 @@ In the long term, all code using cryptography should use PSA interfaces, to bene The goal of this work is to arrange for more non-PSA interfaces to use PSA interfaces under the hood, without breaking code in the cases where this doesn't work. Using PSA interfaces has two benefits: -* Where a PSA driver is available, it likely has better performance, and sometimes better security, than the built-in software implementation. -* In many scenarios, where a PSA driver is available, this allows removing the software implementation altogether. +* Where a PSA driver/provider is available, it likely has better performance, and sometimes better security, than the built-in software implementation. +* In many scenarios, where a PSA driver/provider is available, this allows removing the software implementation altogether. * We may be able to get rid of some redundancies, for example the duplication between the implementations of HMAC in `md.c` and in `psa_crypto_mac.c`, and HKDF in `hkdf.c` and `psa_crypto.c`. ### Correct dependencies @@ -72,7 +80,6 @@ All documented behavior must be preserved, except for interfaces currently descr The following configuration options are described as experimental, and are likely to change at least marginally: * `MBEDTLS_PSA_CRYPTO_CLIENT`: “This interface is experimental and may change or be removed without notice.” In practice we don't want to remove this, but we may constrain how it's used. -* `MBEDTLS_PSA_CRYPTO_DRIVERS`: “This interface is experimental. We intend to maintain backward compatibility with application code that relies on drivers, but the driver interfaces may change without notice.” In practice, this may mean constraints not only on how to write drivers, but also on how to integrate drivers into code that is platform code more than application code. * `MBEDTLS_PSA_CRYPTO_CONFIG`: “This feature is still experimental and is not ready for production since it is not completed.” We may want to change this, for example, to automatically enable more mechanisms (although this wouldn't be considered a backward compatibility break anyway, since we don't promise that you will not get a feature if you don't enable its `PSA_WANT_xxx`). ### Non-goals @@ -190,7 +197,7 @@ Note: PSA cipher is built on Cipher, but PSA AEAD directly calls the underlying Here are some reasons why calling `psa_xxx()` to perform a hash or cipher calculation might not be desirable in some circumstances, explaining why the application would arrange to call the legacy software implementation instead. -* `MBEDTLS_PSA_CRYPTO_C` is disabled. +* `MBEDTLS_PSA_CRYPTO_CLIENT` is disabled. * There is a PSA driver which has not been initialized (this happens in `psa_crypto_init()`). * For ciphers, the keystore is not initialized yet, and Mbed TLS uses a custom implementation of PSA ITS where the file system is not accessible yet (because something else needs to happen first, and the application takes care that it happens before it calls `psa_crypto_init()`). A possible workaround may be to dispatch to the internal functions that are called after the keystore lookup, rather than to the PSA API functions (but this is incompatible with `MBEDTLS_PSA_CRYPTO_CLIENT`). * The requested mechanism is enabled in the legacy interface but not in the PSA interface. This was not really intended, but is possible, for example, if you enable `MBEDTLS_MD5_C` for PEM decoding with PBKDF1 but don't want `PSA_ALG_WANT_MD5` because it isn't supported for `PSA_ALG_RSA_PSS` and `PSA_ALG_DETERMINISTIC_ECDSA`. @@ -208,7 +215,7 @@ Generally speaking, modules in the mixed domain: #### Non-support guarantees: requirements -Generally speaking, just because some feature is not enabled in `mbedtls_config.h` or `psa_config.h` doesn't guarantee that it won't be enabled in the build. We can enable additional features through `build_info.h`. +Generally speaking, just because some feature is not enabled in `mbedtls_config.h` or `crypto_config.h` doesn't guarantee that it won't be enabled in the build. We can enable additional features through `build_info.h` and other header files included there (`*adjust*.h`). If `PSA_WANT_xxx` is disabled, this should guarantee that attempting xxx through the PSA API will fail. This is generally guaranteed by the test suite `test_suite_psa_crypto_not_supported` with automatically enumerated test cases, so it would be inconvenient to carve out an exception. @@ -331,14 +338,10 @@ Note that this applies to TLS 1.3 as well, as some uses of hashes and all uses o This will go away naturally in 4.0 when this macros is not longer an option (because it's always on). -#### Don't support for `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C` +#### Support for `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C` We generally don't really support builds with `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`. For example, both `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_SSL_PROTO_TLS1_3` require `MBEDTLS_PSA_CRYPTO_C`, while in principle they should only require `MBEDTLS_PSA_CRYPTO_CLIENT`. -Considering this existing restriction which we do not plan to lift before 4.0, it is acceptable driver-only hashes and cipher support to have the same restriction in 3.x. - -It is however desirable for the design to keep support for `MBEDTLS_PSA_CRYPTO_CLIENT` in mind, in order to avoid making it more difficult to add in the future. - #### For cipher: prioritize constrained devices and modern TLS The primary target is a configuration like TF-M's medium profile, plus TLS with only AEAD ciphersuites. @@ -420,8 +423,9 @@ Unlike the full MD, MD light does not support null pointers as `mbedtls_md_conte For each hash algorithm, `md.h` defines a macro `MBEDTLS_MD_CAN_xxx` whenever the corresponding hash is available through MD light. These macros are only defined when `MBEDTLS_MD_LIGHT` is enabled. Per “[Availability of hashes](#availability-of-hashes)”, `MBEDTLS_MD_CAN_xxx` is enabled if: -* the corresponding `MBEDTLS_xxx_C` is defined; or -* one of `MBEDTLS_PSA_CRYPTO_C` or `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, and the corresponding `PSA_WANT_ALG_xxx` is enabled. +* the corresponding `MBEDTLS_xxx_C` is defined. +* `MBEDTLS_PSA_CRYPTO_C` is enabled and the corresponding `PSA_WANT_ALG_xxx` and `MBEDTLS_PSA_ACCEL_ALG_xxx` are enabled. This enables driver acceleration support. +* `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled the corresponding `PSA_WANT_ALG_xxx` is enabled. Then the Mbed TLS library must be linked against the PSA Crypto provider one which will eventually handle all PSA calls. Note that some algorithms have different spellings in legacy and PSA. Since MD is a legacy interface, we'll use the legacy names. Thus, for example: @@ -440,7 +444,7 @@ for now this is out of scope. #### MD light internal support macros -* If at least one hash has a PSA driver, define `MBEDTLS_MD_SOME_PSA`. +* If at least one hash has a PSA driver or support in PSA Crypto provider, define `MBEDTLS_MD_SOME_PSA`. * If at least one hash has a legacy implementation, defined `MBEDTLS_MD_SOME_LEGACY`. #### Support for PSA in the MD context @@ -488,15 +492,24 @@ static inline psa_algorithm_t psa_alg_of_md_info( #### Determination of PSA support at runtime +Mbed TLS defines internal symbols `MBEDTLS_MD_xxx_VIA_PSA` which are used to check if the `xxx` hash algorithm is supported in PSA. They are enabled when: + +* `MBEDTLS_PSA_CRYPTO_C && MBEDTLS_PSA_ACCEL_ALG_xxx`, i.e. when the PSA Crypto core is built with Mbed TLS and the `xxx` is accelerated through a driver. +* `MBEDTLS_PSA_CRYPTO_CLIENT && PSA_WANT_ALG_xxx`, i.e. there is a PSA Crypto provider/server which supports `xxx` hash algorithm. + +MD internally uses the following private function to determine if PSA can be used at runtime or not: + ``` -int psa_can_do_hash(psa_algorithm_t hash_alg); +static int md_can_use_psa(const mbedtls_md_info_t *info) ``` -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. +Internally this function does the following: -As a starting point, return 1 if PSA crypto's driver subsystem has been initialized. +* First of all it converts the `mbedtls_md_info_t` to `psa_algorithm_t`. The result of this conversion is based on the `MBEDTLS_MD_xxx_VIA_PSA` symbols: if an algorithm does not have the corresponding `MBEDTLS_MD_xxx_VIA_PSA` enabled, then `md_can_use_psa` will return false. -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`. +* `int psa_can_do_hash(psa_algorithm_t hash_alg)` is then used to further checking if the PSA Crypto core has been initialized or not. If so then `md_can_use_psa` will finally succeed, otherwise it will fail. + +To be noted that in client/server builds (i.e. `MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C`) the implementer of the client interface is expected to provide psa_can_do_hash(). #### Support for PSA dispatch in hash operations @@ -506,7 +519,7 @@ If given an established context, use its `engine` field. If given an algorithm as an `mbedtls_md_type_t type` (possibly being the `type` field of a `const mbedtls_md_info_t *`): -* If there is a PSA accelerator for this hash and `psa_can_do_hash(alg)`, call the corresponding PSA function, and if applicable set the engine to `MBEDTLS_MD_ENGINE_PSA`. (Skip this is `MBEDTLS_MD_SOME_PSA` is not defined.) +* If there is a PSA accelerator/provider for this hash and `md_can_use_psa` succeeds, call the corresponding PSA function, and if applicable set the engine to `MBEDTLS_MD_ENGINE_PSA`. (Skip this is `MBEDTLS_MD_SOME_PSA` is not defined.) * Otherwise dispatch to the legacy module based on the type as currently done. (Skip this is `MBEDTLS_MD_SOME_LEGACY` is not defined.) * If no dispatch is possible, return `MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE`. @@ -522,7 +535,7 @@ As discussed in [“Implications between legacy availability and PSA availabilit > If an algorithm has a legacy implementation, it is also available through PSA. -When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, this is already the case. When is enabled, we will now make it so as well. Change `include/mbedtls/config_psa.h` accordingly. +When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, this is already the case. When is enabled, `include/config_adjust_psa_superset_legacy.h` will ensure that PSA configuration is always a superset of what's enabled in legacy. ### MD light optimizations @@ -557,15 +570,6 @@ Work in progress on this conversion is at https://github.com/gilles-peskine-arm/ PSA has its own HMAC implementation. In builds with both `MBEDTLS_MD_C` and `PSA_WANT_ALG_HMAC` not fully provided by drivers, we should have a single implementation. Replace the one in `md.h` by calls to the PSA driver interface. This will also give mixed-domain modules access to HMAC accelerated directly by a PSA driver (eliminating the need to a HMAC interface in software if all supported hashes have an accelerator that includes HMAC support). -### Improving support for `MBEDTLS_PSA_CRYPTO_CLIENT` - -So far, MD light only dispatches to PSA if an algorithm is available via `MBEDTLS_PSA_CRYPTO_C`, not if it's available via `MBEDTLS_PSA_CRYPTO_CLIENT`. This is acceptable because `MBEDTLS_USE_PSA_CRYPTO` requires `MBEDTLS_PSA_CRYPTO_C`, hence mixed-domain code never invokes PSA. - -The architecture can be extended to support `MBEDTLS_PSA_CRYPTO_CLIENT` with a little extra work. Here is an overview of the task breakdown, which should be fleshed up after we've done the first [migration](#migration-to-md-light): - -* 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 (previously known as "Cipher light") #### Definition From 05b3835bd62c3378eb231b468dda14d43f5ce44d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 21 Feb 2025 14:40:51 +0100 Subject: [PATCH 5/8] psa: move definition of psa_can_do_hash() to crypto_extra.h This allows any implementer of the PSA client interface to easily include this header and therefore function's prototype. Signed-off-by: Valerio Setti --- include/psa/crypto_extra.h | 26 ++++++++++++++++++++++++++ library/psa_crypto_core.h | 12 ------------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index f48c0873b..b991c866b 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -583,6 +583,32 @@ psa_status_t mbedtls_psa_platform_get_builtin_key( /** @} */ +/** \defgroup psa_crypto_client Functions defined by a client provider + * + * The functions in this group are meant to be implemented by providers of + * the PSA Crypto client interface. They are provided by the library when + * #MBEDTLS_PSA_CRYPTO_C is enabled. + * + * \note All functions in this group are experimental, as using + * alternative client interface providers is experimental. + * + * @{ + */ + +/** + * Tell if PSA is ready for this hash. + * + * \note For now, only checks the state of the driver subsystem, + * not the algorithm. Might do more in the future. + * + * \param hash_alg The hash algorithm (ignored for now). + * + * \return 1 if the driver subsytem is ready, 0 otherwise. + */ +int psa_can_do_hash(psa_algorithm_t hash_alg); + +/**@}*/ + /** \addtogroup crypto_types * @{ */ diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index df0ee501a..c3c077014 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -24,18 +24,6 @@ #include "mbedtls/threading.h" #endif -/** - * Tell if PSA is ready for this hash. - * - * \note For now, only checks the state of the driver subsystem, - * not the algorithm. Might do more in the future. - * - * \param hash_alg The hash algorithm (ignored for now). - * - * \return 1 if the driver subsytem is ready, 0 otherwise. - */ -int psa_can_do_hash(psa_algorithm_t hash_alg); - /** * Tell if PSA is ready for this cipher. * From 79a98bd7b63f31bed9fb19d1df0a0c9eedc3569e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 21 Feb 2025 15:00:11 +0100 Subject: [PATCH 6/8] crypto_extra: improve description of psa_can_do_hash() Signed-off-by: Valerio Setti --- include/psa/crypto_extra.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index b991c866b..a046ba577 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -595,15 +595,18 @@ psa_status_t mbedtls_psa_platform_get_builtin_key( * @{ */ -/** - * Tell if PSA is ready for this hash. +/** Check if PSA is capable of handling the specified hash algorithm. * - * \note For now, only checks the state of the driver subsystem, - * not the algorithm. Might do more in the future. + * This means that PSA core was built with the corresponding PSA_WANT_ALG_xxx + * set and that psa_crypto_init has already been called. * - * \param hash_alg The hash algorithm (ignored for now). + * \note When using Mbed TLS version of PSA core (i.e. MBEDTLS_PSA_CRYPTO_C is + * set) for now this function only checks the state of the driver + * subsystem, not the algorithm. This might be improved in the future. * - * \return 1 if the driver subsytem is ready, 0 otherwise. + * \param hash_alg The hash algorithm. + * + * \return 1 if the PSA can handle \p hash_alg, 0 otherwise. */ int psa_can_do_hash(psa_algorithm_t hash_alg); From cc1b26bd9a31642a1afcae135c758fe636b47fb9 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 23 Jan 2025 16:22:05 +0100 Subject: [PATCH 7/8] changelog: add note for MD changes Signed-off-by: Valerio Setti --- ChangeLog.d/9652.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 ChangeLog.d/9652.txt diff --git a/ChangeLog.d/9652.txt b/ChangeLog.d/9652.txt new file mode 100644 index 000000000..98a8eae4d --- /dev/null +++ b/ChangeLog.d/9652.txt @@ -0,0 +1,9 @@ +Features + * MD module can now perform PSA dispatching also when + `MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C`, even though this + configuration is not officially supported. This requires that a + PSA Crypto provider library which: + * supports the required `PSA_WANT_ALG_xxx` and + * implements `psa_can_do_hash()` on the client interface + is linked against Mbed TLS and that `psa_crypto_init()` is called before + performing any PSA call. From bc55af83d3942b4401a54e27f24564a788bf4d1e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 22 Jan 2025 16:34:26 +0100 Subject: [PATCH 8/8] framework: update reference Signed-off-by: Valerio Setti --- framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework b/framework index 523a12d05..b5dc86cfe 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 523a12d05b91301b020e2aa560d9774135e3a801 +Subproject commit b5dc86cfe7f1f15626bc43e6720447a0a51860b9