Skip to content

Add stm32H5 TrustZone wolfHSM Port#348

Draft
aidangarske wants to merge 6 commits intowolfSSL:mainfrom
aidangarske:wolfhsm-h5-port
Draft

Add stm32H5 TrustZone wolfHSM Port#348
aidangarske wants to merge 6 commits intowolfSSL: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

  New port/stmicro/stm32-tz/wh_transport_nsc.{c,h} implementing both
  client and server callbacks for a synchronous TrustZone NSC bridge.
  The non-secure (client) side calls a single cmse_nonsecure_entry
  veneer (wcs_wolfhsm_transmit, provided by the host) which hands the
  request to the secure-side server context, runs
  wh_Server_HandleRequestMessage once inline, and returns the response
  in the same call -- no polling, notify counter, or async
  producer/consumer.

  Send delivers; Recv returns the cached response. Server-side Recv
  hands the request the host's NSC veneer parked in the static context;
  Send writes the response back into the NS buffer and stores its size
  for the veneer to read.

  Used by wolfBoot's WOLFCRYPT_TZ_WOLFHSM=1 lane on STM32H5 (separate
  PR against wolfBoot). Gated by WOLFHSM_CFG_PORT_STM32_TZ_NSC so the
  file is safe to ship in the wolfHSM tree without forcing every
  consumer to link the unresolved wcs_wolfhsm_transmit extern.
The field name is self-describing; the comment was duplicating it.
Add a port section describing the new port/stmicro/stm32-tz NSC bridge
transport: synchronous single-call client Send/Recv, server-side static
context, target-agnostic transport with the STM32H5 glue (NSC veneer,
whFlashCb adapter, secure-side server init, NS test exerciser) living in
the wolfBoot port.
  Transport (port/stmicro/stm32-tz/wh_transport_nsc):
  - _NscServerSend returns WH_ERROR_BADARGS for size validation
    (only ABORTED when rsp_buf is NULL), matching the contract.
  - _NscClientSend / _NscClientRecv reject calls on an
    uninitialized context, giving ctx->initialized a purpose.
  - _NscServerRecv clears request_pending on the oversize path
    and resets rsp_size on entry to prevent stale-value leaks.
  - Drop the redundant cmd_buf staging copy on the client side,
    saving WH_COMM_MTU bytes of NS BSS plus a per-request memcpy.

  Test:
  - New test/wh_test_transport_nsc.c covering BADARGS, NOTREADY,
    happy path, and the request_pending / rsp_size state machine
    for both callback tables. Wired into whTest_Unit; new
    STM32_TZ_NSC=1 build flag compiles the transport source.

  Docs:
  - chapter08: client Recv consumes the cached response on the
    first call (subsequent calls return WH_ERROR_NOTREADY).
Copilot AI review requested due to automatic review settings May 1, 2026 23:30
@aidangarske aidangarske self-assigned this May 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an STM32 TrustZone NSC bridge transport port (targeting ARMv8-M TrustZone use cases like STM32H5 + wolfBoot) along with unit tests, CI coverage, and documentation.

Changes:

  • Introduces port/stmicro/stm32-tz/wh_transport_nsc.{c,h} implementing synchronous NSC-based client/server transport callbacks.
  • Adds a host-side unit test (wh_test_transport_nsc.c) plus a build flag (STM32_TZ_NSC=1) to compile/run it in the test harness.
  • Extends CI workflow and documentation to cover the new TrustZone NSC bridge transport.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/wh_test_transport_nsc.h Declares new NSC transport unit test entrypoint.
test/wh_test_transport_nsc.c Adds unit tests + a stub veneer to validate client/server callback state machines.
test/wh_test.c Registers the new unit test behind WOLFHSM_CFG_PORT_STM32_TZ_NSC.
test/Makefile Adds STM32_TZ_NSC=1 build flag to compile the new port and tests.
port/stmicro/stm32-tz/wh_transport_nsc.h Defines NSC client/server contexts, config stubs, and callback externs.
port/stmicro/stm32-tz/wh_transport_nsc.c Implements synchronous NSC transport callbacks for client and server.
docs/src/chapter08.md Documents the new STM32 TrustZone (STM32H5 / NSC bridge) port.
.github/workflows/build-and-test.yml Adds CI lane to build/run tests with STM32_TZ_NSC=1 ASAN=1.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +99 to +115
static int _NscClientRecv(void* context, uint16_t* out_size, void* data)
{
whTransportNscClientContext* ctx = (whTransportNscClientContext*)context;

if (ctx == NULL || out_size == NULL || data == NULL ||
ctx->initialized == 0U) {
return WH_ERROR_BADARGS;
}
if (ctx->last_rsp_size == 0U) {
return WH_ERROR_NOTREADY;
}

memcpy(data, ctx->rsp_buf, ctx->last_rsp_size);
*out_size = ctx->last_rsp_size;
ctx->last_rsp_size = 0;
return WH_ERROR_OK;
}
ctx->rsp_buf, &rspSz);
if (rc != 0) {
ctx->last_rsp_size = 0;
return WH_ERROR_ABORTED;
uint8_t rsp_buf[WH_TRANSPORT_NSC_BUFFER_SIZE];
uint16_t last_rsp_size;
uint8_t initialized;
uint8_t WH_PAD[5]; /* Pad to 8-byte alignment */
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.

2 participants