4343#include "wolfhsm/wh_server.h"
4444#include "wolfhsm/wh_server_nvm.h"
4545
46+ /* Handle NVM read, do access checking and clamping */
47+ static int _HandleNvmRead (whServerContext * server , uint8_t * out_data ,
48+ whNvmSize offset , whNvmSize len , whNvmSize * out_len ,
49+ whNvmId id )
50+ {
51+ whNvmMetadata meta ;
52+ int32_t rc ;
53+
54+ if ((server == NULL ) || (out_data == NULL ) || (out_len == NULL )) {
55+ return WH_ERROR_BADARGS ;
56+ }
57+
58+ if (len > WH_MESSAGE_NVM_MAX_READ_LEN ) {
59+ return WH_ERROR_ABORTED ;
60+ }
61+
62+ rc = wh_Nvm_GetMetadata (server -> nvm , id , & meta );
63+ if (rc != WH_ERROR_OK ) {
64+ return rc ;
65+ }
66+
67+ if (meta .flags & WH_NVM_FLAGS_NONEXPORTABLE ) {
68+ return WH_ERROR_ACCESS ;
69+ }
70+
71+ if (offset >= meta .len )
72+ return WH_ERROR_BADARGS ;
73+
74+ /* Clamp length to object size */
75+ if ((offset + len ) > meta .len ) {
76+ len = meta .len - offset ;
77+ }
78+
79+ rc = wh_Nvm_Read (server -> nvm , id , offset , len , out_data );
80+ if (rc != WH_ERROR_OK )
81+ return rc ;
82+ * out_len = len ;
83+ return WH_ERROR_OK ;
84+ }
85+
4686int wh_Server_HandleNvmRequest (whServerContext * server ,
4787 uint16_t magic , uint16_t action , uint16_t seq ,
4888 uint16_t req_size , const void * req_packet ,
@@ -240,44 +280,30 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
240280
241281 case WH_MESSAGE_NVM_ACTION_READ :
242282 {
243- whMessageNvm_ReadRequest req = {0 };
244- whMessageNvm_ReadResponse resp = {0 };
245- uint16_t hdr_len = sizeof (resp );
246- uint8_t * data = (uint8_t * )resp_packet + hdr_len ;
247- uint16_t data_len = 0 ;
248- whNvmMetadata meta = {0 };
283+ whMessageNvm_ReadRequest req = {0 };
284+ whMessageNvm_ReadResponse resp = {0 };
285+ uint16_t hdr_len = sizeof (resp );
286+ uint8_t * data = (uint8_t * )resp_packet + hdr_len ;
287+ whNvmSize data_len = 0 ;
249288
250289 if (req_size != sizeof (req )) {
251290 /* Request is malformed */
252291 resp .rc = WH_ERROR_ABORTED ;
253- } else {
292+ }
293+ else {
254294 /* Convert request struct */
255- wh_MessageNvm_TranslateReadRequest (magic ,
256- (whMessageNvm_ReadRequest * )req_packet , & req );
295+ wh_MessageNvm_TranslateReadRequest (
296+ magic , (whMessageNvm_ReadRequest * )req_packet , & req );
257297
258- if (req .data_len > WH_MESSAGE_NVM_MAX_READ_LEN ) {
259- resp .rc = WH_ERROR_ABORTED ;
260- } else {
261- /* Check metadata for non-exportable flag */
262- resp .rc = wh_Nvm_GetMetadata (server -> nvm , req .id , & meta );
263- if (resp .rc == 0 ) {
264- if (meta .flags & WH_NVM_FLAGS_NONEXPORTABLE ) {
265- resp .rc = WH_ERROR_ACCESS ;
266- }
267- else {
268- /* Process the Read action */
269- resp .rc = wh_Nvm_Read (server -> nvm , req .id , req .offset ,
270- req .data_len , data );
271- if (resp .rc == 0 ) {
272- data_len = req .data_len ;
273- }
274- }
275- }
298+ resp .rc = _HandleNvmRead (server , data , req .offset , req .data_len ,
299+ & req .data_len , req .id );
300+ if (resp .rc == WH_ERROR_OK ) {
301+ data_len = req .data_len ;
276302 }
277303 }
278304 /* Convert the response struct */
279- wh_MessageNvm_TranslateReadResponse (magic ,
280- & resp , (whMessageNvm_ReadResponse * )resp_packet );
305+ wh_MessageNvm_TranslateReadResponse (
306+ magic , & resp , (whMessageNvm_ReadResponse * )resp_packet );
281307 * out_resp_size = sizeof (resp ) + data_len ;
282308 }; break ;
283309
@@ -338,6 +364,7 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
338364 whMessageNvm_ReadDmaRequest req = {0 };
339365 whMessageNvm_SimpleResponse resp = {0 };
340366 whNvmMetadata meta = {0 };
367+ whNvmSize read_len ;
341368 void * data = NULL ;
342369
343370 if (req_size != sizeof (req )) {
@@ -355,6 +382,23 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
355382 resp .rc = WH_ERROR_ACCESS ;
356383 }
357384 }
385+
386+ if (resp .rc == 0 ) {
387+ if (req .offset >= meta .len ) {
388+ resp .rc = WH_ERROR_BADARGS ;
389+ }
390+ }
391+
392+ if (resp .rc == 0 ) {
393+ read_len = req .data_len ;
394+ /* Clamp length to object size */
395+ if ((req .offset + read_len ) > meta .len ) {
396+ read_len = meta .len - req .offset ;
397+ }
398+ }
399+
400+ /* use unclamped length for DMA address processing in case DMA callbacks
401+ * are sensible to alignment and/or size */
358402 if (resp .rc == 0 ) {
359403 /* perform platform-specific host address processing */
360404 resp .rc = wh_Server_DmaProcessClientAddress (
@@ -363,8 +407,8 @@ int wh_Server_HandleNvmRequest(whServerContext* server,
363407 }
364408 if (resp .rc == 0 ) {
365409 /* Process the Read action */
366- resp .rc = wh_Nvm_Read (server -> nvm , req .id , req .offset , req . data_len ,
367- (uint8_t * )data );
410+ resp .rc = wh_Nvm_Read (server -> nvm , req .id , req .offset , read_len ,
411+ (uint8_t * )data );
368412 }
369413 if (resp .rc == 0 ) {
370414 /* perform platform-specific host address processing */
0 commit comments