Skip to content

Commit 7c6359e

Browse files
authored
Merge pull request #348 from aidangarske/wolfhsm-h5-port
Add stm32H5 TrustZone wolfHSM Port
2 parents ad909a8 + 866fa9c commit 7c6359e

6 files changed

Lines changed: 563 additions & 0 deletions

File tree

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Nightly integration: build wolfBoot's STM32H5 TrustZone demo against
2+
# the latest wolfHSM main and run it under the m33mu emulator. This
3+
# catches drift between wolfHSM and wolfBoot main (in either direction)
4+
# that the pinned-submodule per-PR builds do not. The full client suite
5+
# runs software RSA and ECC, which is slow under the emulator, so this
6+
# is a nightly job rather than a per-PR gate.
7+
#
8+
# On failure it opens (or updates) a tracking issue assigned to
9+
# wolfSSL-Bot.
10+
11+
name: wolfBoot TrustZone integration nightly (m33mu)
12+
13+
on:
14+
schedule:
15+
# 07:00 UTC daily
16+
- cron: '0 7 * * *'
17+
workflow_dispatch:
18+
19+
permissions:
20+
contents: read
21+
issues: write
22+
23+
jobs:
24+
wolfboot-stm32h5-tz-wolfhsm:
25+
runs-on: ubuntu-latest
26+
timeout-minutes: 60
27+
container:
28+
image: ghcr.io/wolfssl/wolfboot-ci-m33mu:latest
29+
30+
steps:
31+
- name: Checkout wolfHSM (this repo, main)
32+
uses: actions/checkout@v4
33+
with:
34+
path: wolfHSM
35+
36+
- name: Checkout wolfBoot master
37+
# Switch `ref` to `master` once wolfBoot PR #769 lands; until
38+
# then the STM32H5 demo only exists on that PR.
39+
uses: actions/checkout@v4
40+
with:
41+
repository: wolfSSL/wolfBoot
42+
ref: refs/pull/769/head
43+
path: wolfBoot
44+
# Skip lib/wolfHSM submodule init - we replace it with this
45+
# checkout. Other submodules still need to come down.
46+
submodules: false
47+
48+
- name: Initialise wolfBoot submodules (except lib/wolfHSM)
49+
working-directory: wolfBoot
50+
run: |
51+
git config -f .gitmodules submodule.lib/wolfHSM.update none
52+
git submodule update --init --recursive
53+
54+
- name: Point lib/wolfHSM at this checkout
55+
working-directory: wolfBoot
56+
run: |
57+
rm -rf lib/wolfHSM
58+
ln -s "$GITHUB_WORKSPACE/wolfHSM" lib/wolfHSM
59+
ls -l lib/wolfHSM
60+
61+
- name: Build wolfBoot STM32H5 TZ demo
62+
working-directory: wolfBoot/port/stmicro/stm32h5-tz-wolfhsm
63+
run: make
64+
65+
- name: Run wolfHSM whTest_ClientConfig under m33mu
66+
working-directory: wolfBoot/port/stmicro/stm32h5-tz-wolfhsm
67+
run: |
68+
set -o pipefail
69+
mkdir -p /tmp/m33mu-wolfhsm-persist
70+
cp out/wolfboot.bin out/image_v1_signed.bin /tmp/m33mu-wolfhsm-persist/
71+
cd /tmp/m33mu-wolfhsm-persist
72+
# m33mu timeout below the 60 min job timeout so a hung run
73+
# still produces a log. Software RSA keygen dominates.
74+
m33mu wolfboot.bin image_v1_signed.bin:0x60000 \
75+
--persist --uart-stdout --timeout 3000 \
76+
--expect-bkpt 0x7d --quit-on-faults \
77+
2>&1 | tee /tmp/m33mu-wolfhsm.log
78+
79+
- name: Verify wolfHSM whTest_ClientConfig
80+
run: |
81+
grep -q "wolfHSM whTest_ClientConfig PASSED" /tmp/m33mu-wolfhsm.log
82+
grep -q "RNG DEVID=0x5748534D SUCCESS" /tmp/m33mu-wolfhsm.log
83+
grep -q "AES GCM DEVID=0x5748534D SUCCESS" /tmp/m33mu-wolfhsm.log
84+
grep -q "RSA SUCCESS" /tmp/m33mu-wolfhsm.log
85+
grep -q "ECC ephemeral ECDH SUCCESS" /tmp/m33mu-wolfhsm.log
86+
grep -q "SHA256 DEVID=0x5748534D SUCCESS" /tmp/m33mu-wolfhsm.log
87+
grep -q "HKDF SUCCESS" /tmp/m33mu-wolfhsm.log
88+
grep -q "\\[BKPT\\] imm=0x7d" /tmp/m33mu-wolfhsm.log
89+
grep -q "\\[EXPECT BKPT\\] Success" /tmp/m33mu-wolfhsm.log
90+
91+
- name: Archive emulator log on failure
92+
if: failure()
93+
uses: actions/upload-artifact@v4
94+
with:
95+
name: m33mu-wolfhsm.log
96+
path: /tmp/m33mu-wolfhsm.log
97+
98+
- name: Open or update tracking issue on failure
99+
if: failure()
100+
uses: actions/github-script@v7
101+
with:
102+
script: |
103+
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
104+
const marker = 'nightly-tz-integration';
105+
const title = 'Nightly wolfBoot TrustZone (m33mu) integration failed';
106+
const body = [
107+
'The nightly wolfBoot STM32H5 TrustZone integration run failed.',
108+
'',
109+
`Run: ${runUrl}`,
110+
'',
111+
'This builds wolfBoot main against wolfHSM main and runs the',
112+
'STM32H5 demo under m33mu. A failure usually means a regression',
113+
'in the NSC transport, the wolfBoot port, or a wolfHSM/wolfBoot',
114+
'API drift. The emulator log is attached to the run as an artifact.',
115+
].join('\n');
116+
117+
// Reuse one open tracking issue instead of opening a new one
118+
// every night.
119+
const existing = await github.rest.issues.listForRepo({
120+
owner: context.repo.owner,
121+
repo: context.repo.repo,
122+
state: 'open',
123+
labels: marker,
124+
});
125+
126+
if (existing.data.length > 0) {
127+
await github.rest.issues.createComment({
128+
owner: context.repo.owner,
129+
repo: context.repo.repo,
130+
issue_number: existing.data[0].number,
131+
body: `Still failing as of ${runUrl}`,
132+
});
133+
return;
134+
}
135+
136+
// Best-effort label create (ignore if it already exists).
137+
try {
138+
await github.rest.issues.createLabel({
139+
owner: context.repo.owner,
140+
repo: context.repo.repo,
141+
name: marker,
142+
color: 'b60205',
143+
});
144+
} catch (e) { /* label exists */ }
145+
146+
try {
147+
await github.rest.issues.create({
148+
owner: context.repo.owner,
149+
repo: context.repo.repo,
150+
title,
151+
body,
152+
labels: [marker],
153+
assignees: ['wolfSSL-Bot'],
154+
});
155+
} catch (e) {
156+
// Assignee may not be assignable; retry without it so the
157+
// issue still gets filed.
158+
await github.rest.issues.create({
159+
owner: context.repo.owner,
160+
repo: context.repo.repo,
161+
title,
162+
body,
163+
labels: [marker],
164+
});
165+
}

