Skip to content

Add Mbed TLS 4.1 / TF-PSA-Crypto 1.1 test coverage to simulator#2713

Open
d3zd3z wants to merge 8 commits intomcu-tools:mainfrom
d3zd3z:add-mbedtls-v4
Open

Add Mbed TLS 4.1 / TF-PSA-Crypto 1.1 test coverage to simulator#2713
d3zd3z wants to merge 8 commits intomcu-tools:mainfrom
d3zd3z:add-mbedtls-v4

Conversation

@d3zd3z
Copy link
Copy Markdown
Member

@d3zd3z d3zd3z commented Apr 24, 2026

Summary

Adds a second ext/mbedtls-4.1.0 submodule and a new mbedtls-v4 Cargo feature so MCUboot's PSA-based crypto paths can be built and tested against the Mbed TLS 4.x release series alongside the existing 3.6 LTS. The 4.x path is fully opt-in — default builds are unchanged.

Why not an in-place bump: Mbed TLS 4.x relocates the legacy crypto API to a private-header tier and splits sources across a new tf-psa-crypto submodule, so a straight bump would force every MCUboot feature path (sig-rsa, sig-ecdsa-mbedtls, enc-rsa, enc-ec256-mbedtls, enc-x25519-mbedtls, plus every PSA path) to be reworked at once. Keeping 3.6 in place for the legacy paths while migrating the PSA paths to 4.1 incrementally is tractable.

Approach

  • Rename ext/mbedtlsext/mbedtls-3.6.0, add ext/mbedtls-4.1.0 as a second submodule (pinned at v4.1.0).
  • Drive the 4.1 build through its own CMakeLists.txt (ext/mbedtls-4.1.0/tf-psa-crypto) rather than recompiling a hand-picked file list from build.rs — the same shift Zephyr made when it moved to 4.1. Our only inputs become the config header and a few CMake -D knobs.
  • New mbedtls-v4 Cargo feature selects the 4.x build for sig-ecdsa-psa, with follow-up commits enabling enc-ec256 and enc-aes256-ec256 PSA encryption on top.
  • Three small local carry patches to boot/bootutil/src/encrypted_psa.c so it compiles under 4.1 with -Werror -Wall -Wextra (private OID header → raw bytes, pointer-sign cast, unused-parameter attribute). Flagged as temporary carry intended to flow back upstream.

CI coverage

New matrix rows exercise mbedtls-v4 across:

  • sig-ecdsa-psa (mirror of the existing 3.6 entry plus sig-p384 / swap-move variant)
  • Orthogonal features (swap-offset, validate-primary-slot, overwrite-only, multiimage)
  • Reset-resilience / XIP / rollback (ram-load, direct-xip, overwrite-only + downgrade-prevention, hw-rollback-protection + multiimage)
  • enc-ec256 and enc-aes256-ec256 on the PSA path

Developer requirements

The CMake-driven 4.x build needs cmake in PATH and jinja2 + jsonschema available to the Python the build invokes (the 4.x CMake invokes Python generators for psa_crypto_driver_wrappers* and config-check headers). Both are added to scripts/requirements.txt.

Coordination with #2680

This series and #2680 (boot:crypto Add custom crypto support) both touch sim/mcuboot-sys/build.rs, and the edits are almost certainly going to conflict.

Test plan

  • cargo test --features sig-ecdsa-psa,mbedtls-v4 -- --test-threads=1 → 25/25
  • cargo test --features sig-ecdsa-psa,enc-ec256,mbedtls-v4 -- --test-threads=1 → 25/25
  • cargo test --features sig-ecdsa-psa,enc-aes256-ec256,mbedtls-v4 → 25/25
  • cargo build --features sig-ecdsa-psa (no mbedtls-v4) — 3.6 path unchanged
  • CI across the full new matrix

d3zd3z added 8 commits April 26, 2026 21:23
cryptography 47.0.0 (released April 2026) bumps its PyO3 minimum
supported PyPy version to 3.11. Pip-installing imgtool's deps on
PyPy 3.9 or 3.10 now fails during the cryptography wheel build
with

  error: the configured PyPy interpreter version (3.10) is lower
         than PyO3's minimum supported version (3.11)

