Skip to content

Mbedtls 4 support (and esp-idf 6)#2174

Draft
petermm wants to merge 18 commits intoatomvm:release-0.7from
petermm:mbedtls-4-support
Draft

Mbedtls 4 support (and esp-idf 6)#2174
petermm wants to merge 18 commits intoatomvm:release-0.7from
petermm:mbedtls-4-support

Conversation

@petermm
Copy link
Contributor

@petermm petermm commented Mar 9, 2026

Esp-idf 6 - simtest - is included as it was an opportunity to test mbedtls4

Obviously this PR should be mbedtls4 only, and then esp-idf in another.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

@petermm petermm force-pushed the mbedtls-4-support branch 3 times, most recently from 94c6a0c to cc891a3 Compare March 20, 2026 20:02
@petermm petermm changed the base branch from main to release-0.7 March 20, 2026 20:22
@petermm petermm force-pushed the mbedtls-4-support branch from cc891a3 to 3ac52ed Compare March 21, 2026 11:32
petermm and others added 16 commits March 21, 2026 14:19
Signed-off-by: Peter M <petermm@gmail.com>
Signed-off-by: Peter M <petermm@gmail.com>
Avoid including mbedtls/pkcs5.h when building against mbedtls 4,
where that header is not available.

Keep the existing PKCS5-based pbkdf2_hmac implementation for
mbedtls 2/3, but switch the mbedtls 4 path to the PSA key
derivation API so crypto:pbkdf2_hmac/5 remains available.

Also update the feature/NIF guards so pbkdf2_hmac stays registered
on both legacy and mbedtls 4 builds.

Signed-off-by: Peter M <petermm@gmail.com>
Streamed cipher and MAC operations were deferring PSA key destruction
to the Erlang resource destructor (GC). On embedded devices this means
key material remains resident in PSA key storage longer than necessary.

Destroy the PSA key handle immediately after psa_cipher_finish and
psa_mac_sign_finish in crypto_final, mac_final, and mac_finalN.
The resource destructors now guard against double-destroy by checking
key_id != 0 before calling psa_destroy_key.

Amp-Thread-ID: https://ampcode.com/threads/T-019d108a-c8e4-72f4-924c-997ffe14adac
Co-authored-by: Amp <amp@ampcode.com>
Replace free() with secure_free() (which calls mbedtls_platform_zeroize
before freeing) for temporary buffers that may contain sensitive data:

- temp_buf and allocated_data_data in one-shot cipher (may hold plaintext)
- maybe_allocated_data and out_buf in streamed cipher update
- out_buf in streamed cipher final
- maybe_allocated_intext in AEAD (plaintext on encrypt, ciphertext on decrypt)

This matches the convention already used by the legacy mbedtls path and
ensures key material and plaintext are wiped from heap memory promptly,
which is important on embedded devices.

Amp-Thread-ID: https://ampcode.com/threads/T-019d108a-c8e4-72f4-924c-997ffe14adac
Co-authored-by: Amp <amp@ampcode.com>
When psa_mac_update or psa_cipher_update fails, the PSA operation is
left in an indeterminate state. Previously the error was raised but
the operation and key handle were left dangling until the resource
destructor ran at GC time.

Now on update failure:
- Abort the PSA operation immediately
- Destroy the PSA key and zero the key_id
- Mark cipher state as finalized to reject further calls
- Use secure_free for the input data buffer

The resource destructors already guard against key_id == 0, so the
subsequent GC cleanup remains safe.

Amp-Thread-ID: https://ampcode.com/threads/T-019d108a-c8e4-72f4-924c-997ffe14adac
Co-authored-by: Amp <amp@ampcode.com>
Move do_psa_init() out of #ifdef HAVE_PSA_CRYPTO into a broader guard
that covers all PSA availability scenarios (HAVE_PSA_CRYPTO,
MBEDTLS_PSA_CRYPTO_C, or mbedtls >= 4.0).

Add do_psa_init() calls to NIFs that were missing them:
- nif_crypto_hash (mbedtls 4.x path)
- nif_crypto_crypto_one_time (mbedtls 4.x path)
- nif_crypto_strong_rand_bytes (mbedtls 4.x path)

Replace the ad-hoc inline psa_crypto_init() in nif_crypto_pbkdf2_hmac
with the shared do_psa_init() for consistency.

Platform startup already calls psa_crypto_init() on all platforms, and
psa_crypto_init() is idempotent, so these calls are cheap no-ops in
practice but remove a brittle implicit dependency.

Amp-Thread-ID: https://ampcode.com/threads/T-019d108a-c8e4-72f4-924c-997ffe14adac
Co-authored-by: Amp <amp@ampcode.com>
PBKDF2 with zero iterations would silently produce weak/empty output.
Explicitly reject iterations == 0 with a clear error message.

Amp-Thread-ID: https://ampcode.com/threads/T-019d108a-c8e4-72f4-924c-997ffe14adac
Co-authored-by: Amp <amp@ampcode.com>
@petermm petermm force-pushed the mbedtls-4-support branch from 9efa913 to 5dcd891 Compare March 21, 2026 14:03
petermm added 2 commits March 21, 2026 16:29
Declare the PSA output buffer size variables before any goto-based cleanup path can skip their initialization.

This fixes Clang -Wsometimes-uninitialized failures in crypto_one_time/4-5 and crypto_update/2 when cleanup frees scratch buffers after early exits.
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.

1 participant