docs/src/5-Features.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ wolfHSM ships with several reference transports that between them cover the most
496496
- **POSIX TCP transport** (`port/posix/posix_transport_tcp.h`): carries the packet exchange over a length-prefixed TCP stream. The server listens on a configured port and the client connects to it. This is the default transport for the POSIX server example and the recommended development transport, because the client and server can live in separate host processes — or on separate machines — without any additional platform integration.
497497
- **POSIX shared memory transport** (`port/posix/posix_transport_shm.h`): hosts the same request/response buffer layout used by the memory buffer transport in a named POSIX shared memory object, with optional space for DMA-style buffers alongside it. This lets the client and server run as independent processes on the same host while exercising the shared-memory code paths a multi-core SoC would use in production.
498498
- **TLS-over-TCP transport** (`port/posix/posix_transport_tls.h`): wraps the POSIX TCP transport in a wolfSSL-secured channel, with support for certificate-based authentication and PSK. It is intended for deployments where the client and server are physically separated and the link between them cannot be trusted. The packet framing above the TLS session is identical to the plain TCP transport, so higher-level code does not change between the two.
499+
- **ARMv8-M TrustZone NSC bridge transport** (`port/armv8m-tz/wh_transport_nsc.h`): a synchronous transport for ARMv8-M Cortex-M parts where the server runs in the secure world and clients run in the non-secure world. The non-secure client `Send` calls a single `cmse_nonsecure_entry` veneer (`wcs_wolfhsm_transmit`) the integrator provides; that veneer hands the request to the secure-side server inline and returns the response in the same call, which `Recv` then yields. There is no polling or shared-memory ring. The transport is target-agnostic across ARMv8-M parts; the veneer, flash/NVM adapter, and server init are supplied by the secure-side integration. The reference integration is the wolfBoot STM32H5 port.
499500
500501
Beyond the reference transports, platform ports for embedded targets typically supply hardware-specific transports — silicon mailboxes, interrupt-driven inter-core channels, vendor IPC blocks — by implementing the same callback interface. The comm-layer contract is purely "deliver one packet, in order," so a transport need only marshal bytes between the two sides.
501502

