Skip to content

crypto: mbedtls_crypto_alt: replace legacy Mbed TLS crypto with PSA API and prepare for TF-PSA-Crypto 1.0#125

Open
valeriosetti wants to merge 33 commits intozephyrproject-rtos:mainfrom
valeriosetti:prepare-mbedtls4
Open

crypto: mbedtls_crypto_alt: replace legacy Mbed TLS crypto with PSA API and prepare for TF-PSA-Crypto 1.0#125
valeriosetti wants to merge 33 commits intozephyrproject-rtos:mainfrom
valeriosetti:prepare-mbedtls4

Conversation

@valeriosetti
Copy link

@valeriosetti valeriosetti commented Feb 24, 2026

Do all the changes which are required to make HostAP compatible with Mbed TLS 4.x/TF-PSA-Crypto 1.x.

It's a draft because tests are still in progress.

This will be integrated into Zephyr from zephyrproject-rtos/zephyr#104031

@valeriosetti valeriosetti changed the title Prepare mbedtls4 crypto: mbedtls_crypto_alt: replace legacy Mbed TLS crypto with PSA API and prepare for TF-PSA-Crypto 1.0 Feb 24, 2026
@valeriosetti valeriosetti force-pushed the prepare-mbedtls4 branch 3 times, most recently from 64a9b34 to 573a6a6 Compare February 26, 2026 23:03
Since TF-PSA-Crypto the signature of mbedtls_nist_kw_wrap() and
mbedtls_nist_kw_unwrap() have changed. Now they use a PSA API key
instead of a legacy context.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
…tion

Starting from TF-PSA-Crypto 1.0 PK functions won't require RNG function
to be specified on input.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
HKDF legacy crypto module was removed from TF-PSA-Crypto and now only PSA
API must be used for this scope.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Remove inclusion of most legacy crypto headers, but add bignum that was
missing.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Remove usage of legacy crypto (ecp, ecdsa, ...) as much as possible and
move to tf-psa-crypto allowed functions.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
@MaochenWang1
Copy link
Collaborator

Hi @valeriosetti
based on your latest PR codebase, I add some changes in the hostap repo to fix the build error, and now the build is passed.
Should I push my commit on top of your commits in this same PR? What's your suggestion?

@valeriosetti
Copy link
Author

Hi @valeriosetti based on your latest PR codebase, I add some changes in the hostap repo to fix the build error, and now the build is passed. Should I push my commit on top of your commits in this same PR? What's your suggestion?

Please wait, I'm working on that in parallel. Changes that I recently pushed here and zephyrproject-rtos/zephyr#104031 should make the build to work correctly.
Can you give this a try?

@MaochenWang1
Copy link
Collaborator

MaochenWang1 commented Feb 27, 2026

Hi @valeriosetti based on your latest PR codebase, I add some changes in the hostap repo to fix the build error, and now the build is passed. Should I push my commit on top of your commits in this same PR? What's your suggestion?

Please wait, I'm working on that in parallel. Changes that I recently pushed here and zephyrproject-rtos/zephyr#104031 should make the build to work correctly. Can you give this a try?

I already rebased on your latest zephyr and hostap PR and I just check the local SHA values, same as yours.
There are still some errors I locally faced, as I use west build -p always -b rd_rw612_bga samples/net/wifi/shell -d wifi -DEXTRA_CONF_FILE="nxp/overlay_rw612.conf nxp/overlay_hostap_rw612.conf" to build.
I can wait and keep the change locally.
BTW, I find the WPA3 connection failure issue after the build passed, debugging this issue now.

"psa_generate_random()" in Zephyr automatically uses either a real
entropy driver or a fallback based on CTR-DRBG/HMAC-DRBG. There is no
need to reimplement the mechanism in HostAP.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
When there is the possibility to chose between legacy crypto and PSA API
always opt for the latter. This is equivalent to assume
CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA always set and then
removing dead code.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
DHE and RSA based key exchanges were removed from Mbed TLS 4.0.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
mbedtls_pk_get_type -> mbedtls_pk_get_key_type
mbedtls_pk_type_t -> mbedtls_pk_sigalg_t

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
This is now an internal module in TF-PSA-Crypto and it cannot be used
directly.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
DES and 3DES have been removed from cipher module.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
@MaochenWang1
Copy link
Collaborator

