Skip to content

Commit e14742d

Browse files
committed
port/stmicro/stm32-tz: review fixes for NSC transport
- _NscServerRecv clears ctx->rsp_size up-front so error paths leave no stale response state behind. - _NscClientRecv rejects too-small caller buffers with WH_ERROR_BADARGS instead of WH_ERROR_ABORTED; cached response is preserved for retry. - _NscClientSend returns WH_ERROR_NOTREADY if a prior response has not been consumed; propagates known WH_ERROR_* codes from the veneer. - _NscServerCleanup zeroes the context so stale NS pointers cannot survive a reinit. - _NscServerSend documents the per-call veneer staging contract. - Reorder whTransportNscServerContext fields to satisfy -Wpadded. - Document WOLFHSM_CFG_PORT_STM32_TZ_NSC in wh_settings.h. - Cover the new behaviors in wh_test_transport_nsc and add the NSC contexts to the struct padding check.
1 parent 0aeb181 commit e14742d

5 files changed

Lines changed: 64 additions & 12 deletions

File tree

port/stmicro/stm32-tz/wh_transport_nsc.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
* GNU General Public License for more details.
1717
*
1818
* You should have received a copy of the GNU General Public License
19-
* along with this program; if not, write to the Free Software
20-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
19+
* along with wolfHSM. If not, see <http://www.gnu.org/licenses/>.
2120
*/
2221

2322
#include "wolfhsm/wh_settings.h"
@@ -79,12 +78,21 @@ static int _NscClientSend(void* context, uint16_t size, const void* data)
7978
if (size == 0U || size > WH_TRANSPORT_NSC_BUFFER_SIZE) {
8079
return WH_ERROR_BADARGS;
8180
}
81+
/* prior response must be consumed before next Send */
82+
if (ctx->last_rsp_size != 0U) {
83+
return WH_ERROR_NOTREADY;
84+
}
8285

8386
rspSz = (uint32_t)WH_TRANSPORT_NSC_BUFFER_SIZE;
8487
rc = wcs_wolfhsm_transmit((const uint8_t*)data, (uint32_t)size,
8588
ctx->rsp_buf, &rspSz);
8689
if (rc != 0) {
8790
ctx->last_rsp_size = 0;
91+
/* propagate known wolfHSM error codes, collapse unknowns */
92+
if (rc == WH_ERROR_BADARGS || rc == WH_ERROR_NOTREADY ||
93+
rc == WH_ERROR_ABORTED) {
94+
return rc;
95+
}
8896
return WH_ERROR_ABORTED;
8997
}
9098
if (rspSz == 0U || rspSz > (uint32_t)WH_TRANSPORT_NSC_BUFFER_SIZE) {
@@ -107,6 +115,10 @@ static int _NscClientRecv(void* context, uint16_t* out_size, void* data)
107115
if (ctx->last_rsp_size == 0U) {
108116
return WH_ERROR_NOTREADY;
109117
}
118+
/* out_size is in/out capacity; reject truncation, keep cached response */
119+
if (*out_size < ctx->last_rsp_size) {
120+
return WH_ERROR_BADARGS;
121+
}
110122

111123
memcpy(data, ctx->rsp_buf, ctx->last_rsp_size);
112124
*out_size = ctx->last_rsp_size;
@@ -170,15 +182,14 @@ static int _NscServerRecv(void* context, uint16_t* inout_size, void* data)
170182
if (!ctx->request_pending || ctx->req_buf == NULL || ctx->req_size == 0U) {
171183
return WH_ERROR_NOTREADY;
172184
}
185+
/* clear stale rsp_size up-front so every exit path leaves a clean state */
186+
ctx->rsp_size = 0;
187+
173188
if (ctx->req_size > *inout_size) {
174189
ctx->request_pending = 0;
175190
return WH_ERROR_ABORTED;
176191
}
177192

178-
/* Stale value from the previous call must not leak through error paths
179-
* that skip Send. */
180-
ctx->rsp_size = 0;
181-
182193
memcpy(data, ctx->req_buf, ctx->req_size);
183194
*inout_size = ctx->req_size;
184195
ctx->request_pending = 0;
@@ -187,6 +198,7 @@ static int _NscServerRecv(void* context, uint16_t* inout_size, void* data)
187198

188199
static int _NscServerSend(void* context, uint16_t size, const void* data)
189200
{
201+
/* veneer is responsible for Recv/Send pairing; Send does not enforce it */
190202
whTransportNscServerContext* ctx = (whTransportNscServerContext*)context;
191203

192204
if (ctx == NULL || data == NULL) {
@@ -210,6 +222,8 @@ static int _NscServerCleanup(void* context)
210222
if (ctx == NULL) {
211223
return WH_ERROR_BADARGS;
212224
}
225+
/* clear stale NS pointers so they cannot survive reinit */
226+
memset(ctx, 0, sizeof(*ctx));
213227
return WH_ERROR_OK;
214228
}
215229

port/stmicro/stm32-tz/wh_transport_nsc.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
* GNU General Public License for more details.
1717
*
1818
* You should have received a copy of the GNU General Public License
19-
* along with this program; if not, write to the Free Software
20-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
19+
* along with wolfHSM. If not, see <http://www.gnu.org/licenses/>.
2120
*/
2221

2322
/*
@@ -55,10 +54,10 @@ typedef struct {
5554
uint8_t rsp_buf[WH_TRANSPORT_NSC_BUFFER_SIZE];
5655
uint16_t last_rsp_size;
5756
uint8_t initialized;
58-
uint8_t WH_PAD[5]; /* Pad to 8-byte alignment */
57+
uint8_t WH_PAD[5]; /* trailing slack */
5958
} whTransportNscClientContext;
6059

61-
/* Empty config struct - kept for ABI symmetry with other transports */
60+
/* Empty config; Init accepts NULL since there is nothing to read. */
6261
typedef struct {
6362
uint8_t WH_PAD[1];
6463
} whTransportNscClientConfig;
@@ -71,8 +70,8 @@ typedef struct {
7170
*/
7271
typedef struct {
7372
const uint8_t* req_buf;
74-
uint16_t req_size;
7573
uint8_t* rsp_buf;
74+
uint16_t req_size;
7675
uint16_t rsp_capacity;
7776
uint16_t rsp_size; /* set by Send, read by veneer */
7877
uint8_t request_pending; /* set by veneer, cleared by Recv */
@@ -83,6 +82,7 @@ typedef struct {
8382
uint8_t WH_PAD[1];
8483
} whTransportNscServerConfig;
8584

85+
/* Pre-populated tables; callbacks are file-local in wh_transport_nsc.c */
8686
extern const whTransportClientCb whTransportNscClient_Cb;
8787
extern const whTransportServerCb whTransportNscServer_Cb;
8888

test/wh_test_check_struct_padding.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,10 @@ whMessageCert_VerifyAcertRequest whMessageCert_VerifyAcertRequest_test;
203203
#endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER_ACERT */
204204
#endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER */
205205

206+
#ifdef WOLFHSM_CFG_PORT_STM32_TZ_NSC
207+
#include "wh_transport_nsc.h"
208+
whTransportNscClientContext whTransportNscClientContext_test;
209+
whTransportNscServerContext whTransportNscServerContext_test;
210+
#endif /* WOLFHSM_CFG_PORT_STM32_TZ_NSC */
211+
206212
#endif /* WH_TEST_CHECK_STRUCT_PADDING_C_ */

test/wh_test_transport_nsc.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,34 @@ static int test_client_callbacks(void)
100100
WH_TEST_ASSERT_RETURN(WH_ERROR_NOTREADY ==
101101
whTransportNscClient_Cb.Recv(&ctx, &sz, data_out));
102102

103+
/* too-small buffer returns BADARGS, cached response preserved */
104+
rc = whTransportNscClient_Cb.Send(&ctx, sizeof(data_in), data_in);
105+
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_OK);
106+
sz = (uint16_t)(sizeof(data_in));
107+
WH_TEST_ASSERT_RETURN(WH_ERROR_BADARGS ==
108+
whTransportNscClient_Cb.Recv(&ctx, &sz, data_out));
109+
/* second Send before Recv consumes prior reply is NOTREADY */
110+
WH_TEST_ASSERT_RETURN(WH_ERROR_NOTREADY ==
111+
whTransportNscClient_Cb.Send(&ctx, sizeof(data_in), data_in));
112+
sz = sizeof(data_out);
113+
rc = whTransportNscClient_Cb.Recv(&ctx, &sz, data_out);
114+
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_OK);
115+
WH_TEST_ASSERT_RETURN(sz == sizeof(data_in) + 1U);
116+
103117
g_stub_force_rc = -42;
104118
rc = whTransportNscClient_Cb.Send(&ctx, sizeof(data_in), data_in);
105119
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_ABORTED);
106120
g_stub_force_rc = 0;
107121

