-
Notifications
You must be signed in to change notification settings - Fork 35
Add stm32H5 TrustZone wolfHSM Port #348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
aidangarske
wants to merge
7
commits into
wolfSSL:main
Choose a base branch
from
aidangarske:wolfhsm-h5-port
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
1e20df9
Add stm32-tz NSC bridge transport
aidangarske d9c0e42
Cleanup phase 1 code
aidangarske 78618c1
port/stmicro/stm32-tz: drop redundant comment on last_rsp_size
aidangarske 057ff32
docs/chapter08: document STM32 TrustZone (NSC bridge) port
aidangarske 6227202
port/stmicro/stm32-tz: Skoll review fixes + host unit test
aidangarske 0aeb181
Add CI testing for tz build path
aidangarske 16cfc43
port/armv8m-tz: NSC bridge transport for ARMv8-M TrustZone
aidangarske File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,237 @@ | ||
| /* | ||
| * port/armv8m-tz/wh_transport_nsc.c | ||
| * | ||
| * Copyright (C) 2026 wolfSSL Inc. | ||
| * | ||
| * This file is part of wolfHSM. | ||
| * | ||
| * wolfHSM is free software; you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation; either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * wolfHSM is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with wolfHSM. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| #include "wolfhsm/wh_settings.h" | ||
|
|
||
| #ifdef WOLFHSM_CFG_PORT_ARMV8M_TZ_NSC | ||
|
|
||
| #include <stdint.h> | ||
| #include <string.h> | ||
|
|
||
| #include "wolfhsm/wh_comm.h" | ||
| #include "wolfhsm/wh_error.h" | ||
| #include "wh_transport_nsc.h" | ||
|
|
||
| /* | ||
| * Resolved on the non-secure side via the wolfBoot --cmse-implib import | ||
| * library; on the secure side the same symbol is provided by the host's | ||
| * NSC veneer (wolfBoot's src/wolfhsm_callable.c). The server callbacks | ||
| * below never call this; --gc-sections strips client-side code from the | ||
| * secure image. | ||
| */ | ||
| extern int wcs_wolfhsm_transmit(const uint8_t* cmd, uint32_t cmdSz, | ||
| uint8_t* rsp, uint32_t* rspSz); | ||
|
|
||
|
|
||
| /* ============================================================ | ||
| * Non-secure (client) callbacks | ||
| * ============================================================ */ | ||
|
|
||
| static int _NscClientInit(void* context, const void* config, | ||
| whCommSetConnectedCb connectcb, void* connectcb_arg) | ||
| { | ||
| whTransportNscClientContext* ctx = (whTransportNscClientContext*)context; | ||
|
|
||
| (void)config; | ||
|
|
||
| if (ctx == NULL) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
|
|
||
| memset(ctx, 0, sizeof(*ctx)); | ||
| ctx->initialized = 1; | ||
|
|
||
| /* Synchronous bridge: the secure side is always reachable once linked. */ | ||
| if (connectcb != NULL) { | ||
| connectcb(connectcb_arg, WH_COMM_CONNECTED); | ||
| } | ||
| return WH_ERROR_OK; | ||
| } | ||
|
|
||
| static int _NscClientSend(void* context, uint16_t size, const void* data) | ||
| { | ||
| whTransportNscClientContext* ctx = (whTransportNscClientContext*)context; | ||
| uint32_t rspSz; | ||
| int rc; | ||
|
|
||
| if (ctx == NULL || data == NULL || ctx->initialized == 0U) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
| if (size == 0U || size > WH_TRANSPORT_NSC_BUFFER_SIZE) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
| /* prior response must be consumed before next Send */ | ||
| if (ctx->last_rsp_size != 0U) { | ||
| return WH_ERROR_NOTREADY; | ||
| } | ||
|
|
||
| rspSz = (uint32_t)WH_TRANSPORT_NSC_BUFFER_SIZE; | ||
| rc = wcs_wolfhsm_transmit((const uint8_t*)data, (uint32_t)size, | ||
| ctx->rsp_buf, &rspSz); | ||
| if (rc != 0) { | ||
| ctx->last_rsp_size = 0; | ||
| /* propagate known wolfHSM error codes, collapse unknowns */ | ||
| if (rc == WH_ERROR_BADARGS || rc == WH_ERROR_NOTREADY || | ||
| rc == WH_ERROR_ABORTED) { | ||
| return rc; | ||
| } | ||
| return WH_ERROR_ABORTED; | ||
| } | ||
| if (rspSz == 0U || rspSz > (uint32_t)WH_TRANSPORT_NSC_BUFFER_SIZE) { | ||
| ctx->last_rsp_size = 0; | ||
| return WH_ERROR_ABORTED; | ||
| } | ||
|
|
||
| ctx->last_rsp_size = (uint16_t)rspSz; | ||
| return WH_ERROR_OK; | ||
| } | ||
|
|
||
| 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; | ||
| } | ||
| /* out_size is in/out capacity; reject truncation, keep cached response */ | ||
| if (*out_size < ctx->last_rsp_size) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
|
|
||
| memcpy(data, ctx->rsp_buf, ctx->last_rsp_size); | ||
| *out_size = ctx->last_rsp_size; | ||
| ctx->last_rsp_size = 0; | ||
| return WH_ERROR_OK; | ||
| } | ||
|
aidangarske marked this conversation as resolved.
|
||
|
|
||
| static int _NscClientCleanup(void* context) | ||
| { | ||
| whTransportNscClientContext* ctx = (whTransportNscClientContext*)context; | ||
| if (ctx == NULL) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
| ctx->initialized = 0; | ||
| return WH_ERROR_OK; | ||
| } | ||
|
|
||
| const whTransportClientCb whTransportNscClient_Cb = { | ||
| .Init = _NscClientInit, | ||
| .Send = _NscClientSend, | ||
| .Recv = _NscClientRecv, | ||
| .Cleanup = _NscClientCleanup, | ||
| }; | ||
|
|
||
|
|
||
| /* ============================================================ | ||
| * Secure-side (server) callbacks | ||
| * | ||
| * The host's NSC veneer populates req_buf/req_size/rsp_buf/rsp_capacity | ||
| * and sets request_pending = 1 before calling wh_Server_HandleRequestMessage. | ||
| * Recv hands the request to the dispatcher; Send writes the response back | ||
| * into rsp_buf and stores its size for the veneer to read. | ||
| * ============================================================ */ | ||
|
|
||
| static int _NscServerInit(void* context, const void* config, | ||
| whCommSetConnectedCb connectcb, void* connectcb_arg) | ||
| { | ||
| whTransportNscServerContext* ctx = (whTransportNscServerContext*)context; | ||
|
|
||
| (void)config; | ||
|
|
||
| if (ctx == NULL) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
|
|
||
| memset(ctx, 0, sizeof(*ctx)); | ||
|
|
||
| if (connectcb != NULL) { | ||
| connectcb(connectcb_arg, WH_COMM_CONNECTED); | ||
| } | ||
| return WH_ERROR_OK; | ||
| } | ||
|
|
||
| static int _NscServerRecv(void* context, uint16_t* inout_size, void* data) | ||
| { | ||
| whTransportNscServerContext* ctx = (whTransportNscServerContext*)context; | ||
|
|
||
| if (ctx == NULL || inout_size == NULL || data == NULL) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
| if (!ctx->request_pending || ctx->req_buf == NULL || ctx->req_size == 0U) { | ||
| return WH_ERROR_NOTREADY; | ||
| } | ||
| /* clear stale rsp_size up-front so every exit path leaves a clean state */ | ||
| ctx->rsp_size = 0; | ||
|
|
||
| if (ctx->req_size > *inout_size) { | ||
| ctx->request_pending = 0; | ||
| return WH_ERROR_ABORTED; | ||
| } | ||
|
|
||
| memcpy(data, ctx->req_buf, ctx->req_size); | ||
| *inout_size = ctx->req_size; | ||
| ctx->request_pending = 0; | ||
| return WH_ERROR_OK; | ||
| } | ||
|
|
||
| static int _NscServerSend(void* context, uint16_t size, const void* data) | ||
| { | ||
| /* veneer is responsible for Recv/Send pairing; Send does not enforce it */ | ||
| whTransportNscServerContext* ctx = (whTransportNscServerContext*)context; | ||
|
|
||
| if (ctx == NULL || data == NULL) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
| if (size == 0U || size > ctx->rsp_capacity) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
| if (ctx->rsp_buf == NULL) { | ||
| return WH_ERROR_ABORTED; | ||
| } | ||
|
|
||
| memcpy(ctx->rsp_buf, data, size); | ||
| ctx->rsp_size = size; | ||
| return WH_ERROR_OK; | ||
| } | ||
|
|
||
| static int _NscServerCleanup(void* context) | ||
| { | ||
| whTransportNscServerContext* ctx = (whTransportNscServerContext*)context; | ||
| if (ctx == NULL) { | ||
| return WH_ERROR_BADARGS; | ||
| } | ||
| /* clear stale NS pointers so they cannot survive reinit */ | ||
| memset(ctx, 0, sizeof(*ctx)); | ||
| return WH_ERROR_OK; | ||
| } | ||
|
|
||
| const whTransportServerCb whTransportNscServer_Cb = { | ||
| .Init = _NscServerInit, | ||
| .Recv = _NscServerRecv, | ||
| .Send = _NscServerSend, | ||
| .Cleanup = _NscServerCleanup, | ||
| }; | ||
|
|
||
| #endif /* WOLFHSM_CFG_PORT_ARMV8M_TZ_NSC */ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| /* | ||
| * port/armv8m-tz/wh_transport_nsc.h | ||
| * | ||
| * Copyright (C) 2026 wolfSSL Inc. | ||
| * | ||
| * This file is part of wolfHSM. | ||
| * | ||
| * wolfHSM is free software; you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation; either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * wolfHSM is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with wolfHSM. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| /* | ||
| * Synchronous TrustZone NSC bridge transport for wolfHSM. | ||
| * | ||
| * The non-secure (client) side calls a single ARMv8-M Cortex-M | ||
| * cmse_nonsecure_entry veneer (`wcs_wolfhsm_transmit`) provided by the | ||
| * secure-side host. The veneer hands the request to the secure-side | ||
| * server context, runs `wh_Server_HandleRequestMessage` once inline, | ||
| * and returns the response in the same call. There is no polling, | ||
| * notify counter, or async producer/consumer — Send delivers the | ||
| * response, Recv just hands it back. | ||
| * | ||
| * The transport is target-agnostic across ARMv8-M TrustZone parts; | ||
| * the target-specific NSC veneer is provided by the host. | ||
| */ | ||
|
|
||
| #ifndef WH_TRANSPORT_NSC_H_ | ||
| #define WH_TRANSPORT_NSC_H_ | ||
|
|
||
| #include "wolfhsm/wh_settings.h" | ||
|
|
||
| #ifdef WOLFHSM_CFG_PORT_ARMV8M_TZ_NSC | ||
|
|
||
| #include <stdint.h> | ||
| #include "wolfhsm/wh_comm.h" | ||
|
|
||
| #define WH_TRANSPORT_NSC_BUFFER_SIZE WH_COMM_MTU | ||
|
|
||
| /* | ||
| * Non-secure (client) context. Owns the response buffer in NS .bss. | ||
| * Not internally thread-safe. | ||
| */ | ||
| typedef struct { | ||
| uint8_t rsp_buf[WH_TRANSPORT_NSC_BUFFER_SIZE]; | ||
| uint16_t last_rsp_size; | ||
| uint8_t initialized; | ||
| uint8_t WH_PAD[5]; /* trailing slack */ | ||
| } whTransportNscClientContext; | ||
|
|
||
| /* Empty config; Init accepts NULL since there is nothing to read. */ | ||
| typedef struct { | ||
| uint8_t WH_PAD[1]; | ||
| } whTransportNscClientConfig; | ||
|
|
||
| /* | ||
| * Secure-side server context. Populated by the NSC veneer per call: | ||
| * before invoking `wh_Server_HandleRequestMessage` the host sets | ||
| * req_buf/req_size/rsp_buf/rsp_capacity; after the dispatcher returns, | ||
| * the host reads rsp_size to pass back to the non-secure caller. | ||
| */ | ||
| typedef struct { | ||
| const uint8_t* req_buf; | ||
| uint8_t* rsp_buf; | ||
| uint16_t req_size; | ||
| uint16_t rsp_capacity; | ||
| uint16_t rsp_size; /* set by Send, read by veneer */ | ||
| uint8_t request_pending; /* set by veneer, cleared by Recv */ | ||
| uint8_t WH_PAD[1]; | ||
| } whTransportNscServerContext; | ||
|
|
||
| typedef struct { | ||
| uint8_t WH_PAD[1]; | ||
| } whTransportNscServerConfig; | ||
|
|
||
| /* Pre-populated tables; callbacks are file-local in wh_transport_nsc.c */ | ||
| extern const whTransportClientCb whTransportNscClient_Cb; | ||
| extern const whTransportServerCb whTransportNscServer_Cb; | ||
|
|
||
| #endif /* WOLFHSM_CFG_PORT_ARMV8M_TZ_NSC */ | ||
|
|
||
| #endif /* WH_TRANSPORT_NSC_H_ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.