Based on the latest codebase, there is new build error, which is not seen yesterday:

/home/nxf75317/zephyr-sdk-0.17.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: zephyr/libzephyr.a(ms_funcs.c.obj): in function `challenge_response':
/home/nxf75317/code/zephyr_github/modules/lib/hostap/src/crypto/ms_funcs.c:150: undefined reference to `des_encrypt'
/home/nxf75317/zephyr-sdk-0.17.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /home/nxf75317/code/zephyr_github/modules/lib/hostap/src/crypto/ms_funcs.c:151: undefined reference to `des_encrypt'
/home/nxf75317/zephyr-sdk-0.17.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /home/nxf75317/code/zephyr_github/modules/lib/hostap/src/crypto/ms_funcs.c:156: undefined reference to `des_encrypt'
/home/nxf75317/zephyr-sdk-0.17.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: zephyr/libzephyr.a(ms_funcs.c.obj): in function `nt_password_hash_encrypted_with_block':
/home/nxf75317/code/zephyr_github/modules/lib/hostap/src/crypto/ms_funcs.c:499: undefined reference to `des_encrypt'
/home/nxf75317/zephyr-sdk-0.17.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: /home/nxf75317/code/zephyr_github/modules/lib/hostap/src/crypto/ms_funcs.c:500: undefined reference to `des_encrypt'
/home/nxf75317/zephyr-sdk-0.17.4/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: zephyr/libzephyr.a(ms_funcs.c.obj):/home/nxf75317/code/zephyr_github/modules/lib/hostap/src/crypto/ms_funcs.c:499: more undefined references to `des_encrypt' follow
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

It looks like MBEDTLS_DES_C is not defined in hostap perspective.

@MaochenWang1
Copy link
Collaborator

MaochenWang1 commented Feb 28, 2026

Just removing MBEDTLS_DES_C in the hostap can fix the build error.
With some local patches, the WPA3 connection can be successful (@valeriosetti if you agree, I can push my commit on top of your commits in this same PR, or I just hold the patch locally.).

For wifi enterprise test cases:
EAP-TLS with TLS 1.2, PEAPv0-MSCHAPv2, PEAPv1-GTC, EAP-PEAP-TLS are all successful.
EAP-TTLS-MSCHAPv2 is failed as CONFIG_FIPS is enabled by default, and @krish2718 is checking it.
EAP-TLS with TLS 1.3 is failed, return error in ssl_tls13_handle_hs_message_post_handshake.
image
the callstack is
image

Hi @valeriosetti I tried to disable MBEDTLS_SSL_SESSION_TICKETS, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED and MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED, then the connection is successful, but I am not sure if it's a correct way to fix this issue.
I also found that there is a commit in Mbedtls 3.6 https://github.com/Mbed-TLS/mbedtls/pull/9507/changes#diff-67127675c5612072a0cb4c12b6dd40b0cfdcc6cdb23839f48ce9e3a2257e77e7, but is missing in Mbedtls 4.x, which might affect this issue. Does Mbedtls4.x needs it?

Setting MBEDTLS_DES_C when building TF-PSA-Crypto is now prohibited
because the symbols is both related to legacy crypto and its support
has been removed from the library.

Remove the guard for simplicity. If DES is not available the build will
fail anyway.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
@valeriosetti
Copy link
Author

valeriosetti commented Feb 28, 2026

Just removing MBEDTLS_DES_C in the hostap can fix the build error.

Added one more commit to implement this. Thanks for the notification.

I tried to disable MBEDTLS_SSL_SESSION_TICKETS, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED and MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED, then the connection is successful, but I am not sure if it's a correct way to fix this issue.

I don't know at all details of EAP-TLS with TLS 1.3. However the name suggests that it relies on TLS 1.3 and based on your comment you are disabling TLS 1.3 key exchanges, which makes me suspect the connection falls back to TLS 1.2? If that's the case then I don't know if this is fine or not...

I also found that there is a commit in Mbedtls 3.6 https://github.com/Mbed-TLS/mbedtls/pull/9507/changes#diff-67127675c5612072a0cb4c12b6dd40b0cfdcc6cdb23839f48ce9e3a2257e77e7, but is missing in Mbedtls 4.x, which might affect this issue. Does Mbedtls4.x needs it?

