Skip to content

Add stm32H5 TrustZone wolfHSM Port#348

Open
aidangarske wants to merge 3 commits into
wolfSSL:mainfrom
aidangarske:wolfhsm-h5-port
Open

Add stm32H5 TrustZone wolfHSM Port#348
aidangarske wants to merge 3 commits into
wolfSSL:mainfrom
aidangarske:wolfhsm-h5-port

Conversation

@aidangarske
Copy link
Copy Markdown
Member

Description

  • Adds port/stmicro/stm32-tz/wh_transport_nsc.{c,h}: a portable
    synchronous TrustZone non-secure-callable bridge transport for
    ARMv8-M Cortex-M targets. Client Send invokes a host-supplied
    veneer (wcs_wolfhsm_transmit) inline and caches the response;
    client Recv consumes the cached response on the first call.
    Server-side callbacks consume the request the host's veneer parked
    in a static context and write the response back into the non-secure
    caller's buffer.
  • Target-agnostic. The STM32H5-specific glue (NSC veneer, flash
    adapter, secure-side server init, NS test exerciser) lives in the
    matching wolfBoot PR.
  • New STM32_TZ_NSC=1 build flag in test/Makefile compiles the
    transport into the host test build and pulls in a new unit test
    test/wh_test_transport_nsc.c covering BADARGS, NOTREADY, happy-
    path round trip, and the request_pending / rsp_size state
    machine for both callback tables.
  • New CI lane in .github/workflows/build-and-test.yml:
    STM32_TZ_NSC=1 ASAN=1 build + run.
  • Docs: new "STM32 TrustZone (STM32H5 / NSC bridge)" section in
    docs/src/chapter08.md.

Notes

  • Companion wolfBoot PR adds WOLFCRYPT_TZ_WOLFHSM=1 for STM32H5,
    which is the first consumer of this transport. here

Test plan

  • STM32_TZ_NSC=1 ASAN=1 build + make run (CI)
  • Existing CI matrix unaffected (no changes outside the new port)
  • End-to-end on STM32H5 NUCLEO-H563ZI via the wolfBoot PR

Copilot AI review requested due to automatic review settings May 1, 2026 23:30
@aidangarske aidangarske self-assigned this May 1, 2026

This comment was marked as resolved.

wolfSSL-Fenrir-bot

This comment was marked as low quality.

@aidangarske aidangarske marked this pull request as ready for review May 12, 2026 01:43
@aidangarske aidangarske requested a review from danielinux May 12, 2026 01:43
@bigbrett bigbrett self-assigned this May 12, 2026
Copy link
Copy Markdown
Contributor

@bigbrett bigbrett left a comment

Choose a reason for hiding this comment

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

@aidangarske thanks for this! I'm little unclear whether any of this stm32H5 specific or is just a generic TZ-M compatible transport? In the docs you say

The transport itself is target-agnostic; the STM32H5-specific glue (NSC veneer, whFlashCb flash adapter, secure-side server init, NS test exerciser) lives in the wolfBoot port.

If this is the case then I don't think you need any mention of STM32H5 in any of this? Unless I'm misunderstanding. If this is meant to be a generic trustzone M transport then I think having under port/tzm or something like that is better, with no mentions of STM32H5 at all.

LMK if I'm misunderstanding

@bigbrett bigbrett removed their assignment May 12, 2026
@bigbrett bigbrett marked this pull request as draft May 13, 2026 14:49
@bigbrett
Copy link
Copy Markdown
Contributor

@aidangarske reverting to draft after our conversation yesterday

@aidangarske aidangarske force-pushed the wolfhsm-h5-port branch 7 times, most recently from 92edc94 to c8bce36 Compare May 25, 2026 23:02
@aidangarske aidangarske marked this pull request as ready for review May 26, 2026 17:24
Comment on lines +2 to +4
# the STM32H5 TZ demo under m33mu. Informational until m33mu's
# data-dependent ECDH issue is fixed upstream; NUCLEO-H563ZI hardware
# is the authoritative validation (log in PR description).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I assume the data-dependent ECDH issue is fixed upstream? Either way, pls refine this comment to be less ai-ish

