99
1010#include <stdint.h>
1111#include <string.h>
12+ #include <arm_cmse.h>
1213
1314#include "loader.h"
1415#include "store_sbrk.h"
@@ -50,6 +51,9 @@ extern uint32_t _flash_keyvault;
5051extern uint32_t _flash_keyvault_size ;
5152
5253static whFlashH5Ctx g_flash_ctx ;
54+ /* Immutable flash config referenced by g_nvm_flash_cfg.config. Held at file
55+ * scope so the pointer stays valid after wcs_wolfhsm_init returns. */
56+ static whFlashH5Ctx g_flash_h5_cfg ;
5357
5458static whNvmFlashContext g_nvm_flash_ctx ;
5559static whNvmFlashConfig g_nvm_flash_cfg = {
@@ -84,23 +88,22 @@ static whServerConfig g_server_cfg = {
8488};
8589
8690static whServerContext g_server ;
87- static int g_wolfhsm_ready ;
91+ static volatile int g_wolfhsm_ready ;
8892
8993void wcs_wolfhsm_init (void )
9094{
91- whFlashH5Ctx flash_cfg ;
92- int rc ;
95+ int rc ;
9396
9497 if (g_wolfhsm_ready ) {
9598 return ;
9699 }
97100
98101 memset (& g_srv_tx_ctx , 0 , sizeof (g_srv_tx_ctx ));
99102
100- flash_cfg .base = (uint32_t )& _flash_keyvault ;
101- flash_cfg .size = (uint32_t )& _flash_keyvault_size ;
102- flash_cfg .partition_size = WCS_WOLFHSM_PARTITION_SIZE ;
103- g_nvm_flash_cfg .config = & flash_cfg ;
103+ g_flash_h5_cfg .base = (uint32_t )& _flash_keyvault ;
104+ g_flash_h5_cfg .size = (uint32_t )& _flash_keyvault_size ;
105+ g_flash_h5_cfg .partition_size = WCS_WOLFHSM_PARTITION_SIZE ;
106+ g_nvm_flash_cfg .config = & g_flash_h5_cfg ;
104107
105108 /* g_crypto_ctx.rng is an embedded WC_RNG[1] (see wh_server.h) */
106109 rc = wc_InitRng (& g_crypto_ctx .rng [0 ]);
@@ -131,6 +134,18 @@ int CSME_NSE_API wcs_wolfhsm_transmit(const uint8_t *cmd, uint32_t cmdSz,
131134 if (cmd == NULL || rsp == NULL || rspSz == NULL ) {
132135 return WH_ERROR_BADARGS ;
133136 }
137+ /* The caller is the non-secure world. Validate every caller-supplied
138+ * pointer references non-secure memory before dereferencing it, so a
139+ * compromised NS app cannot trick the secure side into reading or
140+ * writing through a secure-world pointer. Check the SAU/IDAU security
141+ * attribution only (CMSE_AU_NONSECURE); the NS MPU is not configured in
142+ * this demo, so an MPU-based permission check would reject valid
143+ * buffers. rspSz is checked first since it is dereferenced below to
144+ * obtain the response capacity. */
145+ if (cmse_check_address_range ((void * )rspSz , sizeof (* rspSz ),
146+ CMSE_AU_NONSECURE ) == NULL ) {
147+ return WH_ERROR_BADARGS ;
148+ }
134149 /* single-fetch *rspSz so it cannot be re-read after validation */
135150 rsp_capacity = * (volatile const uint32_t * )rspSz ;
136151
@@ -142,6 +157,16 @@ int CSME_NSE_API wcs_wolfhsm_transmit(const uint8_t *cmd, uint32_t cmdSz,
142157 * rspSz = 0 ;
143158 return WH_ERROR_BADARGS ;
144159 }
160+ if (cmse_check_address_range ((void * )cmd , cmdSz ,
161+ CMSE_AU_NONSECURE ) == NULL ) {
162+ * rspSz = 0 ;
163+ return WH_ERROR_BADARGS ;
164+ }
165+ if (cmse_check_address_range (rsp , rsp_capacity ,
166+ CMSE_AU_NONSECURE ) == NULL ) {
167+ * rspSz = 0 ;
168+ return WH_ERROR_BADARGS ;
169+ }
145170 if (!g_wolfhsm_ready ) {
146171 * rspSz = 0 ;
147172 return WH_ERROR_NOTREADY ;
0 commit comments