122+
/* WH_ERROR_* return values from the veneer are propagated unchanged. */
123+
g_stub_force_rc = WH_ERROR_BADARGS;
124+
rc = whTransportNscClient_Cb.Send(&ctx, sizeof(data_in), data_in);
125+
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_BADARGS);
126+
g_stub_force_rc = WH_ERROR_NOTREADY;
127+
rc = whTransportNscClient_Cb.Send(&ctx, sizeof(data_in), data_in);
128+
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_NOTREADY);
129+
g_stub_force_rc = 0;
130+
108131
g_stub_force_rspSz = (uint32_t)WH_TRANSPORT_NSC_BUFFER_SIZE + 1U;
109132
rc = whTransportNscClient_Cb.Send(&ctx, sizeof(data_in),
110133
data_in);
@@ -157,11 +180,12 @@ static int test_server_callbacks(void)
157180
ctx.rsp_size = 0xBEEF;
158181
ctx.request_pending = 1;
159182

160-
/* Oversize: must clear request_pending. */
183+
/* oversize must clear request_pending and rsp_size */
161184
sz = (uint16_t)(sizeof(req) - 1U);
162185
rc = whTransportNscServer_Cb.Recv(&ctx, &sz, data_buf);
163186
WH_TEST_ASSERT_RETURN(rc == WH_ERROR_ABORTED);
164187
WH_TEST_ASSERT_RETURN(ctx.request_pending == 0U);
188+
WH_TEST_ASSERT_RETURN(ctx.rsp_size == 0U);
165189

166190
ctx.req_buf = req;
167191
ctx.req_size = (uint16_t)sizeof(req);

wolfhsm/wh_settings.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@
129129
* WOLFHSM_CFG_PORT_GETTIME - Function-like macro returning the current system
130130
* time in microseconds as a uint64_t. Must be defined in wolfhsm_cfg.h for
131131
* the active port UNLESS WOLFHSM_CFG_NO_SYS_TIME is defined
132+
*
133+
* WOLFHSM_CFG_PORT_STM32_TZ_NSC - If defined, build the STM32 TrustZone
134+
* non-secure-callable (NSC) bridge transport in
135+
* port/stmicro/stm32-tz/wh_transport_nsc.{c,h}. Intended for ARMv8-M
136+
* Cortex-M deployments where a non-secure wolfHSM client calls into a
137+
* secure-side server through a single cmse_nonsecure_entry veneer
138+
* (e.g. wolfBoot's WOLFCRYPT_TZ_WOLFHSM engine).
139+
* Default: Not defined
132140
133141
* Overridable porting functions:
134142
*

0 commit comments

Comments
 (0)