port/armv8m-tz/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# ARMv8-M TrustZone NSC bridge transport
2+
3+
A synchronous wolfHSM transport for ARMv8-M TrustZone targets that
4+
bridges a non-secure client to a secure-world server through a single
5+
Non-Secure Callable (NSC) veneer. See `wh_transport_nsc.h` for the C
6+
API.
7+
8+
## How it works
9+
10+
Client and server share a single secure-callable function. The
11+
non-secure side packs a wolfHSM request into a buffer, calls the
12+
veneer, and waits for the veneer to return with the response written
13+
into a second buffer. The secure side runs the wolfHSM server in the
14+
same process; there is no separate task, no IRQ, and no shared-memory
15+
ring — just a function call across the security boundary.
16+
17+
## Host-side veneer contract
18+
19+
The integrator provides one function with this exact shape:
20+
21+
```c
22+
int wcs_wolfhsm_transmit(const uint8_t *cmd, uint32_t cmdSz,
23+
uint8_t *rsp, uint32_t *rspSz);
24+
```
25+
26+
declared `cmse_nonsecure_entry` from the secure side. On entry,
27+
`cmd[0..cmdSz)` holds the request and `*rspSz` is the maximum response
28+
size the client can accept; on return the function writes the
29+
response into `rsp[0..*rspSz)` and updates `*rspSz` to the actual
30+
size. Return value follows wolfHSM's `WH_ERROR_*` convention.
31+
32+
The veneer must not block on anything outside the secure server; the
33+
non-secure side treats it as a synchronous call.
34+
35+
## Known integrations
36+
37+
- **wolfBoot STM32H5 demo app** at
38+
[`port/stmicro/stm32h5-tz-wolfhsm/`](https://github.com/wolfSSL/wolfBoot/tree/main/port/stmicro/stm32h5-tz-wolfhsm)
39+
in wolfBoot. Reference integration on a NUCLEO-H563ZI;
40+
verified end-to-end on real silicon and on the m33mu emulator.
41+
42+
To add a new integration, copy the veneer skeleton from wolfBoot's
43+
demo, wire `wh_transport_nsc.h` into the non-secure client init, and
44+
write a `whServerCb` table for the secure server.

0 commit comments

Comments
 (0)