so every PR run against this workflow fails on those two matrix
entries. The matrix that landed in 95a6e38 ("imgtool: python
version coverage") was green at the time because it ran against
cryptography 46.x; the next push exposed the issue.

Drop pypy3.9 and pypy3.10 from the matrix, keep pypy3.11. CPython
coverage is unchanged.

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
Rename the Mbed TLS submodule's path from ext/mbedtls to
ext/mbedtls-3.6.0 to make room for a second submodule pinned at
Mbed TLS 4.1.0, which will be added in a follow-up. This clears
the way to build and test MCUboot's PSA-based crypto paths against
the Mbed TLS 4.x release series alongside the current 3.6 LTS.

The dual-submodule arrangement lets the simulator's legacy-crypto
feature paths (sig-rsa, sig-ecdsa-mbedtls, enc-rsa, enc-ec256-mbedtls,
enc-x25519-mbedtls) continue using the 3.6 LTS series while new and
PSA-based code migrates to 4.1 incrementally. Mbed TLS 4.x relocates
the legacy crypto API to a private/ header tier and splits sources
across a new tf-psa-crypto submodule, so a straight in-place bump
would force all feature paths to be reworked at once.

No content change for the submodule itself; it stays at v3.6.0
(2ca6c285a0). Updated:
- .gitmodules path entry
- .mbedignore
- sim/mcuboot-sys/build.rs (all 148 source/include paths)
- boot/espressif/CMakeLists.txt and crypto_config/rsa.cmake
- docs/readme-espressif.md (instructions for submodule init)

No changes required in boot/zephyr/, which uses Zephyr's own mbedtls
module rather than this submodule.

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
Add Mbed TLS v4.1.0 alongside the existing 3.6.0 submodule. Nothing
in the tree references this path yet; wiring up the simulator or
any OS port against 4.1 comes in follow-up commits as each feature
is migrated.

Mbed TLS 4.x restructures the repository into a top-level tree for
TLS/X.509/etc and a nested tf-psa-crypto submodule for crypto. A
shared framework/ submodule holds build infrastructure. After
cloning, run:

    git submodule update --init --recursive ext/mbedtls-4.1.0

to fetch both nested submodules.

Pinned commit: 0fe989b6b5 (v4.1.0).

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
Drive the Mbed TLS 4.1 (TF-PSA-Crypto 1.1.0) build through its own
CMakeLists.txt instead of recompiling a hand-picked file list from
build.rs. This follows the same shift Zephyr made when it moved to
Mbed TLS 4.1: stop shadowing the upstream build and let upstream own
the (still-evolving) 4.x file layout, generator plumbing, and config-
adjustment logic. Our only inputs become the config header and a
handful of CMake -D knobs.

What changed:

- `sim/mcuboot-sys/Cargo.toml`: new `mbedtls-v4` feature and
  `cmake = "0.1"` build-dep.
- `sim/Cargo.toml`: forwards the feature to `mcuboot-sys`.
- `sim/mcuboot-sys/csupport/config-ec-psa-v4.h`: minimal TF-PSA-Crypto
  1.1.0 configuration (PSA_WANT_* macros); the 4.x build auto-derives
  legacy MBEDTLS_*_C internals.
- `sim/mcuboot-sys/build.rs`: new `add_mbedtls_v4_psa_ecdsa()` branch
  invokes the `cmake` crate on `ext/mbedtls-4.1.0/tf-psa-crypto` with
  `TF_PSA_CRYPTO_CONFIG_FILE` + `ENABLE_{PROGRAMS,TESTING}=OFF`,
  builds the `tfpsacrypto` target, and links the resulting static
  library. The boot-code cc::Build gets the matching include paths
  and `-DTF_PSA_CRYPTO_CONFIG_FILE` so public headers see the same
  config.
- `sim/mcuboot-sys/csupport/psa_rng_stub_v4.c`: self-contained stub
  for `mbedtls_psa_external_get_random` + the test-RNG enable/disable
  toggles. The equivalent upstream test shim drags in the whole
  test-framework header tree; verification-only tests only need a
  symbol that resolves and returns bytes.
- `scripts/requirements.txt`: `jinja2`, `jsonschema` — the 4.x
  CMake's GEN_FILES path invokes Python generators for
  `psa_crypto_driver_wrappers*` and `tf_psa_crypto_config_check_*.h`.

Tested (arm64 macOS):
- `MCUBOOT_SKIP_SLOW_TESTS=1 cargo test --features \
   sig-ecdsa-psa,mbedtls-v4 -- --test-threads=1` → 25/25.
- `cargo build --features sig-ecdsa-psa` (no mbedtls-v4) still
  builds against 3.6.0 unchanged.

Developers need `cmake` in PATH and `jinja2`+`jsonschema` available
to the Python the build invokes.

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
Add three new matrix rows exercising the `mbedtls-v4` Cargo feature
across orthogonal feature combinations:

1. Mirror of the existing sig-ecdsa-psa row with `mbedtls-v4`
   appended (base, sig-p384, swap-move+bootstrap+max-align-16). The
   CMake-driven 4.x build is expected to match the 3.6 path here
   since the crypto config is the same shape.
2. Orthogonal features untested on the 3.6 sig-ecdsa-psa path
   (swap-offset, validate-primary-slot, overwrite-only, multiimage).
   These don't touch the crypto surface, so they ought to work on
   4.1 too; good shakedown of the CMake build surface.
3. Reset-resilience / XIP / rollback combinations (ram-load,
   direct-xip, overwrite-only+downgrade-prevention,
   hw-rollback-protection+multiimage).

Verified locally with `ptest -t 63..=73 run`: 11/11 pass.

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
Three carry patches to make boot/bootutil/src/encrypted_psa.c compile
under Mbed TLS 4.1 with the simulator's -Werror -Wall -Wextra:

- Define MBEDTLS_OID_EC_ALG_UNRESTRICTED / _EC_GRP_SECP256R1 locally
  when unavailable. In 4.x these moved from the public
  `mbedtls/oid.h` to a private header
  (`tf-psa-crypto/utilities/crypto_oid.h`); supply the raw OID bytes
  rather than depend on a private include path.
- Cast the "MCUBoot_ECIES_v1" literal to `const uint8_t *` when
  handed to psa_key_derivation_input_bytes, silencing
  -Wpointer-sign.
- Mark `blk_off` as intentionally unused in bootutil_aes_ctr_{encrypt,
  decrypt}; the PSA cipher API handles CTR block alignment
  internally. Silences -Wunused-parameter.

Temporary local carries. File was originally written against Mbed TLS
3.x PSA mode; these should flow back upstream as a proper 4.x
compatibility fix, at which point this commit can be dropped.

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
…s-v4

On the 3.6 path, `sig-ecdsa-psa enc-ec256` falls into the
`psa_crypto_init_stub.c` shim: PSA init is a no-op and the actual
ECIES work runs on TinyCrypt. On the mbedtls-v4 path we can do
better — the tfpsacrypto library is already being linked for the
signature side, so route image encryption through it too.

What changed:

- `sim/mcuboot-sys/csupport/config-ec-psa-v4.h`: new
  `#if defined(MCUBOOT_ENCRYPT_EC256)` block enabling PSA_WANT_*
  entries for ECDH, HKDF, CTR, HMAC, AES, HMAC keys, and
  ECC_KEY_PAIR_{DERIVE,IMPORT}. ECC curve (SECP_R1_256) is already on
  unconditionally for the signature path.
- `sim/mcuboot-sys/build.rs`:
  - `add_mbedtls_v4_psa_ecdsa()` now takes `enc_ec256` and forwards
    `-DMCUBOOT_ENCRYPT_EC256` to the CMake build so the library and
    boot code evaluate `#if defined(...)` identically.
  - New `enc_ec256 && mbedtls_v4` branch: pulls in both
    `encrypted.c` (high-level `boot_enc_*` interface) and
    `encrypted_psa.c` (PSA primitives under `MCUBOOT_USE_PSA_CRYPTO`),
    does not define `MCUBOOT_USE_TINYCRYPT` (incompatible with
    `MCUBOOT_USE_PSA_CRYPTO`), and defines `CONFIG_BOOT_ECDSA_PSA`
    to gate out `encrypted.c`'s duplicated legacy ASN.1 + ECDH
    block (which references `MBEDTLS_OID_*` macros no longer public
    in 4.x).
  - Skip `MBEDTLS_CONFIG_FILE=<config-asn1.h>` when `mbedtls-v4`
    is set — 4.x uses `TF_PSA_CRYPTO_CONFIG_FILE` instead.
- `.github/workflows/sim.yaml`: new matrix row mirroring the 3.6
  enc-ec256 entries, now exercising real PSA.

Tested: `MCUBOOT_SKIP_SLOW_TESTS=1 cargo test --features \
sig-ecdsa-psa,enc-ec256,mbedtls-v4 --test core -- \
--test-threads=1` → 25/25. Pre-existing 3.6 combinations (with and
without mbedtls-v4) unchanged.

Depends on boot/encrypted_psa local-carry patch (previous commit)
for the file to compile cleanly under 4.x + -Werror.

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
enc-aes256-ec256 shares the ECIES-P256 machinery with enc-ec256 and
differs only in BOOT_ENC_KEY_SIZE (32 bytes vs. 16), gated by
MCUBOOT_AES_256. PSA_KEY_TYPE_AES covers all AES key sizes, so no
additional PSA_WANT_* entries are required — this is purely a
build.rs branch-extension plus a matrix row.

Changes:
- build.rs: the `enc_ec256 && mbedtls_v4` branch now also matches
  `enc_aes256_ec256 && mbedtls_v4`, defining MCUBOOT_AES_256 when
  the latter is selected. add_mbedtls_v4_psa_ecdsa() is told
  enc-ec256-equivalent encryption is active via
  `enc_ec256 || enc_aes256_ec256`, so it forwards
  `-DMCUBOOT_ENCRYPT_EC256` to CMake.
- build.rs: guard the `config-ec.h` MBEDTLS_CONFIG_FILE selection
  with `!mbedtls_v4` so enc-aes256-ec256+mbedtls-v4 doesn't pick up
  the 3.6-style config header.
- .github/workflows/sim.yaml: mirror of the 3.6 enc-aes256-ec256
  entries, routed through the PSA path.

Tested (arm64 macOS):
- `cargo test --features sig-ecdsa-psa,enc-aes256-ec256,mbedtls-v4`
  → 25/25.
- ptest -t 74..77 (enc-ec256 + enc-aes256-ec256 mbedtls-v4 entries)
  → 4/4.
- Pre-existing 3.6 entries 19, 20, 50 (enc-aes256-ec256 on 3.6)
  unchanged.

Assisted-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: David Brown <david.brown@linaro.org>
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