Comment on lines +11 to +17
- 'port/armv8m-tz/**'
- 'wolfhsm/wh_transport*.h'
- 'wolfhsm/wh_client*.h'
- 'src/wh_client*.c'
- 'src/wh_server*.c'
- 'test/wh_test.c'
- '.github/workflows/wolfboot-tz-integration.yml'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

at this point I'd either remove the paths and have it run on every PR or only scope it to port/armv8m-tz

@@ -0,0 +1,27 @@
# STM32H5 TrustZone port — lives in wolfBoot

This directory is a pointer, not an implementation.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pls no

Comment thread src/wh_server.c
/* A fresh INIT after a prior CLOSE must put the channel back into
* the connected state so the subsequent request loop accepts non-
* COMM groups again. */
wh_Server_SetConnected(server, WH_COMM_CONNECTED);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is not correct and should not be set here. Exactly where this is set is on a per-transport basis. In the SHM transport this must be set via an out-of-band signal after the client has zeroed out the shared memory.

Comment thread src/wh_server.c
if ( (server->connected == WH_COMM_DISCONNECTED) ||
(data == NULL) ) {
/* Valid data pointer? */
if (data == NULL) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why did we remove the connected guard?

Comment thread src/wh_server.c
Comment on lines +546 to +549
/* When disconnected, only allow COMM-group messages through so the
* client can re-establish (INIT), interrogate (INFO/ECHO) or repeat
* a CLOSE on the channel. Any other request is rejected with
* NOTREADY until a fresh INIT brings the channel back up. */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

unfortunately this is not the flow. Connected is a bit of a misnomer. It is more a signal that the transport is ready for use.

Comment thread src/wh_server_keystore.c
Comment on lines +320 to +325
/* Last-resort fallback: every slot is occupied by an uncommitted
* key (typical when many ephemeral keys are cached in succession
* with no intervening commit). Reclaim the first non-erased slot
* so the cache cannot saturate on transient state alone. Drops
* the slot's in-flight contents; the caller's request gets the
* slot fresh. */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think this is correct behavior. It is perfectly fine to fail if the client is trying to cache more keys than the server can handle without committing. It should be up to the client to evict manually in this case. At least that is how it was intended to work. Same issue below with the big cache.

Comment on lines +207 to +211
#ifdef WOLFHSM_CFG_PORT_ARMV8M_TZ_NSC
#include "wh_transport_nsc.h"
whTransportNscClientContext whTransportNscClientContext_test;
whTransportNscServerContext whTransportNscServerContext_test;
#endif /* WOLFHSM_CFG_PORT_ARMV8M_TZ_NSC */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why did we add these to the padding check? This should only hold "wire structures"

Comment thread wolfhsm/wh_settings.h
* time in microseconds as a uint64_t. Must be defined in wolfhsm_cfg.h for
* the active port UNLESS WOLFHSM_CFG_NO_SYS_TIME is defined
*
* WOLFHSM_CFG_PORT_ARMV8M_TZ_NSC - If defined, build the ARMv8-M TrustZone
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I dont think we want a separate compilation guard for port-specific stuff. Core library features, yes, but that is because the library code should support being wildcard compiled. Port stuff needs to be explicitly opted in and compiled manually so there is no sense in requiring a new core library config macro for it

Comment thread docs/src/chapter08.md
- Single-call NSC transport (no polling, no shared-memory ring): client `Send` invokes the host-supplied veneer inline and caches the response; client `Recv` consumes the cached response on the first call (subsequent calls return `WH_ERROR_NOTREADY` until the next `Send`).
- Server-side callbacks that consume the request the host's veneer parked in a static context and write the response back to the non-secure caller's buffer.

The transport is target-agnostic. Bringing it up on a new ARMv8-M part is a porting exercise on the host side only: provide the `cmse_nonsecure_entry` veneer that fronts `wcs_wolfhsm_transmit`, plus whatever flash/NVM adapter and server init the deployment needs.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This line doesnt make sense. "Host side only"? Is that meant to indicate non-secure world only? But flash/NVM should live in secure world. This doc could use a human touch...

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.

4 participants