In Mbed TLS 4 I found the following:

So perhaps in Mbed TLS 4 the commit you pointed to is not present because it's handled differently?

You can try to temporarly add the build symbol to modules/lib/openthread/third_party/mbedtls/mbedtls-config.h, set it to a value you think it's correct, and then re-run the test. If that works I will add the proper Kconfig for it (which I think it's missing now)

…euse

Rework crypto_ecdh_init2() to clone the original PSA key using
psa_copy_key() and wrap it into a new mbedtls_pk_context. The previous
implementation copied the pk context directly, causing both contexts to
share the same key_id. As a result, deinit of one context could destroy
a key still in use. The new approach ensures a separate volatile key
instance with its own key_id, and preserves key attributes and public
key data.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
Update ECDH public key export and peer key processing to align with
mbedtls 4.x PSA-based APIs.
Uses psa_export_public_key() as the source of truth for EC points.
Supports both compressed and uncompressed peer key formats.
Handles X/Y reconstruction for compressed keys using mbedtls_ecp APIs.
Rebuilds SubjectPublicKeyInfo DER with compressed ECPoint correctly.
These updates restore DPP provisioning and authentication flows under
mbedtls 4.x.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
Fix an issue in crypto_ec_key_set_pub() where pub_raw_len was left as
zero after populating the X and Y coordinates. This caused
crypto_ec_key_get_pubkey_point() to fail because the PK context
reported no public key data.
This fix updates pub_raw_len as bytes are written and sets
pk_info to mbedtls_eckey_info, which is required by mbedtls 4.x
PK wrapping logic when handling externally constructed EC keys.
This restores correct DPP public key handling on mbedtls 4.x.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
Add NULL pointer checks to crypto_ecdh_deinit() and
crypto_ec_key_deinit() to avoid dereferencing invalid contexts. Without
these checks, callers that pass NULL could trigger crashes when
freeing pk contexts or destroying PSA key IDs.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
… DPP

Fix psa_copy_key() failures in DPP ECDH flow by adding
PSA_KEY_USAGE_COPY to all ECC keypair and key import usage flags.
Without this flag, mbedtls 4.x PSA enforces that a key cannot be
cloned, causing crypto_ecdh_init2() to fail during key copy.
Also set key lifetime to VOLATILE for imported private keys to match
mbedtls 4.x expectations and ensure the copied key can be created.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
Replace calls of os_calloc(sizeof(type), 1) with the correct form
os_calloc(1, sizeof(type)) to avoid argument order ambiguity and align
with standard allocation patterns used elsewhere in hostap.
Also fix buffer sizing in crypto_ec_key_get_ecprivate_key() by switching
from MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES to
MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES and replacing wpabuf_len() with
wpabuf_size() to match the mbedtls_pk_write_key_der() API expectations.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
Fix crypto_ec_key_cmp() where the previous implementation exported
private keys via PSA to compare them. However, the PK context
held an invalid/zero key_id, causing psa_export_key() to fail and the
comparison to be unreliable.
Switch to comparing the public key raw buffer (pub_raw/pub_raw_len)
only. This avoids dependence on key_id and PSA export, and provides a
stable equality check.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
Fix a memory corruption in DPP auth flow caused by a type size mismatch.
'psa_key_bits_t key_bits' (smaller than size_t on this platform) was
passed as '(size_t *)' to mbedtls_ecc_group_to_psa(), which wrote 4 bytes
into a 2-byte field and overflowed adjacent memory.
After dpp_set_pubkey_point(), auth->curve was corrupted (sometimes 0),
making auth->curve->hash_len a huge value and leading to crashes
(BUS fault in DPP authentication path).
Use 'size_t key_bits' instead of 'psa_key_bits_t' in keypaths,this
prevents out-of-bounds writes and restores stable DPP authentication.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
@MaochenWang1
Copy link
Collaborator

Hi @valeriosetti please review the new commit

Copy link
Author

@valeriosetti valeriosetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one minor comment on the last commit

PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
psa_set_key_enrollment_algorithm(&key_attr, PSA_ALG_ECDH);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning: using psa_set_key_enrollment_algorithm is fine when PSA API are provided by Mbed TLS, but this is their own custom extension to the official PSA API. Indeed when this is used in Mbed TLS codebase it is usually guarded by MBEDTLS_PSA_CRYPTO_C. See this for example.

Long story short: this works with Mbed TLS, but I'm not sure it works when TF-M is the PSA API provider.

This is the reason why I didn't use psa_set_key_enrollment_algorithm in my initial implementation. However I understand that it's handy when you don't know ahead of time for which goal the key will be used, so I'm not against it.

Copy link
Collaborator

@MaochenWang1 MaochenWang1 Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need to add MBEDTLS_PSA_CRYPTO_C guard here for psa_set_key_enrollment_algorithm?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can and this would make the code being able to build also with TF-M as crypto backend, but of course the fix you just added (i.e. assigning 2 algorithms to the same key) wouldn't work in that case.
I don't think there is an elegant way to solve this a part from creating 2 different keys with different algorithms associated, which is a bit of a burden.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the MBEDTLS_PSA_CRYPTO_C, currently I don't find a good way to fix this issue for TF-M case

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine for now. HostAP uses so much legacy crypto support from Mbed TLS that it's very far from using only PSA. This means that Mbed TLS is always present when we're building HostAP.

@rlubos
Copy link
Contributor

rlubos commented Mar 12, 2026

I've retested the latest changes with nrf7002dk/nrf5340/cpuapp, WPA/WPA2/WPA3/EAP with TLS1.3, all worked just fine 👍

In mbedtls 4.x, EC keys were set with PSA_ALG_ECDH as the only algorithm,
causing PSA_ERROR_NOT_PERMITTED when performing ECDSA signing (called by
crypto_ec_key_sign_r_s).
Set PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) as primary and PSA_ALG_ECDH as
enrollment algorithm, allowing keys to be used for both ECDSA signing
and ECDH key agreement.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
@MaochenWang1
Copy link
Collaborator

Hi @valeriosetti is this PR ready for review, could you change the mode from Draft to review mode?

@valeriosetti valeriosetti marked this pull request as ready for review March 16, 2026 08:03
@valeriosetti
Copy link
Author

Hi @valeriosetti is this PR ready for review, could you change the mode from Draft to review mode?

So are all tests passing now?

@MaochenWang1
Copy link
Collaborator

Hi @valeriosetti is this PR ready for review, could you change the mode from Draft to review mode?

So are all tests passing now?

basic tests pass

@tomi-font
Copy link

@krish2718 @rlubos please take a look when you have a moment

@krish2718
Copy link
Collaborator

@krish2718 @rlubos please take a look when you have a moment

I am waiting on go-ahead from our QA @krga2022 , will update soon. I guess Robert already verified all security on nRF70 platform.

When CONFIG_MBEDTLS_PSA_CRYPTO_LEGACY_RNG=y, Hostap still enters the
legacy CTR_DRBG code path, but MbedTLS 4.x with PSA no longer exposes
mbedtls_ctr_drbg_context or the classic CTR_DRBG API. This causes build
errors. Remove the unused CTR_DRBG declaration and initialization to
align with PSA RNG usage.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
@MaochenWang1
Copy link
Collaborator

add one commit to fix the build error when CONFIG_MBEDTLS_PSA_CRYPTO_LEGACY_RNG is enabled.

These modules were removed from TF-PSA-Crypto, but they are still used
in some Zephyr module so this commit brings them back.

Problematic modules are:
- DES, DHM --> HostAP
- ECDH --> ESP32 WiFi and BT drivers

Here's the commits where they were taken from in TF-PSA-Crypto upstream
repo:

- DES: cb169403b0055edde4fdcfcfb22c3524c7d2f370
- DHM: 5b636e8c7ea96f2af57f876253a9d94e1958f962
- ECDH: 882a2cd42a6c52a31f99a2349361233afdcec83c

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
@valeriosetti
Copy link
Author

I added 1 commit to move TF-PSA-Crypto "removed modules" from TF-PSA-Crypto fork to this one.
This was agreed with @carlescufi @tejlmand @rlubos @jukkar @frkv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants