Separate configuration option for PSA threading support to avoid enabling full library threading #691

Open
opened 2026-02-12 00:51:40 -06:00 by Ashish285 · 4 comments
Ashish285 commented 2026-02-12 00:51:40 -06:00 (Migrated from github.com)

Summary

Hi all,
After the PSA migration, TLS operations now use a centralized PSA key management interface that requires MBEDTLS_THREADING_C for thread-safety, even when using separate thread-specific SSL contexts. This forces applications to enable threading support for the entire library, which may not be necessary or desired for all components.
In Mbed TLS 3.6.5 and earlier versions, applications could use separate thread-specific SSL contexts without requiring threading support, as each context managed its own keys independently.

Currently, these PSA-specific mutexes are only compiled when both MBEDTLS_THREADING_C and MBEDTLS_PSA_CRYPTO_C are enabled

This creates an all-or-nothing situation:

  • To enable PSA key store thread-safety (required for multi-threaded TLS), MBEDTLS_THREADING_C must be enabled
  • Enabling MBEDTLS_THREADING_C enables threading support for the entire library, adding mutex overhead to all components

Previously (pre-PSA migration), such applications didn't need MBEDTLS_THREADING_C. Now they do, which changes the threading behavior of the entire library.

Question

Is this architectural coupling of PSA threading with general library threading intentional, or is there a plan to introduce PSA level threading?

System information

TF-PSA-Crypto version (number or commit id): 1.0.0
Operating system and version: Linux
Configuration (if not default, please attach crypto_config.h): Default
Compiler and options (if you used a pre-built binary, please indicate how you obtained it): gcc
Additional environment information:

### Summary Hi all, After the PSA migration, TLS operations now use a centralized PSA key management interface that requires [MBEDTLS_THREADING_C](https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/development/docs/architecture/psa-thread-safety/psa-thread-safety.md#thread-safety-of-the-psa-subsystem) for thread-safety, even when using separate thread-specific SSL contexts. This forces applications to enable threading support for the entire library, which may not be necessary or desired for all components. In Mbed TLS 3.6.5 and earlier versions, applications could use separate thread-specific SSL contexts without requiring threading support, as each context managed its own keys independently. Currently, these PSA-specific mutexes are only compiled when both MBEDTLS_THREADING_C and MBEDTLS_PSA_CRYPTO_C are enabled This creates an all-or-nothing situation: * To enable PSA key store thread-safety (required for multi-threaded TLS), `MBEDTLS_THREADING_C` must be enabled * Enabling `MBEDTLS_THREADING_C` enables threading support for the entire library, adding mutex overhead to all components Previously (pre-PSA migration), such applications didn't need `MBEDTLS_THREADING_C`. Now they do, which changes the threading behavior of the entire library. ### Question Is this architectural coupling of PSA threading with general library threading intentional, or is there a plan to introduce PSA level threading? ### System information TF-PSA-Crypto version (number or commit id): 1.0.0 Operating system and version: Linux Configuration (if not default, please attach `crypto_config.h`): Default Compiler and options (if you used a pre-built binary, please indicate how you obtained it): gcc Additional environment information:
gilles-peskine-arm commented 2026-02-12 03:54:55 -06:00 (Migrated from github.com)

PSA is not just a cryptographic operations API, but also a random generation API and a key store API. The random generator and the key store are both global state that is shared between threads, which is why MBEDTLS_THREADING_C is needed even if each end-user of cryptography sticks to its own thread.

It would technically be possible to provide a way to build the library without shared state between threads, giving each thread its own random generator and its own key store. To do that, we would need either explicit crypto contexts for every function, or a way to make the crypto globals be thread-local storage.

Explicit crypto contexts would be useful for multiple niche use cases. It's been requested before. But it's a lot of work because it affects basically every function in the library. It's not something that we refuse in principle, but I can only see it happening if someone who is not from the current maintenance team 1. does the initial work and 2. commits to continuing to maintain it.

Making the crypto globals be thread-local storage would be a relatively doable change, but it would result in a very special-purpose build. I think this is something we could accept as a contribution and then continue maintaining. Note that the contribution would have to include proper testing, which is probably harder to set up than the feature itself.

PSA is not just a cryptographic operations API, but also a random generation API and a key store API. The random generator and the key store are both global state that is shared between threads, which is why `MBEDTLS_THREADING_C` is needed even if each end-user of cryptography sticks to its own thread. It would technically be possible to provide a way to build the library without shared state between threads, giving each thread its own random generator and its own key store. To do that, we would need either explicit crypto contexts for every function, or a way to make the crypto globals be thread-local storage. Explicit crypto contexts would be useful for multiple niche use cases. [It's been requested before](https://github.com/Mbed-TLS/mbedtls/issues/7685). But it's a lot of work because it affects basically every function in the library. It's not something that we refuse in principle, but I can only see it happening if someone who is not from the current maintenance team 1. does the initial work and 2. commits to continuing to maintain it. Making the crypto globals be thread-local storage would be a relatively doable change, but it would result in a very special-purpose build. I think this is something we could accept as a contribution and then continue maintaining. Note that the contribution would have to include proper testing, which is probably harder to set up than the feature itself.
Ashish285 commented 2026-02-12 07:49:17 -06:00 (Migrated from github.com)

Hi @gilles-peskine-arm , thanks for your reply.

My question was not on why PSA requires threading support, but instead why specifically MBEDTLS_THREADING_C.

For the key and RNG management, it appears three mutex are in use mbedtls_threading_key_slot_mutex, mbedtls_threading_psa_globaldata_mutex and mbedtls_threading_psa_rngdata_mutex which are all exclusively used inside the tf-psa-crypto.
But now enabling MBEDTLS_THREADING_C enables these mutex but also mutex inside other operations which might not require the thread safety.

My thought was that if we can have a separate config to enable the thread safety for PSA subsystem, MBEDTLS_PSA_THREADING_C which specifically enables the required threading support for PSA subsystem but not for other components. Thanks!

Hi @gilles-peskine-arm , thanks for your reply. My question was not on why PSA requires threading support, but instead why specifically `MBEDTLS_THREADING_C`. For the key and RNG management, it appears three mutex are in use `mbedtls_threading_key_slot_mutex`, `mbedtls_threading_psa_globaldata_mutex` and `mbedtls_threading_psa_rngdata_mutex` which are all exclusively used inside the tf-psa-crypto. But now enabling `MBEDTLS_THREADING_C` enables these mutex but also mutex inside other operations which might not require the thread safety. My thought was that if we can have a separate config to enable the thread safety for PSA subsystem, `MBEDTLS_PSA_THREADING_C` which specifically enables the required threading support for PSA subsystem but not for other components. Thanks!
gilles-peskine-arm commented 2026-02-12 08:34:27 -06:00 (Migrated from github.com)

But now enabling MBEDTLS_THREADING_C enables these mutex but also mutex inside other operations which might not require the thread safety.

What other operations? In Mbed TLS 3.6, there were crypto data structures with mutexes. But they are gone since TF-PSA-Crypto 1.0. Now there are mutexes in:

  • platform_util.c if your platform lacks gmtime_r()
  • library/x509_crt.c for readdir()
  • ctr_drbg.c, hmac_drbg.c and entropy.c (internal details of the RNG)
  • memory_buffer_alloc.c
  • psa_crypto.c and core/psa_crypto_slot_management.c for the PSA keystore and the PSA RNG
  • bignum_core.c only in debug builds
  • library/ssl_cache.c
  • library/ssl_ticket.c
> But now enabling MBEDTLS_THREADING_C enables these mutex but also mutex inside other operations which might not require the thread safety. What other operations? In Mbed TLS 3.6, there were crypto data structures with mutexes. But they are gone since TF-PSA-Crypto 1.0. Now there are mutexes in: * `platform_util.c` if your platform lacks `gmtime_r()` * `library/x509_crt.c` for `readdir()` * `ctr_drbg.c`, `hmac_drbg.c` and `entropy.c` (internal details of the RNG) * `memory_buffer_alloc.c` * `psa_crypto.c` and `core/psa_crypto_slot_management.c` for the PSA keystore and the PSA RNG * `bignum_core.c` only in debug builds * `library/ssl_cache.c` * `library/ssl_ticket.c`
Ashish285 commented 2026-02-12 09:59:39 -06:00 (Migrated from github.com)

Ah, it used to be there in rsa.c (which is why I saw performance impact) in v1.0.0 but it seems it has been removed in the current development branch.

Ah, it used to be there in [rsa.c](https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/v1.0.0/drivers/builtin/src/rsa.c#L958) (which is why I saw performance impact) in v1.0.0 but it seems it has been removed in the current development branch.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-Mbed-TLS/TF-PSA-Crypto#691
No description provided.