From 3e1841b1113a7c213b090f784aaf0ff76e050fb5 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 23 Sep 2025 11:16:27 +0200 Subject: [PATCH 01/22] nvm: nvm flash log based implementation it can be used when the write granularity is too big to be used with the current wh_nvm_flash implementation. --- src/wh_nvm_flash_log.c | 573 +++++++++++++++++++++++++++++++++++++ wolfhsm/wh_nvm_flash_log.h | 98 +++++++ 2 files changed, 671 insertions(+) create mode 100644 src/wh_nvm_flash_log.c create mode 100644 wolfhsm/wh_nvm_flash_log.h diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c new file mode 100644 index 000000000..f470d594f --- /dev/null +++ b/src/wh_nvm_flash_log.c @@ -0,0 +1,573 @@ +/* + * Copyright (C) 2025 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 . + */ + +/* + * wh NVM Flash Layer + * + * This NVM layer provides secure, atomic storage of data on flash devices + * with large write granularity (e.g., 64 bytes). The layer manages two + * equal-sized partitions in flash, with only one partition active at any time. + * All objects metadata are cached in memory for fast access. + * + * Atomicity Guarantee: + * On every modification, the inactive partition is erased, all objects are + * written to it, and only then is the partition header (containing an + * incremented epoch counter) programmed. At initialization, the layer selects + * the partition with the highest epoch as active, ensuring that after any + * interruption, either the state before or after the write is valid. + * + * Object Storage Format: + * Objects are stored back-to-back in the partition, each consisting of a + * whNvmMetadata structure immediately followed by the object data. + * + * Write Padding: + * All writes are padded to the flash's write granularity. + * + * Flash backend: + * This layer relies on the same flash backend as wh_Flash, using the whFlashCb + * interface. + */ + +#include "wolfhsm/wh_settings.h" + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + +#include +#include +#include + +#include "wolfhsm/wh_common.h" +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_flash.h" + +#include "wolfhsm/wh_nvm_flash_log.h" + +#define PAD_SIZE(size) \ + (((size) + WH_NVM_FLASH_LOG_WRITE_GRANULARITY - 1) & \ + ~(WH_NVM_FLASH_LOG_WRITE_GRANULARITY - 1)) + +typedef struct { + union { + whNvmMetadata meta; + uint8_t _pad[PAD_SIZE(sizeof(whNvmMetadata))]; + }; +} whNvmFlashLogMetadata; + +static int wh_NvmFlashLog_ErasePartition(whNvmFlashLogContext* ctx, + uint32_t partition) +{ + const whFlashCb* f_cb = ctx->flash_cb; + uint32_t part_offset; + int ret; + + part_offset = partition * ctx->partition_size; + ret = f_cb->Erase(ctx->flash_ctx, part_offset, ctx->partition_size); + if (ret != 0) + return ret; + return WH_ERROR_OK; +} + +static int wh_NvmFlashLog_WritePartition(whNvmFlashLogContext* ctx, + uint32_t partition) +{ + const whFlashCb* f_cb = ctx->flash_cb; + uint32_t part_offset; + int ret; + + part_offset = partition * ctx->partition_size; + + if (ctx->directory.header.size % WH_NVM_FLASH_LOG_WRITE_GRANULARITY != 0) + return WH_ERROR_ABORTED; + + if (ctx->directory.header.size > 0) { + ret = f_cb->Program(ctx->flash_ctx, + part_offset + sizeof(whNvmFlashLogPartitionHeader), + ctx->directory.header.size, ctx->directory.data); + if (ret != 0) + return ret; + } + + return WH_ERROR_OK; +} + +static int wh_NvmFlashLog_CommitPartition(whNvmFlashLogContext* ctx, + uint32_t partition) +{ + const whFlashCb* f_cb = ctx->flash_cb; + uint32_t part_offset; + int ret; + + part_offset = partition * ctx->partition_size; + + ret = f_cb->BlankCheck(ctx->flash_ctx, part_offset, + sizeof(whNvmFlashLogPartitionHeader)); + if (ret != 0) + return ret; + ret = f_cb->Program(ctx->flash_ctx, part_offset, + sizeof(whNvmFlashLogPartitionHeader), + (uint8_t*)&ctx->directory.header); + if (ret != 0) + return ret; + + return WH_ERROR_OK; +} + +static int wh_NvmFlashLog_ChoosePartition(whNvmFlashLogContext* ctx) +{ + whNvmFlashLogPartitionHeader header0, header1; + const whFlashCb* f_cb = ctx->flash_cb; + uint32_t part1_offset; + int part0_blank, part1_blank; + int ret; + + part1_offset = ctx->partition_size; + + ret = f_cb->BlankCheck(ctx->flash_ctx, 0, sizeof(header0)); + if (ret != 0 && ret != WH_ERROR_NOTBLANK) { + return ret; + } + part0_blank = (ret == 0); + + ret = f_cb->BlankCheck(ctx->flash_ctx, part1_offset, sizeof(header0)); + if (ret != 0 && ret != WH_ERROR_NOTBLANK) { + return ret; + } + part1_blank = (ret == 0); + + if (part0_blank && part1_blank) { + /* Both partitions are blank, start with partition 0 */ + ret = wh_NvmFlashLog_ErasePartition(ctx, 0); + if (ret != 0) + return ret; + ret = wh_NvmFlashLog_CommitPartition(ctx, 0); + if (ret != 0) + return ret; + return WH_ERROR_OK; + } + + if (part0_blank) { + ctx->active_partition = 1; + return WH_ERROR_OK; + } + + if (part1_blank) { + ctx->active_partition = 0; + return WH_ERROR_OK; + } + + /* both partition are programmed */ + ret = f_cb->Read(ctx->flash_ctx, 0, sizeof(header0), (uint8_t*)&header0); + if (ret != 0) { + return ret; + } + ret = f_cb->Read(ctx->flash_ctx, part1_offset, sizeof(header1), + (uint8_t*)&header1); + if (ret != 0) { + return ret; + } + + if (header0.partition_epoch > header1.partition_epoch) { + ctx->active_partition = 0; + } + else { + ctx->active_partition = 1; + } + + return 0; +} + +static whNvmFlashLogMetadata* +wh_NvmFlashLog_FindObjectById(whNvmFlashLogContext* ctx, whNvmId id) +{ + whNvmFlashLogMetadata* obj; + uint8_t* idx; + + if (ctx == NULL) + return NULL; + + idx = ctx->directory.data; + while (idx < ctx->directory.data + ctx->directory.header.size) { + obj = (whNvmFlashLogMetadata*)idx; + if (obj->meta.id == id) { + return obj; + } + idx += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); + } + return NULL; +} + +static int wh_NvmFlashLog_DestroyObject(whNvmFlashLogContext* ctx, whNvmId id) +{ + whNvmFlashLogMetadata* obj; + uint32_t obj_len; + uint32_t obj_off; + + obj = wh_NvmFlashLog_FindObjectById(ctx, id); + if (obj == NULL) + return WH_ERROR_OK; + + obj_len = sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); + obj_off = (uint8_t*)obj - ctx->directory.data; + /* zero out the object to prevent leaking */ + memset(obj, 0, obj_len); + memmove(obj, (uint8_t*)obj + obj_len, + ctx->directory.header.size - (obj_off + obj_len)); + ctx->directory.header.size -= obj_len; + return WH_ERROR_OK; +} + +static int wh_NvmFlashLog_CountObjects(whNvmFlashLogContext* ctx, + whNvmFlashLogMetadata* start_obj) +{ + whNvmFlashLogMetadata* obj; + uint8_t* idx; + int count = 0; + + if (ctx == NULL) + return 0; + + idx = (start_obj != NULL) ? (uint8_t*)start_obj : ctx->directory.data; + if (idx < ctx->directory.data || + idx >= ctx->directory.data + ctx->directory.header.size) { + return 0; + } + + while (idx < ctx->directory.data + ctx->directory.header.size) { + obj = (whNvmFlashLogMetadata*)idx; + if (obj->meta.id == WH_NVM_ID_INVALID) { + break; + } + count++; + idx += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); + } + return count; +} + +static int wh_NvmFlashLog_ReadPartition(whNvmFlashLogContext* ctx) +{ + const whFlashCb* f_cb = ctx->flash_cb; + uint32_t part_offset; + int ret; + + part_offset = ctx->active_partition * ctx->partition_size; + + ret = f_cb->Read(ctx->flash_ctx, part_offset, + sizeof(whNvmFlashLogPartitionHeader), + (uint8_t*)&ctx->directory.header); + if (ret != 0) + return ret; + + if (ctx->directory.header.size > + ctx->partition_size - sizeof(whNvmFlashLogPartitionHeader)) { + return WH_ERROR_ABORTED; + } + + if (ctx->directory.header.size > 0) { + ret = f_cb->Read(ctx->flash_ctx, + part_offset + sizeof(whNvmFlashLogPartitionHeader), + ctx->directory.header.size, ctx->directory.data); + if (ret != 0) + return ret; + } + + return WH_ERROR_OK; +} + +static int wh_NvmFlashLog_NewEpoch(whNvmFlashLogContext* ctx) +{ + int next_active; + int ret; + + next_active = (ctx->active_partition == 0) ? 1 : 0; + ctx->directory.header.partition_epoch++; + ret = wh_NvmFlashLog_ErasePartition(ctx, next_active); + if (ret != 0) + return ret; + ret = wh_NvmFlashLog_WritePartition(ctx, next_active); + if (ret != 0) + return ret; + ret = wh_NvmFlashLog_CommitPartition(ctx, next_active); + if (ret != 0) + return ret; + ctx->active_partition = next_active; + return WH_ERROR_OK; +} + +/* Initialization function */ +int wh_NvmFlashLog_Init(void* c, const void* cf) +{ + whNvmFlashLogContext* context = (whNvmFlashLogContext*)c; + const whNvmFlashLogConfig* config = (const whNvmFlashLogConfig*)cf; + int ret; + + if (context == NULL || config == NULL || config->flash_cb == NULL || + config->flash_ctx == NULL) { + return WH_ERROR_BADARGS; + } + if (config->flash_cb->PartitionSize == NULL) { + return WH_ERROR_BADARGS; + } + memset(context, 0, sizeof(*context)); + + ret = 0; + if (config->flash_cb->Init != NULL) + ret = config->flash_cb->Init(config->flash_ctx, config->flash_cfg); + if (ret != 0) + return ret; + + context->flash_cb = config->flash_cb; + context->flash_ctx = config->flash_ctx; + context->partition_size = + context->flash_cb->PartitionSize(context->flash_ctx); + + if (context->partition_size != WH_NVM_FLASH_LOG_PARTITION_SIZE || + context->partition_size % WH_NVM_FLASH_LOG_WRITE_GRANULARITY != 0) { + return WH_ERROR_BADARGS; + } + + /* unlock partitions */ + ret = context->flash_cb->WriteUnlock(context->flash_ctx, 0, + context->partition_size); + if (ret != 0) + return ret; + ret = context->flash_cb->WriteUnlock( + context->flash_ctx, context->partition_size, context->partition_size); + if (ret != 0) + return ret; + + ret = wh_NvmFlashLog_ChoosePartition(context); + if (ret != 0) + return ret; + ret = wh_NvmFlashLog_ReadPartition(context); + if (ret != 0) + return ret; + + return WH_ERROR_OK; +} + +int wh_NvmFlashLog_Cleanup(void* c) +{ + int ret; + whNvmFlashLogContext* context = (whNvmFlashLogContext*)c; + if (context == NULL) + return WH_ERROR_BADARGS; + + /* lock partitions */ + ret = context->flash_cb->WriteLock(context->flash_ctx, 0, + context->partition_size); + if (ret != 0) + return ret; + ret = context->flash_cb->WriteLock( + context->flash_ctx, context->partition_size, context->partition_size); + if (ret != 0) + return ret; + + return WH_ERROR_OK; +} + +/* List objects */ +int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, + whNvmId start_id, whNvmId* out_count, whNvmId* out_id) +{ + /* TODO: Implement access and flag matching */ + (void)access; + (void)flags; + whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; + whNvmFlashLogMetadata* obj; + uint32_t count; + + if (ctx == NULL) + return WH_ERROR_BADARGS; + + obj = wh_NvmFlashLog_FindObjectById(ctx, start_id); + if (obj == NULL) { + if (out_count != NULL) + *out_count = 0; + if (out_id != NULL) + *out_id = WH_NVM_ID_INVALID; + return WH_ERROR_OK; + } + + /* check next object */ + obj = + (whNvmFlashLogMetadata*)((uint8_t*)obj + sizeof(whNvmFlashLogMetadata) + + PAD_SIZE(obj->meta.len)); + if (obj >= (whNvmFlashLogMetadata*)(ctx->directory.data + + ctx->directory.header.size) || + obj->meta.id == WH_NVM_ID_INVALID) { + if (out_count != NULL) + *out_count = 0; + if (out_id != NULL) + *out_id = WH_NVM_ID_INVALID; + return WH_ERROR_OK; + } + count = wh_NvmFlashLog_CountObjects(ctx, obj); + if (out_count != NULL) + *out_count = count; + if (out_id != NULL) + *out_id = obj->meta.id; + + return WH_ERROR_OK; +} + +/* Get available space/objects */ +int wh_NvmFlashLog_GetAvailable(void* c, uint32_t* out_avail_size, + whNvmId* out_avail_objects, + uint32_t* out_reclaim_size, + whNvmId* out_reclaim_objects) +{ + whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; + uint8_t count; + + if (ctx == NULL) + return WH_ERROR_BADARGS; + if (out_avail_size != NULL) { + *out_avail_size = ctx->partition_size - + sizeof(whNvmFlashLogPartitionHeader) - + ctx->directory.header.size; + } + + if (out_avail_objects != NULL) { + count = wh_NvmFlashLog_CountObjects(ctx, NULL); + *out_avail_objects = WOLFHSM_CFG_NVM_OBJECT_COUNT - count; + } + + /* No reclaim in this simple implementation */ + if (out_reclaim_size != NULL) { + *out_reclaim_size = 0; + } + if (out_reclaim_objects != NULL) { + *out_reclaim_objects = 0; + } + + return WH_ERROR_OK; +} + +/* Get metadata for an object */ +int wh_NvmFlashLog_GetMetadata(void* c, whNvmId id, whNvmMetadata* meta) +{ + whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; + whNvmFlashLogMetadata* obj; + + if (ctx == NULL || meta == NULL) + return WH_ERROR_BADARGS; + + obj = wh_NvmFlashLog_FindObjectById(ctx, id); + if (obj == NULL) { + return WH_ERROR_NOTFOUND; + } + + memcpy(meta, &obj->meta, sizeof(*meta)); + return WH_ERROR_OK; +} + +int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, + const uint8_t* data) +{ + whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; + whNvmFlashLogMetadata *obj, *old_obj; + uint32_t available_space; + uint32_t ret; + uint32_t count; + + if (ctx == NULL || meta == NULL || (data_len > 0 && data == NULL)) + return WH_ERROR_BADARGS; + + count = wh_NvmFlashLog_CountObjects(ctx, NULL); + if (count >= WOLFHSM_CFG_NVM_OBJECT_COUNT) + return WH_ERROR_NOSPACE; + + available_space = ctx->partition_size - + sizeof(whNvmFlashLogPartitionHeader) - + ctx->directory.header.size; + + old_obj = wh_NvmFlashLog_FindObjectById(ctx, meta->id); + if (old_obj != NULL) { + available_space += + sizeof(whNvmFlashLogMetadata) + PAD_SIZE(old_obj->meta.len); + } + + if (PAD_SIZE(data_len) + sizeof(whNvmFlashLogMetadata) > available_space) + return WH_ERROR_NOSPACE; + + if (old_obj) { + ret = wh_NvmFlashLog_DestroyObject(ctx, meta->id); + if (ret != WH_ERROR_OK) + return ret; + } + + obj = (whNvmFlashLogMetadata*)(ctx->directory.data + + ctx->directory.header.size); + meta->len = data_len; + memcpy(&obj->meta, meta, sizeof(*meta)); + memcpy((uint8_t*)obj + sizeof(whNvmFlashLogMetadata), data, data_len); + ctx->directory.header.size += + sizeof(whNvmFlashLogMetadata) + PAD_SIZE(data_len); + + return wh_NvmFlashLog_NewEpoch(ctx); +} + +/* Destroy objects by id list */ +int wh_NvmFlashLog_DestroyObjects(void* c, whNvmId list_count, + const whNvmId* id_list) +{ + whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; + int i; + int ret; + + if (ctx == NULL || (list_count > 0 && id_list == NULL)) + return WH_ERROR_BADARGS; + + if (list_count == 0) + return WH_ERROR_OK; + + for (i = 0; i < list_count; i++) { + ret = wh_NvmFlashLog_DestroyObject(ctx, id_list[i]); + if (ret != WH_ERROR_OK) + return ret; + } + + return wh_NvmFlashLog_NewEpoch(ctx); +} + +/* Read object data */ +int wh_NvmFlashLog_Read(void* c, whNvmId id, whNvmSize offset, + whNvmSize data_len, uint8_t* data) +{ + whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; + whNvmFlashLogMetadata* obj; + uint8_t* obj_data; + + if (ctx == NULL || (data_len > 0 && data == NULL)) + return WH_ERROR_BADARGS; + + obj = wh_NvmFlashLog_FindObjectById(ctx, id); + if (obj == NULL) + return WH_ERROR_NOTFOUND; + + if (offset + data_len > obj->meta.len) + return WH_ERROR_BADARGS; + + obj_data = (uint8_t*)obj + sizeof(whNvmFlashLogMetadata) + offset; + memcpy(data, obj_data, data_len); + + return WH_ERROR_OK; +} + +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ diff --git a/wolfhsm/wh_nvm_flash_log.h b/wolfhsm/wh_nvm_flash_log.h new file mode 100644 index 000000000..d3cf83bf6 --- /dev/null +++ b/wolfhsm/wh_nvm_flash_log.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2025 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 . + */ +#ifndef WOLFHSM_WH_NVM_FLASH_LOG_H_ +#define WOLFHSM_WH_NVM_FLASH_LOG_H_ + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + +#include "wolfhsm/wh_settings.h" + +#include "wolfhsm/wh_common.h" +#include "wolfhsm/wh_flash.h" + +#ifndef WH_NVM_FLASH_LOG_WRITE_GRANULARITY +#define WH_NVM_FLASH_LOG_WRITE_GRANULARITY 64 +#endif + +#ifndef WOLFHSM_CFG_NVM_OBJECT_COUNT +#define WOLFHSM_CFG_NVM_OBJECT_COUNT 32 +#endif + +#ifndef WH_NVM_FLASH_LOG_PARTITION_SIZE +#define WH_NVM_FLASH_LOG_PARTITION_SIZE (4 * 1024) +#endif + +typedef struct { + uint32_t partition_epoch; + uint32_t size; + uint8_t _pad[WH_NVM_FLASH_LOG_WRITE_GRANULARITY - sizeof(uint32_t) * 2]; +} whNvmFlashLogPartitionHeader; + +/* In-memory representation of a partition */ +typedef struct { + whNvmFlashLogPartitionHeader header; + uint8_t data[WH_NVM_FLASH_LOG_PARTITION_SIZE]; +} whNvmFlashLogMemPartition; + +/* Flash log backend context structure */ +typedef struct { + const whFlashCb* flash_cb; /* Flash callback interface */ + void* flash_ctx; /* Flash context */ + uint32_t partition_size; + uint32_t active_partition; /* 0 or 1 */ + whNvmFlashLogMemPartition directory; +} whNvmFlashLogContext; + +/* Flash log backend config structure */ +typedef struct { + const whFlashCb* flash_cb; /* Flash callback interface */ + void* flash_ctx; /* Flash context */ + const void* flash_cfg; /* Config to be passed to cb->Init */ +} whNvmFlashLogConfig; + +int wh_NvmFlashLog_Init(void* c, const void* cf); +int wh_NvmFlashLog_Cleanup(void* c); +int wh_NvmFlashLog_List(void* c, + whNvmAccess access, whNvmFlags flags, whNvmId start_id, + whNvmId *out_avail_objects, whNvmId *out_id); +int wh_NvmFlashLog_GetAvailable(void* c, + uint32_t *out_avail_size, whNvmId *out_avail_objects, + uint32_t *out_reclaim_size, whNvmId *out_reclaim_objects); +int wh_NvmFlashLog_GetMetadata(void* c, whNvmId id, whNvmMetadata* meta); +int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, + whNvmSize data_len, const uint8_t* data); +int wh_NvmFlashLog_DestroyObjects(void* c, whNvmId list_count, + const whNvmId* id_list); +int wh_NvmFlashLog_Read(void* c, whNvmId id, whNvmSize offset, + whNvmSize data_len, uint8_t* data); + +#define WH_NVM_FLASH_LOG_CB \ +{ \ + .Init = wh_NvmFlashLog_Init, \ + .Cleanup = wh_NvmFlashLog_Cleanup, \ + .List = wh_NvmFlashLog_List, \ + .GetAvailable = wh_NvmFlashLog_GetAvailable, \ + .GetMetadata = wh_NvmFlashLog_GetMetadata, \ + .AddObject = wh_NvmFlashLog_AddObject, \ + .DestroyObjects = wh_NvmFlashLog_DestroyObjects, \ + .Read = wh_NvmFlashLog_Read, \ +} + +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ + +#endif /* WOLFHSM_WH_NVM_FLASH_LOG_H_ */ From aa96a6fcbd86b3ee6c15ae53ed4a55ff5f4fc3e3 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 23 Sep 2025 11:29:47 +0200 Subject: [PATCH 02/22] test: generalize whTest_NvmFlashCfg --- test/wh_test_nvm_flash.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/wh_test_nvm_flash.c b/test/wh_test_nvm_flash.c index f6bfd69e6..c3a4f0dbf 100644 --- a/test/wh_test_nvm_flash.c +++ b/test/wh_test_nvm_flash.c @@ -156,7 +156,7 @@ static void _ShowList(const whNvmCb* cb, void* context) static int addObjectWithReadBackCheck(const whNvmCb* cb, - whNvmFlashContext* context, + void* context, whNvmMetadata* meta, whNvmSize data_len, const uint8_t* data) @@ -316,10 +316,8 @@ int whTest_Flash(const whFlashCb* fcb, void* fctx, const void* cfg) return 0; } -int whTest_NvmFlashCfg(whNvmFlashConfig* cfg) +int whTest_NvmFlashCfg(void* cfg, void* context, const whNvmCb *cb) { - const whNvmCb cb[1] = {WH_NVM_FLASH_CB}; - whNvmFlashContext context[1] = {0}; int ret = 0; WH_TEST_RETURN_ON_FAIL(cb->Init(context, cfg)); @@ -495,9 +493,10 @@ int whTest_NvmFlash_RamSim(void) .context = myHalFlashCtx, .config = myHalFlashCfg, }; + whNvmFlashContext nvmFlashCtx[1] = {0}; + const whNvmCb nvmFlashCb[1] = {WH_NVM_FLASH_CB}; - - return whTest_NvmFlashCfg(&myNvmCfg); + return whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb); } static int @@ -629,8 +628,10 @@ int whTest_NvmFlash_PosixFileSim(void) .context = myHalFlashContext, .config = myHalFlashConfig, }; + whNvmFlashContext nvmFlashCtx[1] = {0}; + const whNvmCb nvmFlashCb[1] = {WH_NVM_FLASH_CB}; - WH_TEST_ASSERT(0 == whTest_NvmFlashCfg(&myNvmCfg)); + WH_TEST_ASSERT(0 == whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb)); /* Remove the configured file on success*/ unlink(myHalFlashConfig[0].filename); From b2acfc248b907ce00def509ee853552c2e37969e Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 23 Sep 2025 12:17:02 +0200 Subject: [PATCH 03/22] test: test nvm flash log backend --- test/Makefile | 3 +++ test/wh_test_nvm_flash.c | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 051212dcb..8ce179392 100644 --- a/test/Makefile +++ b/test/Makefile @@ -123,6 +123,9 @@ else DEF += -DWOLFHSM_CFG_IS_TEST_SERVER endif +# Test NVM Flash Log implementation +DEF += -DWOLFHSM_CFG_SERVER_NVM_FLASH_LOG + ## Source files # Assembly source files SRC_ASM += diff --git a/test/wh_test_nvm_flash.c b/test/wh_test_nvm_flash.c index c3a4f0dbf..a2db3a622 100644 --- a/test/wh_test_nvm_flash.c +++ b/test/wh_test_nvm_flash.c @@ -31,6 +31,7 @@ #include "wolfhsm/wh_error.h" #include "wolfhsm/wh_nvm.h" #include "wolfhsm/wh_nvm_flash.h" +#include "wolfhsm/wh_nvm_flash_log.h" #include "wolfhsm/wh_flash_unit.h" /* NVM simulator backends to use for testing NVM module */ @@ -496,7 +497,21 @@ int whTest_NvmFlash_RamSim(void) whNvmFlashContext nvmFlashCtx[1] = {0}; const whNvmCb nvmFlashCb[1] = {WH_NVM_FLASH_CB}; - return whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb); + WH_TEST_RETURN_ON_FAIL(whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb)); + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + whNvmFlashLogConfig myLogCfg = { + .flash_cb = myCb, + .flash_ctx = myHalFlashCtx, + .flash_cfg = myHalFlashCfg, + }; + whNvmFlashLogContext nvmLogCtx[1] = {0}; + const whNvmCb nvmLogCb[1] = {WH_NVM_FLASH_LOG_CB}; + WH_TEST_RETURN_ON_FAIL(whTest_NvmFlashCfg(&myLogCfg, nvmLogCtx, nvmLogCb)); +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ + + return 0; + } static int From 789c049bc1569fd87d32f8140325e47f9f4bb5b8 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 12:53:17 +0200 Subject: [PATCH 04/22] test: use nvm_flash_log to do test if compiled it --- test/wh_test_clientserver.c | 63 ++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/test/wh_test_clientserver.c b/test/wh_test_clientserver.c index 808598431..265ba6ee9 100644 --- a/test/wh_test_clientserver.c +++ b/test/wh_test_clientserver.c @@ -34,6 +34,9 @@ #include "wolfhsm/wh_flash_ramsim.h" #include "wolfhsm/wh_server.h" +#ifdef WOLFHSM_CFG_SERVER_NVM_FLASH_LOG +#include "wolfhsm/wh_nvm_flash_log.h" +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ #endif #include "wolfhsm/wh_message.h" @@ -87,6 +90,21 @@ typedef struct { static int _testNonExportableNvmAccess(whClientContext* client); #endif +/* union helper struct to be able to test alternative NVM implementation */ +typedef struct { + union { + struct { + whNvmFlashContext nvmFlashCtx; + whNvmFlashConfig nvmFlashCfg; + }; +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + struct { + whNvmFlashLogContext nvmFlashLogCtx; + whNvmFlashLogConfig nvmFlashLogCfg; + }; +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ + }; +} whNvmUnion; #ifdef WOLFHSM_CFG_ENABLE_SERVER /* Pointer to a local server context so a connect callback can access it. Should @@ -780,21 +798,42 @@ int whTest_ClientServerSequential(void) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; + whNvmUnion nvm_setup; + whNvmConfig n_conf[1]; + whNvmContext nvm[1] = {{0}}; + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + nvm_setup.nvmFlashLogCfg.flash_cb = fcb; + + /* restrict simulated flash partition to nvm_flash_log_partition */ + WH_TEST_ASSERT(FLASH_RAM_SIZE >= WH_NVM_FLASH_LOG_PARTITION_SIZE * 2); + fc_conf->sectorSize = WH_NVM_FLASH_LOG_PARTITION_SIZE; + fc_conf->size = WH_NVM_FLASH_LOG_PARTITION_SIZE * 2; + nvm_setup.nvmFlashLogCfg.flash_cfg = fc_conf; + nvm_setup.nvmFlashLogCfg.flash_ctx = fc; + + memset(&nvm_setup.nvmFlashCtx, 0, sizeof(nvm_setup.nvmFlashCtx)); + whNvmCb nfcb[1] = {WH_NVM_FLASH_LOG_CB}; + /* setup nvm */ + n_conf[0].cb = nfcb; + n_conf[0].context = &nvm_setup.nvmFlashLogCtx; + n_conf[0].config = &nvm_setup.nvmFlashLogCfg; + +#else /* NVM Flash Configuration using RamSim HAL Flash */ - whNvmFlashConfig nf_conf[1] = {{ - .cb = fcb, - .context = fc, - .config = fc_conf, - }}; - whNvmFlashContext nfc[1] = {0}; + nvm_setup.nvmFlashCfg.cb = fcb; + nvm_setup.nvmFlashCfg.context = fc; + nvm_setup.nvmFlashCfg.config = fc_conf; + + memset(&nvm_setup.nvmFlashCtx, 0, sizeof(nvm_setup.nvmFlashCtx)); whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; - whNvmConfig n_conf[1] = {{ - .cb = nfcb, - .context = nfc, - .config = nf_conf, - }}; - whNvmContext nvm[1] = {{0}}; + /* setup nvm */ + n_conf[0].cb = nfcb; + n_conf[0].context = &nvm_setup.nvmFlashCtx; + n_conf[0].config = &nvm_setup.nvmFlashCfg; +#endif + #ifndef WOLFHSM_CFG_NO_CRYPTO whServerCryptoContext crypto[1] = {{ .devId = INVALID_DEVID, From d197dbb0304088d670f9c9fe2ce08f59b2d5a8a6 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 15:32:02 +0200 Subject: [PATCH 05/22] test: generalize tests to use both NVM backends --- test/wh_test.c | 14 +++- test/wh_test_cert.c | 22 ++----- test/wh_test_cert.h | 4 +- test/wh_test_clientserver.c | 116 ++++++++++------------------------ test/wh_test_common.c | 90 ++++++++++++++++++++++++++ test/wh_test_common.h | 32 ++++++++++ test/wh_test_crypto.c | 30 ++++----- test/wh_test_nvm_flash.c | 18 ++++++ test/wh_test_server_img_mgr.c | 21 ++---- test/wh_test_server_img_mgr.h | 6 +- 10 files changed, 218 insertions(+), 135 deletions(-) create mode 100644 test/wh_test_common.c diff --git a/test/wh_test.c b/test/wh_test.c index 6c33f5bda..c68a63cab 100644 --- a/test/wh_test.c +++ b/test/wh_test.c @@ -66,7 +66,12 @@ int whTest_Unit(void) WH_TEST_ASSERT(0 == whTest_Flash_RamSim()); WH_TEST_ASSERT(0 == whTest_NvmFlash()); #if defined(WOLFHSM_CFG_CERTIFICATE_MANAGER) && !defined(WOLFHSM_CFG_NO_CRYPTO) - WH_TEST_ASSERT(0 == whTest_CertRamSim()); + WH_TEST_ASSERT(0 == whTest_CertRamSim(NVM_TEST_BACKEND_FLASH)); + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + WH_TEST_ASSERT(0 == whTest_CertRamSim(NVM_TEST_BACKEND_FLASH_LOG)); +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ + #endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER && !WOLFHSM_CFG_NO_CRYPTO */ @@ -80,7 +85,12 @@ int whTest_Unit(void) #if defined(WOLFHSM_CFG_SERVER_IMG_MGR) && !defined(WOLFHSM_CFG_NO_CRYPTO) /* Image Manager Tests */ - WH_TEST_ASSERT(0 == whTest_ServerImgMgr()); + WH_TEST_ASSERT(0 == whTest_ServerImgMgr(NVM_TEST_BACKEND_FLASH)); + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + WH_TEST_ASSERT(0 == whTest_ServerImgMgr(NVM_TEST_BACKEND_FLASH_LOG)); +#endif + #endif /* WOLFHSM_CFG_SERVER_IMG_MGR && !WOLFHSM_CFG_NO_CRYPTO */ #if defined(WOLFHSM_CFG_SHE_EXTENSION) diff --git a/test/wh_test_cert.c b/test/wh_test_cert.c index 8c2e0d4fc..de538642f 100644 --- a/test/wh_test_cert.c +++ b/test/wh_test_cert.c @@ -578,7 +578,7 @@ static int whTest_CertNonExportable(whClientContext* client) #endif /* WOLFHSM_CFG_ENABLE_CLIENT */ #ifdef WOLFHSM_CFG_ENABLE_SERVER -int whTest_CertRamSim(void) +int whTest_CertRamSim(NvmTestBackendType nvmType) { int rc = WH_ERROR_OK; const uint32_t BUFFER_SIZE = 1024; @@ -614,21 +614,13 @@ int whTest_CertRamSim(void) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - /* NVM Flash Configuration using RamSim HAL Flash */ - whNvmFlashConfig nf_conf[1] = {{ - .cb = fcb, - .context = fc, - .config = fc_conf, - }}; - whNvmFlashContext nfc[1] = {0}; - whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; - - whNvmConfig n_conf[1] = {{ - .cb = nfcb, - .context = nfc, - .config = nf_conf, - }}; + whNvmUnion nvm_setup; + whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; + + WH_TEST_RETURN_ON_FAIL( + whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + #ifndef WOLFHSM_CFG_NO_CRYPTO whServerCryptoContext crypto[1] = {{ .devId = INVALID_DEVID, diff --git a/test/wh_test_cert.h b/test/wh_test_cert.h index 5deecaa69..36269dc80 100644 --- a/test/wh_test_cert.h +++ b/test/wh_test_cert.h @@ -26,8 +26,10 @@ #include "wolfhsm/wh_server.h" #include "wolfhsm/wh_client.h" +#include "wh_test_common.h" + /* Run certificate configuration tests */ -int whTest_CertRamSim(void); +int whTest_CertRamSim(NvmTestBackendType nvmType); int whTest_CertServerCfg(whServerConfig* serverCfg); int whTest_CertClient(whClientContext* client); #if defined(WOLFHSM_CFG_DMA) diff --git a/test/wh_test_clientserver.c b/test/wh_test_clientserver.c index 265ba6ee9..0ce1fa186 100644 --- a/test/wh_test_clientserver.c +++ b/test/wh_test_clientserver.c @@ -34,9 +34,6 @@ #include "wolfhsm/wh_flash_ramsim.h" #include "wolfhsm/wh_server.h" -#ifdef WOLFHSM_CFG_SERVER_NVM_FLASH_LOG -#include "wolfhsm/wh_nvm_flash_log.h" -#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ #endif #include "wolfhsm/wh_message.h" @@ -90,22 +87,6 @@ typedef struct { static int _testNonExportableNvmAccess(whClientContext* client); #endif -/* union helper struct to be able to test alternative NVM implementation */ -typedef struct { - union { - struct { - whNvmFlashContext nvmFlashCtx; - whNvmFlashConfig nvmFlashCfg; - }; -#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) - struct { - whNvmFlashLogContext nvmFlashLogCtx; - whNvmFlashLogConfig nvmFlashLogCfg; - }; -#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ - }; -} whNvmUnion; - #ifdef WOLFHSM_CFG_ENABLE_SERVER /* Pointer to a local server context so a connect callback can access it. Should * be set before calling wh_ClientInit() */ @@ -745,7 +726,7 @@ static int _testOutOfBoundsNvmReads(whClientContext* client, return WH_ERROR_OK; } -int whTest_ClientServerSequential(void) +int whTest_ClientServerSequential(NvmTestBackendType nvmType) { int ret = 0; @@ -802,37 +783,8 @@ int whTest_ClientServerSequential(void) whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; -#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) - nvm_setup.nvmFlashLogCfg.flash_cb = fcb; - - /* restrict simulated flash partition to nvm_flash_log_partition */ - WH_TEST_ASSERT(FLASH_RAM_SIZE >= WH_NVM_FLASH_LOG_PARTITION_SIZE * 2); - fc_conf->sectorSize = WH_NVM_FLASH_LOG_PARTITION_SIZE; - fc_conf->size = WH_NVM_FLASH_LOG_PARTITION_SIZE * 2; - nvm_setup.nvmFlashLogCfg.flash_cfg = fc_conf; - nvm_setup.nvmFlashLogCfg.flash_ctx = fc; - - memset(&nvm_setup.nvmFlashCtx, 0, sizeof(nvm_setup.nvmFlashCtx)); - whNvmCb nfcb[1] = {WH_NVM_FLASH_LOG_CB}; - /* setup nvm */ - n_conf[0].cb = nfcb; - n_conf[0].context = &nvm_setup.nvmFlashLogCtx; - n_conf[0].config = &nvm_setup.nvmFlashLogCfg; - -#else - /* NVM Flash Configuration using RamSim HAL Flash */ - nvm_setup.nvmFlashCfg.cb = fcb; - nvm_setup.nvmFlashCfg.context = fc; - nvm_setup.nvmFlashCfg.config = fc_conf; - - memset(&nvm_setup.nvmFlashCtx, 0, sizeof(nvm_setup.nvmFlashCtx)); - whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; - - /* setup nvm */ - n_conf[0].cb = nfcb; - n_conf[0].context = &nvm_setup.nvmFlashCtx; - n_conf[0].config = &nvm_setup.nvmFlashCfg; -#endif + WH_TEST_RETURN_ON_FAIL( + whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO whServerCryptoContext crypto[1] = {{ @@ -1805,7 +1757,7 @@ static void _whClientServerThreadTest(whClientConfig* c_conf, } } -static int wh_ClientServer_MemThreadTest(void) +static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) { uint8_t req[BUFFER_SIZE] = {0}; uint8_t resp[BUFFER_SIZE] = {0}; @@ -1850,21 +1802,11 @@ static int wh_ClientServer_MemThreadTest(void) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - /* NVM Flash Configuration using RamSim HAL Flash */ - whNvmFlashConfig nf_conf[1] = {{ - .cb = fcb, - .context = fc, - .config = fc_conf, - }}; - whNvmFlashContext nfc[1] = {0}; - whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; + whNvmUnion nvm_setup; + whNvmConfig n_conf[1] = {0}; + whNvmContext nvm[1] = {{0}}; - whNvmConfig n_conf[1] = {{ - .cb = nfcb, - .context = nfc, - .config = nf_conf, - }}; - whNvmContext nvm[1] = {{0}}; + WH_TEST_RETURN_ON_FAIL(whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO /* Crypto context */ @@ -1902,7 +1844,7 @@ static int wh_ClientServer_MemThreadTest(void) } -static int wh_ClientServer_PosixMemMapThreadTest(void) +static int wh_ClientServer_PosixMemMapThreadTest(NvmTestBackendType nvmType) { posixTransportShmConfig tmcf[1] = {{ .name = "/wh_test_clientserver_shm", @@ -1944,21 +1886,12 @@ static int wh_ClientServer_PosixMemMapThreadTest(void) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - /* NVM Flash Configuration using RamSim HAL Flash */ - whNvmFlashConfig nf_conf[1] = {{ - .cb = fcb, - .context = fc, - .config = fc_conf, - }}; - whNvmFlashContext nfc[1] = {0}; - whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; + whNvmUnion nvm_setup; + whNvmConfig n_conf[1]; + whNvmContext nvm[1] = {{0}}; - whNvmConfig n_conf[1] = {{ - .cb = nfcb, - .context = nfc, - .config = nf_conf, - }}; - whNvmContext nvm[1] = {{0}}; + WH_TEST_RETURN_ON_FAIL( + whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO /* Crypto context */ @@ -1999,14 +1932,29 @@ static int wh_ClientServer_PosixMemMapThreadTest(void) int whTest_ClientServer(void) { printf("Testing client/server sequential: mem...\n"); - WH_TEST_ASSERT(0 == whTest_ClientServerSequential()); + WH_TEST_ASSERT(0 == whTest_ClientServerSequential(NVM_TEST_BACKEND_FLASH)); + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + printf("Testing client/server sequential: mem + flash log...\n"); + WH_TEST_ASSERT(0 == whTest_ClientServerSequential(NVM_TEST_BACKEND_FLASH_LOG)); +#endif /* defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) */ #if defined(WOLFHSM_CFG_TEST_POSIX) printf("Testing client/server: (pthread) mem...\n"); - WH_TEST_ASSERT(0 == wh_ClientServer_MemThreadTest()); + WH_TEST_ASSERT(0 == wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH)); printf("Testing client/server: (pthread) POSIX shared memory ...\n"); - WH_TEST_ASSERT(0 == wh_ClientServer_PosixMemMapThreadTest()); + WH_TEST_ASSERT(0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH)); + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + printf("Testing client/server: (pthread) mem + flash log...\n"); + WH_TEST_ASSERT(0 == + wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); + + printf("Testing client/server: (pthread) POSIX shared memory + flash log...\n"); + WH_TEST_ASSERT(0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); +#endif /* defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) */ + #endif /* defined(WOLFHSM_CFG_TEST_POSIX) */ return 0; diff --git a/test/wh_test_common.c b/test/wh_test_common.c new file mode 100644 index 000000000..1fb61d6eb --- /dev/null +++ b/test/wh_test_common.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2025 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 . + */ + +#include + +#include +#include +#include +#include +#include + +#include "wh_test_common.h" + + +/** + * Helper function to configure and select an NVM backend for testing. + * + * @param type The type of NVM backend to configure (see NvmTestBackendType). + * @param nvmSetup Pointer to a union of NVM backend setup structures (output). + * @param nvmCfg Pointer to the NVM configuration structure to populate (output). + * @param fCfg Pointer to the RamSim flash configuration structure. + * @param fCtx Pointer to the RamSim flash context structure. + * @param fCb Pointer to the RamSim flash callback structure. + * + * @return WH_ERROR_OK on success, or WH_ERROR_BADARGS on failure. + */ +int whTest_NvmSetup(NvmTestBackendType type, whNvmUnion* nvmSetup, + whNvmConfig* nvmCfg, whFlashRamsimCfg* fCfg, + whFlashRamsimCtx* fCtx, const whFlashCb* fCb) +{ + + WH_TEST_ASSERT(nvmSetup != NULL); + WH_TEST_ASSERT(nvmCfg != NULL); + WH_TEST_ASSERT(fCfg != NULL); + + switch (type) { +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + case NVM_TEST_BACKEND_FLASH_LOG: + nvmSetup->nvmFlashLogCfg.flash_cb = fCb; + /* restrict simulated flash partition to nvm_flash_log_partition */ + WH_TEST_ASSERT(fCfg->size >= WH_NVM_FLASH_LOG_PARTITION_SIZE * 2); + fCfg->sectorSize = WH_NVM_FLASH_LOG_PARTITION_SIZE; + nvmSetup->nvmFlashLogCfg.flash_cfg = fCfg; + nvmSetup->nvmFlashLogCfg.flash_ctx = fCtx; + memset(&nvmSetup->nvmFlashLogCtx, 0, + sizeof(nvmSetup->nvmFlashLogCtx)); + static whNvmCb nflcb[1] = {WH_NVM_FLASH_LOG_CB}; + + nvmCfg->cb = nflcb; + nvmCfg->context = &nvmSetup->nvmFlashLogCtx; + nvmCfg->config = &nvmSetup->nvmFlashLogCfg; + break; +#endif + case NVM_TEST_BACKEND_FLASH: + /* NVM Flash Configuration using RamSim HAL Flash */ + nvmSetup->nvmFlashCfg.cb = fCb; + nvmSetup->nvmFlashCfg.context = fCtx; + nvmSetup->nvmFlashCfg.config = fCfg; + + memset(&nvmSetup->nvmFlashCtx, 0, sizeof(nvmSetup->nvmFlashCtx)); + static whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; + + nvmCfg->cb = nfcb; + nvmCfg->context = &nvmSetup->nvmFlashCtx; + nvmCfg->config = &nvmSetup->nvmFlashCfg; + break; + + default: + WH_TEST_ASSERT(0); + return WH_ERROR_BADARGS; + } + + return 0; +} diff --git a/test/wh_test_common.h b/test/wh_test_common.h index a6ba3ff2e..6acecfaaf 100644 --- a/test/wh_test_common.h +++ b/test/wh_test_common.h @@ -26,6 +26,10 @@ #include #endif +#include +#include +#include +#include #define WH_TEST_FAIL (-1) #define WH_TEST_SUCCESS (0) @@ -106,4 +110,32 @@ } while (0) + +typedef enum { + NVM_TEST_BACKEND_FLASH = 0, +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + NVM_TEST_BACKEND_FLASH_LOG, +#endif + NVM_TEST_BACKEND_COUNT +} NvmTestBackendType; + +/* union helper struct to be able to test more than one NVM implementation */ +typedef struct { + union { + struct { + whNvmFlashContext nvmFlashCtx; + whNvmFlashConfig nvmFlashCfg; + }; +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + struct { + whNvmFlashLogContext nvmFlashLogCtx; + whNvmFlashLogConfig nvmFlashLogCfg; + }; +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ + }; +} whNvmUnion; + +int whTest_NvmSetup(NvmTestBackendType type, whNvmUnion* nvmSetup, + whNvmConfig* nvmCfg, whFlashRamsimCfg* fCfg, + whFlashRamsimCtx* fCtx, const whFlashCb* fCb); #endif /* WH_TEST_COMMON_H_ */ diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index 7da2aaec9..6142020e5 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -3614,7 +3614,8 @@ static void _whClientServerThreadTest(whClientConfig* c_conf, } } -static int wh_ClientServer_MemThreadTest(void) + +static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) { uint8_t req[BUFFER_SIZE] = {0}; uint8_t resp[BUFFER_SIZE] = {0}; @@ -3671,21 +3672,12 @@ static int wh_ClientServer_MemThreadTest(void) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - /* NVM Flash Configuration using RamSim HAL Flash */ - whNvmFlashConfig nf_conf[1] = {{ - .cb = fcb, - .context = fc, - .config = fc_conf, - }}; - whNvmFlashContext nfc[1] = {0}; - whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; + whNvmUnion nvm_setup; + whNvmConfig n_conf[1]; + whNvmContext nvm[1] = {{0}}; - whNvmConfig n_conf[1] = {{ - .cb = nfcb, - .context = nfc, - .config = nf_conf, - }}; - whNvmContext nvm[1] = {{0}}; + WH_TEST_RETURN_ON_FAIL( + whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); /* Crypto context */ whServerCryptoContext crypto[1] = {{ @@ -3720,7 +3712,13 @@ static int wh_ClientServer_MemThreadTest(void) int whTest_Crypto(void) { printf("Testing crypto: (pthread) mem...\n"); - WH_TEST_RETURN_ON_FAIL(wh_ClientServer_MemThreadTest()); + WH_TEST_RETURN_ON_FAIL(wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH)); + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + printf("Testing crypto: (pthread) mem (flash log)...\n"); + WH_TEST_RETURN_ON_FAIL(wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); +#endif + return 0; } #endif /* WOLFHSM_CFG_TEST_POSIX && WOLFHSM_CFG_ENABLE_CLIENT && \ diff --git a/test/wh_test_nvm_flash.c b/test/wh_test_nvm_flash.c index a2db3a622..1b50a8776 100644 --- a/test/wh_test_nvm_flash.c +++ b/test/wh_test_nvm_flash.c @@ -648,6 +648,24 @@ int whTest_NvmFlash_PosixFileSim(void) WH_TEST_ASSERT(0 == whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb)); + + unlink(myHalFlashConfig[0].filename); + +#if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) + WH_TEST_ASSERT(myHalFlashConfig[0].partition_size >= + WH_NVM_FLASH_LOG_PARTITION_SIZE); + myHalFlashConfig[0].partition_size = WH_NVM_FLASH_LOG_PARTITION_SIZE; + memset(myHalFlashContext, 0, sizeof(myHalFlashContext)); + whNvmFlashLogConfig myLogCfg = { + .flash_cb = myCb, + .flash_ctx = myHalFlashContext, + .flash_cfg = myHalFlashConfig, + }; + whNvmFlashLogContext nvmLogCtx[1] = {0}; + const whNvmCb nvmLogCb[1] = {WH_NVM_FLASH_LOG_CB}; + WH_TEST_RETURN_ON_FAIL(whTest_NvmFlashCfg(&myLogCfg, nvmLogCtx, nvmLogCb)); +#endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ + /* Remove the configured file on success*/ unlink(myHalFlashConfig[0].filename); return 0; diff --git a/test/wh_test_server_img_mgr.c b/test/wh_test_server_img_mgr.c index 45b50d4b8..83b2b5d6b 100644 --- a/test/wh_test_server_img_mgr.c +++ b/test/wh_test_server_img_mgr.c @@ -1192,7 +1192,7 @@ static int whTest_ServerImgMgrServerCfgRsa2048(whServerConfig* serverCfg) } #endif /* !NO_RSA */ -int whTest_ServerImgMgr(void) +int whTest_ServerImgMgr(NvmTestBackendType nvmType) { int rc = 0; const uint32_t BUFFER_SIZE = 1024; @@ -1229,22 +1229,13 @@ int whTest_ServerImgMgr(void) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - /* NVM Flash Configuration using RamSim HAL Flash */ - whNvmFlashConfig nf_conf[1] = {{ - .cb = fcb, - .context = fc, - .config = fc_conf, - }}; - whNvmFlashContext nfc[1] = {0}; - whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; - - whNvmConfig n_conf[1] = {{ - .cb = nfcb, - .context = nfc, - .config = nf_conf, - }}; + whNvmUnion nvm_setup; + whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; + WH_TEST_RETURN_ON_FAIL( + whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + whServerCryptoContext crypto[1] = {{ .devId = INVALID_DEVID, }}; diff --git a/test/wh_test_server_img_mgr.h b/test/wh_test_server_img_mgr.h index 576422ea3..e748d9e35 100644 --- a/test/wh_test_server_img_mgr.h +++ b/test/wh_test_server_img_mgr.h @@ -20,6 +20,8 @@ #ifndef WH_TEST_SERVER_IMG_MGR_H #define WH_TEST_SERVER_IMG_MGR_H -int whTest_ServerImgMgr(void); +#include "wh_test_common.h" -#endif /* WH_TEST_SERVER_IMG_MGR_H */ \ No newline at end of file +int whTest_ServerImgMgr(NvmTestBackendType nvmType); + +#endif /* WH_TEST_SERVER_IMG_MGR_H */ From 360fcf4d2695148abcf7dac278cd7b82725aa232 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 12:54:45 +0200 Subject: [PATCH 06/22] nvm_flash_log: fix and refactor List callback --- src/wh_nvm_flash_log.c | 64 ++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index f470d594f..2d4224072 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -69,6 +69,18 @@ typedef struct { }; } whNvmFlashLogMetadata; +static whNvmFlashLogMetadata* wh_NvmFlashLog_GetNextObj(whNvmFlashLogContext* ctx, + whNvmFlashLogMetadata* obj) +{ + if (obj == NULL || ctx == NULL) + return NULL; + uint8_t* next = (uint8_t*)obj + sizeof(whNvmFlashLogMetadata) + + PAD_SIZE(obj->meta.len); + if (next >= ctx->directory.data + ctx->directory.header.size) + return NULL; + return (whNvmFlashLogMetadata*)next; +} + static int wh_NvmFlashLog_ErasePartition(whNvmFlashLogContext* ctx, uint32_t partition) { @@ -196,18 +208,16 @@ static whNvmFlashLogMetadata* wh_NvmFlashLog_FindObjectById(whNvmFlashLogContext* ctx, whNvmId id) { whNvmFlashLogMetadata* obj; - uint8_t* idx; if (ctx == NULL) return NULL; - idx = ctx->directory.data; - while (idx < ctx->directory.data + ctx->directory.header.size) { - obj = (whNvmFlashLogMetadata*)idx; + obj = (whNvmFlashLogMetadata*)ctx->directory.data; + while (obj != NULL) { if (obj->meta.id == id) { return obj; } - idx += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); + obj = wh_NvmFlashLog_GetNextObj(ctx, obj); } return NULL; } @@ -236,26 +246,25 @@ static int wh_NvmFlashLog_CountObjects(whNvmFlashLogContext* ctx, whNvmFlashLogMetadata* start_obj) { whNvmFlashLogMetadata* obj; - uint8_t* idx; int count = 0; if (ctx == NULL) return 0; - idx = (start_obj != NULL) ? (uint8_t*)start_obj : ctx->directory.data; - if (idx < ctx->directory.data || - idx >= ctx->directory.data + ctx->directory.header.size) { + obj = (start_obj != NULL) ? start_obj : (whNvmFlashLogMetadata*)ctx->directory.data; + if ((uint8_t*)obj < ctx->directory.data || + (uint8_t*)obj >= ctx->directory.data + ctx->directory.header.size) { return 0; } - while (idx < ctx->directory.data + ctx->directory.header.size) { - obj = (whNvmFlashLogMetadata*)idx; + while (obj != NULL) { if (obj->meta.id == WH_NVM_ID_INVALID) { break; } count++; - idx += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); + obj = wh_NvmFlashLog_GetNextObj(ctx, obj); } + return count; } @@ -389,39 +398,34 @@ int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, (void)access; (void)flags; whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; - whNvmFlashLogMetadata* obj; - uint32_t count; + whNvmFlashLogMetadata* next_obj = NULL, *start_obj = NULL; + uint32_t count = 0; if (ctx == NULL) return WH_ERROR_BADARGS; - obj = wh_NvmFlashLog_FindObjectById(ctx, start_id); - if (obj == NULL) { - if (out_count != NULL) - *out_count = 0; - if (out_id != NULL) - *out_id = WH_NVM_ID_INVALID; - return WH_ERROR_OK; + /* list all obects if start_id is WH_NVM_ID_INVALID */ + if (start_id == WH_NVM_ID_INVALID) { + next_obj = (whNvmFlashLogMetadata*)ctx->directory.data; + } else { + start_obj = wh_NvmFlashLog_FindObjectById(ctx, start_id); + if (start_obj != NULL && start_obj->meta.id != WH_NVM_ID_INVALID) + next_obj = wh_NvmFlashLog_GetNextObj(ctx, start_obj); } - /* check next object */ - obj = - (whNvmFlashLogMetadata*)((uint8_t*)obj + sizeof(whNvmFlashLogMetadata) + - PAD_SIZE(obj->meta.len)); - if (obj >= (whNvmFlashLogMetadata*)(ctx->directory.data + - ctx->directory.header.size) || - obj->meta.id == WH_NVM_ID_INVALID) { + if (next_obj == NULL || next_obj->meta.id == WH_NVM_ID_INVALID) { if (out_count != NULL) *out_count = 0; if (out_id != NULL) *out_id = WH_NVM_ID_INVALID; return WH_ERROR_OK; } - count = wh_NvmFlashLog_CountObjects(ctx, obj); + + count = wh_NvmFlashLog_CountObjects(ctx, next_obj); if (out_count != NULL) *out_count = count; if (out_id != NULL) - *out_id = obj->meta.id; + *out_id = next_obj->meta.id; return WH_ERROR_OK; } From c1a27fcb488f05a78503993d6e0c768d156117d5 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 16:10:13 +0200 Subject: [PATCH 07/22] nvm_flash_log: rename and add arg checking to local functions --- src/wh_nvm_flash_log.c | 163 +++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 71 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 2d4224072..00ddd368d 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -69,8 +69,8 @@ typedef struct { }; } whNvmFlashLogMetadata; -static whNvmFlashLogMetadata* wh_NvmFlashLog_GetNextObj(whNvmFlashLogContext* ctx, - whNvmFlashLogMetadata* obj) +static whNvmFlashLogMetadata* nfl_ObjNext(whNvmFlashLogContext* ctx, + whNvmFlashLogMetadata* obj) { if (obj == NULL || ctx == NULL) return NULL; @@ -81,35 +81,39 @@ static whNvmFlashLogMetadata* wh_NvmFlashLog_GetNextObj(whNvmFlashLogContext* ct return (whNvmFlashLogMetadata*)next; } -static int wh_NvmFlashLog_ErasePartition(whNvmFlashLogContext* ctx, - uint32_t partition) +static int nfl_PartitionErase(whNvmFlashLogContext* ctx, uint32_t partition) { const whFlashCb* f_cb = ctx->flash_cb; - uint32_t part_offset; + uint32_t off; int ret; - part_offset = partition * ctx->partition_size; - ret = f_cb->Erase(ctx->flash_ctx, part_offset, ctx->partition_size); + if (ctx == NULL || partition > 1) + return WH_ERROR_BADARGS; + + off = partition * ctx->partition_size; + ret = f_cb->Erase(ctx->flash_ctx, off, ctx->partition_size); if (ret != 0) return ret; return WH_ERROR_OK; } -static int wh_NvmFlashLog_WritePartition(whNvmFlashLogContext* ctx, - uint32_t partition) +static int nfl_PartitionWrite(whNvmFlashLogContext* ctx, uint32_t partition) { const whFlashCb* f_cb = ctx->flash_cb; - uint32_t part_offset; + uint32_t off; int ret; - part_offset = partition * ctx->partition_size; + if (ctx == NULL || partition > 1) + return WH_ERROR_BADARGS; + + off = partition * ctx->partition_size; if (ctx->directory.header.size % WH_NVM_FLASH_LOG_WRITE_GRANULARITY != 0) return WH_ERROR_ABORTED; if (ctx->directory.header.size > 0) { ret = f_cb->Program(ctx->flash_ctx, - part_offset + sizeof(whNvmFlashLogPartitionHeader), + off + sizeof(whNvmFlashLogPartitionHeader), ctx->directory.header.size, ctx->directory.data); if (ret != 0) return ret; @@ -118,20 +122,22 @@ static int wh_NvmFlashLog_WritePartition(whNvmFlashLogContext* ctx, return WH_ERROR_OK; } -static int wh_NvmFlashLog_CommitPartition(whNvmFlashLogContext* ctx, - uint32_t partition) +static int nfl_PartitionCommit(whNvmFlashLogContext* ctx, uint32_t partition) { const whFlashCb* f_cb = ctx->flash_cb; - uint32_t part_offset; + uint32_t off; int ret; - part_offset = partition * ctx->partition_size; + if (ctx == NULL || partition > 1) + return WH_ERROR_BADARGS; + + off = partition * ctx->partition_size; - ret = f_cb->BlankCheck(ctx->flash_ctx, part_offset, + ret = f_cb->BlankCheck(ctx->flash_ctx, off, sizeof(whNvmFlashLogPartitionHeader)); if (ret != 0) return ret; - ret = f_cb->Program(ctx->flash_ctx, part_offset, + ret = f_cb->Program(ctx->flash_ctx, off, sizeof(whNvmFlashLogPartitionHeader), (uint8_t*)&ctx->directory.header); if (ret != 0) @@ -140,7 +146,7 @@ static int wh_NvmFlashLog_CommitPartition(whNvmFlashLogContext* ctx, return WH_ERROR_OK; } -static int wh_NvmFlashLog_ChoosePartition(whNvmFlashLogContext* ctx) +static int nfl_PartitionChoose(whNvmFlashLogContext* ctx) { whNvmFlashLogPartitionHeader header0, header1; const whFlashCb* f_cb = ctx->flash_cb; @@ -148,6 +154,9 @@ static int wh_NvmFlashLog_ChoosePartition(whNvmFlashLogContext* ctx) int part0_blank, part1_blank; int ret; + if (ctx == NULL) + return WH_ERROR_BADARGS; + part1_offset = ctx->partition_size; ret = f_cb->BlankCheck(ctx->flash_ctx, 0, sizeof(header0)); @@ -164,10 +173,10 @@ static int wh_NvmFlashLog_ChoosePartition(whNvmFlashLogContext* ctx) if (part0_blank && part1_blank) { /* Both partitions are blank, start with partition 0 */ - ret = wh_NvmFlashLog_ErasePartition(ctx, 0); + ret = nfl_PartitionErase(ctx, 0); if (ret != 0) return ret; - ret = wh_NvmFlashLog_CommitPartition(ctx, 0); + ret = nfl_PartitionCommit(ctx, 0); if (ret != 0) return ret; return WH_ERROR_OK; @@ -201,82 +210,91 @@ static int wh_NvmFlashLog_ChoosePartition(whNvmFlashLogContext* ctx) ctx->active_partition = 1; } - return 0; + return WH_ERROR_OK; } -static whNvmFlashLogMetadata* -wh_NvmFlashLog_FindObjectById(whNvmFlashLogContext* ctx, whNvmId id) +static whNvmFlashLogMetadata* nfl_ObjectFindById(whNvmFlashLogContext* ctx, + whNvmId id) { whNvmFlashLogMetadata* obj; - if (ctx == NULL) + if (ctx == NULL || id == WH_NVM_ID_INVALID) return NULL; obj = (whNvmFlashLogMetadata*)ctx->directory.data; - while (obj != NULL) { + while (obj != NULL && obj->meta.id != WH_NVM_ID_INVALID) { if (obj->meta.id == id) { return obj; } - obj = wh_NvmFlashLog_GetNextObj(ctx, obj); + obj = nfl_ObjNext(ctx, obj); } return NULL; } -static int wh_NvmFlashLog_DestroyObject(whNvmFlashLogContext* ctx, whNvmId id) +static int nfl_ObjectDestroy(whNvmFlashLogContext* ctx, whNvmId id) { whNvmFlashLogMetadata* obj; - uint32_t obj_len; - uint32_t obj_off; + uint32_t len; + uint32_t off; - obj = wh_NvmFlashLog_FindObjectById(ctx, id); + if (ctx == NULL || id == WH_NVM_ID_INVALID) + return WH_ERROR_BADARGS; + + obj = nfl_ObjectFindById(ctx, id); if (obj == NULL) return WH_ERROR_OK; - obj_len = sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); - obj_off = (uint8_t*)obj - ctx->directory.data; + len = sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); + off = (uint8_t*)obj - ctx->directory.data; /* zero out the object to prevent leaking */ - memset(obj, 0, obj_len); - memmove(obj, (uint8_t*)obj + obj_len, - ctx->directory.header.size - (obj_off + obj_len)); - ctx->directory.header.size -= obj_len; + memset(obj, 0, len); + memmove(obj, (uint8_t*)obj + len, + ctx->directory.header.size - (off + len)); + ctx->directory.header.size -= len; return WH_ERROR_OK; } -static int wh_NvmFlashLog_CountObjects(whNvmFlashLogContext* ctx, - whNvmFlashLogMetadata* start_obj) +static int nfl_ObjectCount(whNvmFlashLogContext* ctx, + whNvmFlashLogMetadata* startObj) { - whNvmFlashLogMetadata* obj; - int count = 0; + int count = 0; if (ctx == NULL) return 0; - obj = (start_obj != NULL) ? start_obj : (whNvmFlashLogMetadata*)ctx->directory.data; - if ((uint8_t*)obj < ctx->directory.data || - (uint8_t*)obj >= ctx->directory.data + ctx->directory.header.size) { + if (startObj == NULL) { + startObj = (whNvmFlashLogMetadata*)ctx->directory.data; + } + + if ((uint8_t*)startObj < ctx->directory.data || + (uint8_t*)startObj >= ctx->directory.data + ctx->directory.header.size) { return 0; } - while (obj != NULL) { - if (obj->meta.id == WH_NVM_ID_INVALID) { + while (startObj != NULL) { + if (startObj->meta.id == WH_NVM_ID_INVALID) { break; } count++; - obj = wh_NvmFlashLog_GetNextObj(ctx, obj); + startObj = nfl_ObjNext(ctx, startObj); } return count; } -static int wh_NvmFlashLog_ReadPartition(whNvmFlashLogContext* ctx) +static int nfl_PartitionRead(whNvmFlashLogContext* ctx) { - const whFlashCb* f_cb = ctx->flash_cb; - uint32_t part_offset; + const whFlashCb* f_cb; + uint32_t off; int ret; - part_offset = ctx->active_partition * ctx->partition_size; + if (ctx == NULL) + return WH_ERROR_BADARGS; + + f_cb = ctx->flash_cb; + off = ctx->active_partition * ctx->partition_size; - ret = f_cb->Read(ctx->flash_ctx, part_offset, + ret = f_cb->Read(ctx->flash_ctx, off, sizeof(whNvmFlashLogPartitionHeader), (uint8_t*)&ctx->directory.header); if (ret != 0) @@ -289,7 +307,7 @@ static int wh_NvmFlashLog_ReadPartition(whNvmFlashLogContext* ctx) if (ctx->directory.header.size > 0) { ret = f_cb->Read(ctx->flash_ctx, - part_offset + sizeof(whNvmFlashLogPartitionHeader), + off + sizeof(whNvmFlashLogPartitionHeader), ctx->directory.header.size, ctx->directory.data); if (ret != 0) return ret; @@ -298,20 +316,23 @@ static int wh_NvmFlashLog_ReadPartition(whNvmFlashLogContext* ctx) return WH_ERROR_OK; } -static int wh_NvmFlashLog_NewEpoch(whNvmFlashLogContext* ctx) +static int nfl_PartitionNewEpoch(whNvmFlashLogContext* ctx) { int next_active; int ret; + if (ctx == NULL) + return WH_ERROR_BADARGS; + next_active = (ctx->active_partition == 0) ? 1 : 0; ctx->directory.header.partition_epoch++; - ret = wh_NvmFlashLog_ErasePartition(ctx, next_active); + ret = nfl_PartitionErase(ctx, next_active); if (ret != 0) return ret; - ret = wh_NvmFlashLog_WritePartition(ctx, next_active); + ret = nfl_PartitionWrite(ctx, next_active); if (ret != 0) return ret; - ret = wh_NvmFlashLog_CommitPartition(ctx, next_active); + ret = nfl_PartitionCommit(ctx, next_active); if (ret != 0) return ret; ctx->active_partition = next_active; @@ -360,10 +381,10 @@ int wh_NvmFlashLog_Init(void* c, const void* cf) if (ret != 0) return ret; - ret = wh_NvmFlashLog_ChoosePartition(context); + ret = nfl_PartitionChoose(context); if (ret != 0) return ret; - ret = wh_NvmFlashLog_ReadPartition(context); + ret = nfl_PartitionRead(context); if (ret != 0) return ret; @@ -408,9 +429,9 @@ int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, if (start_id == WH_NVM_ID_INVALID) { next_obj = (whNvmFlashLogMetadata*)ctx->directory.data; } else { - start_obj = wh_NvmFlashLog_FindObjectById(ctx, start_id); + start_obj = nfl_ObjectFindById(ctx, start_id); if (start_obj != NULL && start_obj->meta.id != WH_NVM_ID_INVALID) - next_obj = wh_NvmFlashLog_GetNextObj(ctx, start_obj); + next_obj = nfl_ObjNext(ctx, start_obj); } if (next_obj == NULL || next_obj->meta.id == WH_NVM_ID_INVALID) { @@ -421,7 +442,7 @@ int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, return WH_ERROR_OK; } - count = wh_NvmFlashLog_CountObjects(ctx, next_obj); + count = nfl_ObjectCount(ctx, next_obj); if (out_count != NULL) *out_count = count; if (out_id != NULL) @@ -448,7 +469,7 @@ int wh_NvmFlashLog_GetAvailable(void* c, uint32_t* out_avail_size, } if (out_avail_objects != NULL) { - count = wh_NvmFlashLog_CountObjects(ctx, NULL); + count = nfl_ObjectCount(ctx, NULL); *out_avail_objects = WOLFHSM_CFG_NVM_OBJECT_COUNT - count; } @@ -472,7 +493,7 @@ int wh_NvmFlashLog_GetMetadata(void* c, whNvmId id, whNvmMetadata* meta) if (ctx == NULL || meta == NULL) return WH_ERROR_BADARGS; - obj = wh_NvmFlashLog_FindObjectById(ctx, id); + obj = nfl_ObjectFindById(ctx, id); if (obj == NULL) { return WH_ERROR_NOTFOUND; } @@ -493,7 +514,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, if (ctx == NULL || meta == NULL || (data_len > 0 && data == NULL)) return WH_ERROR_BADARGS; - count = wh_NvmFlashLog_CountObjects(ctx, NULL); + count = nfl_ObjectCount(ctx, NULL); if (count >= WOLFHSM_CFG_NVM_OBJECT_COUNT) return WH_ERROR_NOSPACE; @@ -501,7 +522,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, sizeof(whNvmFlashLogPartitionHeader) - ctx->directory.header.size; - old_obj = wh_NvmFlashLog_FindObjectById(ctx, meta->id); + old_obj = nfl_ObjectFindById(ctx, meta->id); if (old_obj != NULL) { available_space += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(old_obj->meta.len); @@ -511,7 +532,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, return WH_ERROR_NOSPACE; if (old_obj) { - ret = wh_NvmFlashLog_DestroyObject(ctx, meta->id); + ret = nfl_ObjectDestroy(ctx, meta->id); if (ret != WH_ERROR_OK) return ret; } @@ -524,7 +545,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, ctx->directory.header.size += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(data_len); - return wh_NvmFlashLog_NewEpoch(ctx); + return nfl_PartitionNewEpoch(ctx); } /* Destroy objects by id list */ @@ -542,12 +563,12 @@ int wh_NvmFlashLog_DestroyObjects(void* c, whNvmId list_count, return WH_ERROR_OK; for (i = 0; i < list_count; i++) { - ret = wh_NvmFlashLog_DestroyObject(ctx, id_list[i]); + ret = nfl_ObjectDestroy(ctx, id_list[i]); if (ret != WH_ERROR_OK) return ret; } - return wh_NvmFlashLog_NewEpoch(ctx); + return nfl_PartitionNewEpoch(ctx); } /* Read object data */ @@ -561,7 +582,7 @@ int wh_NvmFlashLog_Read(void* c, whNvmId id, whNvmSize offset, if (ctx == NULL || (data_len > 0 && data == NULL)) return WH_ERROR_BADARGS; - obj = wh_NvmFlashLog_FindObjectById(ctx, id); + obj = nfl_ObjectFindById(ctx, id); if (obj == NULL) return WH_ERROR_NOTFOUND; From 180aada56ff5bebb8a4a31aece70aee634766b05 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 16:40:30 +0200 Subject: [PATCH 08/22] nvm_flash_log: check context is initialized in public functions --- src/wh_nvm_flash_log.c | 16 +++++++++------- wolfhsm/wh_nvm_flash_log.h | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 00ddd368d..cda863735 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -388,6 +388,7 @@ int wh_NvmFlashLog_Init(void* c, const void* cf) if (ret != 0) return ret; + context->is_initialized = 1; return WH_ERROR_OK; } @@ -395,7 +396,7 @@ int wh_NvmFlashLog_Cleanup(void* c) { int ret; whNvmFlashLogContext* context = (whNvmFlashLogContext*)c; - if (context == NULL) + if (context == NULL || !context->is_initialized) return WH_ERROR_BADARGS; /* lock partitions */ @@ -408,6 +409,7 @@ int wh_NvmFlashLog_Cleanup(void* c) if (ret != 0) return ret; + context->is_initialized = 0; return WH_ERROR_OK; } @@ -422,7 +424,7 @@ int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, whNvmFlashLogMetadata* next_obj = NULL, *start_obj = NULL; uint32_t count = 0; - if (ctx == NULL) + if (ctx == NULL || !ctx->is_initialized) return WH_ERROR_BADARGS; /* list all obects if start_id is WH_NVM_ID_INVALID */ @@ -460,7 +462,7 @@ int wh_NvmFlashLog_GetAvailable(void* c, uint32_t* out_avail_size, whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; uint8_t count; - if (ctx == NULL) + if (ctx == NULL || !ctx->is_initialized) return WH_ERROR_BADARGS; if (out_avail_size != NULL) { *out_avail_size = ctx->partition_size - @@ -490,7 +492,7 @@ int wh_NvmFlashLog_GetMetadata(void* c, whNvmId id, whNvmMetadata* meta) whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; whNvmFlashLogMetadata* obj; - if (ctx == NULL || meta == NULL) + if (ctx == NULL || !ctx->is_initialized || meta == NULL) return WH_ERROR_BADARGS; obj = nfl_ObjectFindById(ctx, id); @@ -511,7 +513,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, uint32_t ret; uint32_t count; - if (ctx == NULL || meta == NULL || (data_len > 0 && data == NULL)) + if (ctx == NULL || !ctx->is_initialized || meta == NULL || (data_len > 0 && data == NULL)) return WH_ERROR_BADARGS; count = nfl_ObjectCount(ctx, NULL); @@ -556,7 +558,7 @@ int wh_NvmFlashLog_DestroyObjects(void* c, whNvmId list_count, int i; int ret; - if (ctx == NULL || (list_count > 0 && id_list == NULL)) + if (ctx == NULL || !ctx->is_initialized || (list_count > 0 && id_list == NULL)) return WH_ERROR_BADARGS; if (list_count == 0) @@ -579,7 +581,7 @@ int wh_NvmFlashLog_Read(void* c, whNvmId id, whNvmSize offset, whNvmFlashLogMetadata* obj; uint8_t* obj_data; - if (ctx == NULL || (data_len > 0 && data == NULL)) + if (ctx == NULL || !ctx->is_initialized || (data_len > 0 && data == NULL)) return WH_ERROR_BADARGS; obj = nfl_ObjectFindById(ctx, id); diff --git a/wolfhsm/wh_nvm_flash_log.h b/wolfhsm/wh_nvm_flash_log.h index d3cf83bf6..a03240f37 100644 --- a/wolfhsm/wh_nvm_flash_log.h +++ b/wolfhsm/wh_nvm_flash_log.h @@ -55,6 +55,7 @@ typedef struct { void* flash_ctx; /* Flash context */ uint32_t partition_size; uint32_t active_partition; /* 0 or 1 */ + int is_initialized; whNvmFlashLogMemPartition directory; } whNvmFlashLogContext; From aaa0f838060920863843b4e9f6163edc8041dc60 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 16:41:09 +0200 Subject: [PATCH 09/22] nvm_flash_log: fix mem clean on obj destroy + minors --- src/wh_nvm_flash_log.c | 70 +++++++++++++++++++++++--------------- wolfhsm/wh_nvm_flash_log.h | 2 +- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index cda863735..4b46c9476 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -65,7 +65,7 @@ typedef struct { union { whNvmMetadata meta; - uint8_t _pad[PAD_SIZE(sizeof(whNvmMetadata))]; + uint8_t WH_PAD[PAD_SIZE(sizeof(whNvmMetadata))]; }; } whNvmFlashLogMetadata; @@ -172,7 +172,7 @@ static int nfl_PartitionChoose(whNvmFlashLogContext* ctx) part1_blank = (ret == 0); if (part0_blank && part1_blank) { - /* Both partitions are blank, start with partition 0 */ + /* Both partitions headers are blank, start with partition 0 */ ret = nfl_PartitionErase(ctx, 0); if (ret != 0) return ret; @@ -236,6 +236,7 @@ static int nfl_ObjectDestroy(whNvmFlashLogContext* ctx, whNvmId id) whNvmFlashLogMetadata* obj; uint32_t len; uint32_t off; + uint32_t tail; if (ctx == NULL || id == WH_NVM_ID_INVALID) return WH_ERROR_BADARGS; @@ -244,12 +245,12 @@ static int nfl_ObjectDestroy(whNvmFlashLogContext* ctx, whNvmId id) if (obj == NULL) return WH_ERROR_OK; - len = sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); - off = (uint8_t*)obj - ctx->directory.data; - /* zero out the object to prevent leaking */ - memset(obj, 0, len); - memmove(obj, (uint8_t*)obj + len, - ctx->directory.header.size - (off + len)); + len = sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); + off = (uint8_t*)obj - ctx->directory.data; + tail = ctx->directory.header.size - (off + len); + memmove(obj, (uint8_t*)obj + len, tail); + /* be sure to clean-up moved objects from memory */ + memset((uint8_t*)obj + tail, 0, len); ctx->directory.header.size -= len; return WH_ERROR_OK; } @@ -372,19 +373,25 @@ int wh_NvmFlashLog_Init(void* c, const void* cf) } /* unlock partitions */ - ret = context->flash_cb->WriteUnlock(context->flash_ctx, 0, - context->partition_size); - if (ret != 0) - return ret; - ret = context->flash_cb->WriteUnlock( - context->flash_ctx, context->partition_size, context->partition_size); - if (ret != 0) - return ret; + if (context->flash_cb->WriteUnlock != NULL) { + ret = context->flash_cb->WriteUnlock(context->flash_ctx, 0, + context->partition_size); + if (ret != 0) + return ret; + ret = context->flash_cb->WriteUnlock(context->flash_ctx, + context->partition_size, + context->partition_size); + if (ret != 0) + return ret; + } ret = nfl_PartitionChoose(context); if (ret != 0) return ret; ret = nfl_PartitionRead(context); + if (ret != 0) + return ret; + ret = nfl_PartitionErase(context, (context->active_partition == 0) ? 1 : 0); if (ret != 0) return ret; @@ -394,22 +401,28 @@ int wh_NvmFlashLog_Init(void* c, const void* cf) int wh_NvmFlashLog_Cleanup(void* c) { - int ret; whNvmFlashLogContext* context = (whNvmFlashLogContext*)c; + int ret0, ret1; + if (context == NULL || !context->is_initialized) return WH_ERROR_BADARGS; + context->is_initialized = 0; + /* lock partitions */ - ret = context->flash_cb->WriteLock(context->flash_ctx, 0, - context->partition_size); - if (ret != 0) - return ret; - ret = context->flash_cb->WriteLock( + if (context->flash_cb->WriteLock == NULL) + return WH_ERROR_OK; + + ret0 = context->flash_cb->WriteLock(context->flash_ctx, 0, + context->partition_size); + ret1 = context->flash_cb->WriteLock( context->flash_ctx, context->partition_size, context->partition_size); - if (ret != 0) - return ret; - context->is_initialized = 0; + if (ret0 != WH_ERROR_OK) + return ret0; + if (ret1 != WH_ERROR_OK) + return ret1; + return WH_ERROR_OK; } @@ -417,12 +430,13 @@ int wh_NvmFlashLog_Cleanup(void* c) int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, whNvmId start_id, whNvmId* out_count, whNvmId* out_id) { + whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; + whNvmFlashLogMetadata *next_obj = NULL, *start_obj = NULL; + uint32_t count = 0; + /* TODO: Implement access and flag matching */ (void)access; (void)flags; - whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; - whNvmFlashLogMetadata* next_obj = NULL, *start_obj = NULL; - uint32_t count = 0; if (ctx == NULL || !ctx->is_initialized) return WH_ERROR_BADARGS; diff --git a/wolfhsm/wh_nvm_flash_log.h b/wolfhsm/wh_nvm_flash_log.h index a03240f37..ef378ca04 100644 --- a/wolfhsm/wh_nvm_flash_log.h +++ b/wolfhsm/wh_nvm_flash_log.h @@ -40,7 +40,7 @@ typedef struct { uint32_t partition_epoch; uint32_t size; - uint8_t _pad[WH_NVM_FLASH_LOG_WRITE_GRANULARITY - sizeof(uint32_t) * 2]; + uint8_t WH_PAD[WH_NVM_FLASH_LOG_WRITE_GRANULARITY - sizeof(uint32_t) * 2]; } whNvmFlashLogPartitionHeader; /* In-memory representation of a partition */ From 94148cd8dd91c99e4aa4a0585ff7a04cbc2633fb Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 17:50:31 +0200 Subject: [PATCH 10/22] nvm_flash_log: allow NULL metadata in GetMetadata --- src/wh_nvm_flash_log.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 4b46c9476..08b5a70cd 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -506,7 +506,7 @@ int wh_NvmFlashLog_GetMetadata(void* c, whNvmId id, whNvmMetadata* meta) whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; whNvmFlashLogMetadata* obj; - if (ctx == NULL || !ctx->is_initialized || meta == NULL) + if (ctx == NULL || !ctx->is_initialized) return WH_ERROR_BADARGS; obj = nfl_ObjectFindById(ctx, id); @@ -514,7 +514,8 @@ int wh_NvmFlashLog_GetMetadata(void* c, whNvmId id, whNvmMetadata* meta) return WH_ERROR_NOTFOUND; } - memcpy(meta, &obj->meta, sizeof(*meta)); + if (meta != NULL) + memcpy(meta, &obj->meta, sizeof(*meta)); return WH_ERROR_OK; } From 568cf10275c5b0cd48e1c8eb853be66aa10eba56 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 18:11:37 +0200 Subject: [PATCH 11/22] nvm_flash_log: read-back current partition if update fails --- src/wh_nvm_flash_log.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 08b5a70cd..46516d0cb 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -340,6 +340,23 @@ static int nfl_PartitionNewEpoch(whNvmFlashLogContext* ctx) return WH_ERROR_OK; } +static int nfl_PartitionNewEpochOrFallback(whNvmFlashLogContext* ctx) +{ + int ret; + + if (ctx == NULL) + return WH_ERROR_BADARGS; + ret = nfl_PartitionNewEpoch(ctx); + + if (ret != WH_ERROR_OK) { + /* swtiching to new partition failed for a reason, try to restore + * back active partition. */ + nfl_PartitionRead(ctx); + } + + return ret; +} + /* Initialization function */ int wh_NvmFlashLog_Init(void* c, const void* cf) { @@ -525,7 +542,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, whNvmFlashLogContext* ctx = (whNvmFlashLogContext*)c; whNvmFlashLogMetadata *obj, *old_obj; uint32_t available_space; - uint32_t ret; + int ret; uint32_t count; if (ctx == NULL || !ctx->is_initialized || meta == NULL || (data_len > 0 && data == NULL)) @@ -562,7 +579,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, ctx->directory.header.size += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(data_len); - return nfl_PartitionNewEpoch(ctx); + return nfl_PartitionNewEpochOrFallback(ctx); } /* Destroy objects by id list */ @@ -585,7 +602,7 @@ int wh_NvmFlashLog_DestroyObjects(void* c, whNvmId list_count, return ret; } - return nfl_PartitionNewEpoch(ctx); + return nfl_PartitionNewEpochOrFallback(ctx); } /* Read object data */ From 6763db9e9b9dd91403677a89a88b04cb4eac7b25 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 18:12:00 +0200 Subject: [PATCH 12/22] nvm_flash_log: add performance consideration in header --- src/wh_nvm_flash_log.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 46516d0cb..c837190ea 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -42,6 +42,31 @@ * Flash backend: * This layer relies on the same flash backend as wh_Flash, using the whFlashCb * interface. + * + * Limitations and performance considerations: + * + * The implementation favors simplicity over both speed and space. + * + * Regarding space: + * - An area of RAM as big as one partition is allocated to cache the + * partition. + * + * Regarding speed: + * - Each updates to the NVM (create, write, delete) requires copying all the + * objects from one partition of the flash to the other + erase operations. + * + * Possible future improvements: + * + * - cache only the metadata in RAM, access data on the FLASH as needed + * - use a true append log format to avoid copying all objects on each update + * + * Right now the implementation works well for read-heavy workloads with few + * updates. + * + * Alignment consideration: + * + * The implementation assure that writes are aligned to WRITE_GRANULARITY in FLASH memory space. + * The source data passed on the flash layer might not be aligned. */ #include "wolfhsm/wh_settings.h" From c90da7025103ad0900e386063de045fa62a79938 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 18:36:33 +0200 Subject: [PATCH 13/22] nvm_flash_log: verify program and erase --- src/wh_nvm_flash_log.c | 65 +++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index c837190ea..42c1d7cff 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -94,6 +94,45 @@ typedef struct { }; } whNvmFlashLogMetadata; +/* do a blank check + program + verify */ +static int nfl_FlashProgramHelper(whNvmFlashLogContext* ctx, uint32_t off, + const uint8_t* data, uint32_t len) +{ + int ret; + + if (ctx == NULL || (data == NULL && len > 0)) + return WH_ERROR_BADARGS; + + ret = ctx->flash_cb->BlankCheck(ctx->flash_ctx, off, len); + if (ret != 0) + return ret; + ret = ctx->flash_cb->Program(ctx->flash_ctx, off, len, data); + if (ret != 0) + return ret; + ret = ctx->flash_cb->Verify(ctx->flash_ctx, off, len, data); + if (ret != 0) + return ret; + return WH_ERROR_OK; +} + +/* do a erase + blank check */ +static int nfl_FlashEraseHelper(whNvmFlashLogContext* ctx, uint32_t off, + uint32_t len) +{ + int ret; + + if (ctx == NULL) + return WH_ERROR_BADARGS; + ret = ctx->flash_cb->Erase(ctx->flash_ctx, off, len); + if (ret != 0) + return ret; + ret = ctx->flash_cb->BlankCheck(ctx->flash_ctx, off, len); + if (ret != 0) + return ret; + + return WH_ERROR_OK; +} + static whNvmFlashLogMetadata* nfl_ObjNext(whNvmFlashLogContext* ctx, whNvmFlashLogMetadata* obj) { @@ -108,25 +147,19 @@ static whNvmFlashLogMetadata* nfl_ObjNext(whNvmFlashLogContext* ctx, static int nfl_PartitionErase(whNvmFlashLogContext* ctx, uint32_t partition) { - const whFlashCb* f_cb = ctx->flash_cb; - uint32_t off; - int ret; + uint32_t off; if (ctx == NULL || partition > 1) return WH_ERROR_BADARGS; off = partition * ctx->partition_size; - ret = f_cb->Erase(ctx->flash_ctx, off, ctx->partition_size); - if (ret != 0) - return ret; - return WH_ERROR_OK; + return nfl_FlashEraseHelper(ctx, off, ctx->partition_size); } static int nfl_PartitionWrite(whNvmFlashLogContext* ctx, uint32_t partition) { - const whFlashCb* f_cb = ctx->flash_cb; - uint32_t off; - int ret; + uint32_t off; + int ret; if (ctx == NULL || partition > 1) return WH_ERROR_BADARGS; @@ -137,9 +170,9 @@ static int nfl_PartitionWrite(whNvmFlashLogContext* ctx, uint32_t partition) return WH_ERROR_ABORTED; if (ctx->directory.header.size > 0) { - ret = f_cb->Program(ctx->flash_ctx, - off + sizeof(whNvmFlashLogPartitionHeader), - ctx->directory.header.size, ctx->directory.data); + ret = nfl_FlashProgramHelper( + ctx, off + sizeof(whNvmFlashLogPartitionHeader), + ctx->directory.data, ctx->directory.header.size); if (ret != 0) return ret; } @@ -162,9 +195,9 @@ static int nfl_PartitionCommit(whNvmFlashLogContext* ctx, uint32_t partition) sizeof(whNvmFlashLogPartitionHeader)); if (ret != 0) return ret; - ret = f_cb->Program(ctx->flash_ctx, off, - sizeof(whNvmFlashLogPartitionHeader), - (uint8_t*)&ctx->directory.header); + + ret = nfl_FlashProgramHelper(ctx, off, (uint8_t*)&ctx->directory.header, + sizeof(whNvmFlashLogPartitionHeader)); if (ret != 0) return ret; From 876b34736d41e9e4e0d4fce227cb1216be42e673 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 18:43:36 +0200 Subject: [PATCH 14/22] nvm_flash_log: fix from cppcheck --- src/wh_nvm_flash_log.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 42c1d7cff..e1d51a0e4 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -182,7 +182,7 @@ static int nfl_PartitionWrite(whNvmFlashLogContext* ctx, uint32_t partition) static int nfl_PartitionCommit(whNvmFlashLogContext* ctx, uint32_t partition) { - const whFlashCb* f_cb = ctx->flash_cb; + const whFlashCb* f_cb; uint32_t off; int ret; @@ -190,7 +190,7 @@ static int nfl_PartitionCommit(whNvmFlashLogContext* ctx, uint32_t partition) return WH_ERROR_BADARGS; off = partition * ctx->partition_size; - + f_cb = ctx->flash_cb; ret = f_cb->BlankCheck(ctx->flash_ctx, off, sizeof(whNvmFlashLogPartitionHeader)); if (ret != 0) @@ -207,7 +207,7 @@ static int nfl_PartitionCommit(whNvmFlashLogContext* ctx, uint32_t partition) static int nfl_PartitionChoose(whNvmFlashLogContext* ctx) { whNvmFlashLogPartitionHeader header0, header1; - const whFlashCb* f_cb = ctx->flash_cb; + const whFlashCb* f_cb; uint32_t part1_offset; int part0_blank, part1_blank; int ret; @@ -216,7 +216,7 @@ static int nfl_PartitionChoose(whNvmFlashLogContext* ctx) return WH_ERROR_BADARGS; part1_offset = ctx->partition_size; - + f_cb = ctx->flash_cb; ret = f_cb->BlankCheck(ctx->flash_ctx, 0, sizeof(header0)); if (ret != 0 && ret != WH_ERROR_NOTBLANK) { return ret; From c68809f6eab91351ab86d8af98ea9e37ff85f799 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 29 Sep 2025 18:48:21 +0200 Subject: [PATCH 15/22] widetree: fix clang-format error --- src/wh_nvm.c | 2 +- src/wh_nvm_flash.c | 52 +++++++++++++---------------------- src/wh_nvm_flash_log.c | 36 +++++++++++++----------- test/wh_test_cert.c | 2 +- test/wh_test_clientserver.c | 23 ++++++++++------ test/wh_test_common.c | 6 ++-- test/wh_test_common.h | 9 +++--- test/wh_test_crypto.c | 10 ++++--- test/wh_test_nvm_flash.c | 20 +++++++------- test/wh_test_server_img_mgr.c | 2 +- wolfhsm/wh_nvm.h | 6 ++-- wolfhsm/wh_nvm_flash.h | 4 +-- wolfhsm/wh_nvm_flash_log.h | 45 +++++++++++++++--------------- 13 files changed, 108 insertions(+), 109 deletions(-) diff --git a/src/wh_nvm.c b/src/wh_nvm.c index ae6c662d1..2ea7d7c82 100644 --- a/src/wh_nvm.c +++ b/src/wh_nvm.c @@ -192,7 +192,7 @@ int wh_Nvm_DestroyObjects(whNvmContext* context, whNvmId list_count, int wh_Nvm_Read(whNvmContext* context, whNvmId id, whNvmSize offset, - whNvmSize data_len, uint8_t* data) + whNvmSize data_len, uint8_t* data) { if ( (context == NULL) || (context->cb == NULL) ) { diff --git a/src/wh_nvm_flash.c b/src/wh_nvm_flash.c index aa7a95b86..3d83ab476 100644 --- a/src/wh_nvm_flash.c +++ b/src/wh_nvm_flash.c @@ -133,8 +133,8 @@ static int nfObject_Program(whNvmFlashContext* context, int partition, int object_index, uint32_t epoch, whNvmMetadata* meta, uint32_t start, const uint8_t* data); static int nfObject_ReadDataBytes(whNvmFlashContext* context, int partition, - int object_index, uint32_t byte_offset, uint32_t byte_count, - uint8_t* out_data); + int object_index, uint32_t byte_offset, + uint32_t byte_count, uint8_t* out_data); static int nfObject_Copy(whNvmFlashContext* context, int object_index, int partition, uint32_t *inout_next_object, uint32_t *inout_next_data); @@ -652,8 +652,8 @@ static int nfObject_Program(whNvmFlashContext* context, int partition, } static int nfObject_ReadDataBytes(whNvmFlashContext* context, int partition, - int object_index, - uint32_t byte_offset, uint32_t byte_count, uint8_t* out_data) + int object_index, uint32_t byte_offset, + uint32_t byte_count, uint8_t* out_data) { int start = 0; uint32_t startOffset = 0; @@ -676,18 +676,16 @@ static int nfObject_ReadDataBytes(whNvmFlashContext* context, int partition, } /* Ensure we don't read off the end of the active partition */ - if (WH_ERROR_OK != nfPartition_CheckDataRange(context, partition, - startOffset * WHFU_BYTES_PER_UNIT + byte_offset, - byte_count)) { + if (WH_ERROR_OK != nfPartition_CheckDataRange( + context, partition, + startOffset * WHFU_BYTES_PER_UNIT + byte_offset, + byte_count)) { return WH_ERROR_BADARGS; } return wh_FlashUnit_ReadBytes( - context->cb, - context->flash, - startOffset * WHFU_BYTES_PER_UNIT + byte_offset, - byte_count, - out_data); + context->cb, context->flash, + startOffset * WHFU_BYTES_PER_UNIT + byte_offset, byte_count, out_data); } static int nfObject_Copy(whNvmFlashContext* context, int object_index, @@ -728,13 +726,8 @@ static int nfObject_Copy(whNvmFlashContext* context, int object_index, } /* Read the data from the old object. */ - ret = nfObject_ReadDataBytes( - context, - context->active, - object_index, - data_offset, - this_len, - buffer); + ret = nfObject_ReadDataBytes(context, context->active, object_index, + data_offset, this_len, buffer); if (ret != 0) return ret; /* Write the data to the new object. */ @@ -1243,30 +1236,23 @@ int wh_NvmFlash_DestroyObjects(void* c, whNvmId list_count, } /* Read the data of the object starting at the byte offset */ -int wh_NvmFlash_Read(void* c, whNvmId id, whNvmSize offset, - whNvmSize data_len, uint8_t* data) +int wh_NvmFlash_Read(void* c, whNvmId id, whNvmSize offset, whNvmSize data_len, + uint8_t* data) { whNvmFlashContext* context = c; int ret = 0; - int object_index = -1; + int object_index = -1; if ( (context == NULL) || ((data_len > 0) && (data == NULL)) ){ return WH_ERROR_BADARGS; } - ret = nfMemDirectory_FindObjectIndexById( - &context->directory, - id, - &object_index); + ret = nfMemDirectory_FindObjectIndexById(&context->directory, id, + &object_index); if (ret == 0) { - ret = nfObject_ReadDataBytes( - context, - context->active, - object_index, - offset, - data_len, - data); + ret = nfObject_ReadDataBytes(context, context->active, object_index, + offset, data_len, data); } return ret; } diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index e1d51a0e4..2c18fa259 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -65,8 +65,9 @@ * * Alignment consideration: * - * The implementation assure that writes are aligned to WRITE_GRANULARITY in FLASH memory space. - * The source data passed on the flash layer might not be aligned. + * The implementation assure that writes are aligned to WRITE_GRANULARITY in + * FLASH memory space. The source data passed on the flash layer might not be + * aligned. */ #include "wolfhsm/wh_settings.h" @@ -138,8 +139,8 @@ static whNvmFlashLogMetadata* nfl_ObjNext(whNvmFlashLogContext* ctx, { if (obj == NULL || ctx == NULL) return NULL; - uint8_t* next = (uint8_t*)obj + sizeof(whNvmFlashLogMetadata) + - PAD_SIZE(obj->meta.len); + uint8_t* next = + (uint8_t*)obj + sizeof(whNvmFlashLogMetadata) + PAD_SIZE(obj->meta.len); if (next >= ctx->directory.data + ctx->directory.header.size) return NULL; return (whNvmFlashLogMetadata*)next; @@ -189,10 +190,10 @@ static int nfl_PartitionCommit(whNvmFlashLogContext* ctx, uint32_t partition) if (ctx == NULL || partition > 1) return WH_ERROR_BADARGS; - off = partition * ctx->partition_size; + off = partition * ctx->partition_size; f_cb = ctx->flash_cb; - ret = f_cb->BlankCheck(ctx->flash_ctx, off, - sizeof(whNvmFlashLogPartitionHeader)); + ret = f_cb->BlankCheck(ctx->flash_ctx, off, + sizeof(whNvmFlashLogPartitionHeader)); if (ret != 0) return ret; @@ -216,8 +217,8 @@ static int nfl_PartitionChoose(whNvmFlashLogContext* ctx) return WH_ERROR_BADARGS; part1_offset = ctx->partition_size; - f_cb = ctx->flash_cb; - ret = f_cb->BlankCheck(ctx->flash_ctx, 0, sizeof(header0)); + f_cb = ctx->flash_cb; + ret = f_cb->BlankCheck(ctx->flash_ctx, 0, sizeof(header0)); if (ret != 0 && ret != WH_ERROR_NOTBLANK) { return ret; } @@ -326,7 +327,8 @@ static int nfl_ObjectCount(whNvmFlashLogContext* ctx, } if ((uint8_t*)startObj < ctx->directory.data || - (uint8_t*)startObj >= ctx->directory.data + ctx->directory.header.size) { + (uint8_t*)startObj >= + ctx->directory.data + ctx->directory.header.size) { return 0; } @@ -351,10 +353,9 @@ static int nfl_PartitionRead(whNvmFlashLogContext* ctx) return WH_ERROR_BADARGS; f_cb = ctx->flash_cb; - off = ctx->active_partition * ctx->partition_size; + off = ctx->active_partition * ctx->partition_size; - ret = f_cb->Read(ctx->flash_ctx, off, - sizeof(whNvmFlashLogPartitionHeader), + ret = f_cb->Read(ctx->flash_ctx, off, sizeof(whNvmFlashLogPartitionHeader), (uint8_t*)&ctx->directory.header); if (ret != 0) return ret; @@ -519,7 +520,8 @@ int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, /* list all obects if start_id is WH_NVM_ID_INVALID */ if (start_id == WH_NVM_ID_INVALID) { next_obj = (whNvmFlashLogMetadata*)ctx->directory.data; - } else { + } + else { start_obj = nfl_ObjectFindById(ctx, start_id); if (start_obj != NULL && start_obj->meta.id != WH_NVM_ID_INVALID) next_obj = nfl_ObjNext(ctx, start_obj); @@ -603,7 +605,8 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, int ret; uint32_t count; - if (ctx == NULL || !ctx->is_initialized || meta == NULL || (data_len > 0 && data == NULL)) + if (ctx == NULL || !ctx->is_initialized || meta == NULL || + (data_len > 0 && data == NULL)) return WH_ERROR_BADARGS; count = nfl_ObjectCount(ctx, NULL); @@ -648,7 +651,8 @@ int wh_NvmFlashLog_DestroyObjects(void* c, whNvmId list_count, int i; int ret; - if (ctx == NULL || !ctx->is_initialized || (list_count > 0 && id_list == NULL)) + if (ctx == NULL || !ctx->is_initialized || + (list_count > 0 && id_list == NULL)) return WH_ERROR_BADARGS; if (list_count == 0) diff --git a/test/wh_test_cert.c b/test/wh_test_cert.c index de538642f..574666898 100644 --- a/test/wh_test_cert.c +++ b/test/wh_test_cert.c @@ -614,7 +614,7 @@ int whTest_CertRamSim(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whNvmUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; diff --git a/test/wh_test_clientserver.c b/test/wh_test_clientserver.c index 0ce1fa186..47ec064b6 100644 --- a/test/wh_test_clientserver.c +++ b/test/wh_test_clientserver.c @@ -779,7 +779,7 @@ int whTest_ClientServerSequential(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whNvmUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; @@ -1802,11 +1802,12 @@ static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whNvmUnion nvm_setup; whNvmConfig n_conf[1] = {0}; whNvmContext nvm[1] = {{0}}; - WH_TEST_RETURN_ON_FAIL(whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + WH_TEST_RETURN_ON_FAIL( + whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO /* Crypto context */ @@ -1886,9 +1887,9 @@ static int wh_ClientServer_PosixMemMapThreadTest(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whNvmUnion nvm_setup; whNvmConfig n_conf[1]; - whNvmContext nvm[1] = {{0}}; + whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); @@ -1936,7 +1937,8 @@ int whTest_ClientServer(void) #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) printf("Testing client/server sequential: mem + flash log...\n"); - WH_TEST_ASSERT(0 == whTest_ClientServerSequential(NVM_TEST_BACKEND_FLASH_LOG)); + WH_TEST_ASSERT(0 == + whTest_ClientServerSequential(NVM_TEST_BACKEND_FLASH_LOG)); #endif /* defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) */ #if defined(WOLFHSM_CFG_TEST_POSIX) @@ -1944,15 +1946,18 @@ int whTest_ClientServer(void) WH_TEST_ASSERT(0 == wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH)); printf("Testing client/server: (pthread) POSIX shared memory ...\n"); - WH_TEST_ASSERT(0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH)); + WH_TEST_ASSERT( + 0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) printf("Testing client/server: (pthread) mem + flash log...\n"); WH_TEST_ASSERT(0 == wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); - printf("Testing client/server: (pthread) POSIX shared memory + flash log...\n"); - WH_TEST_ASSERT(0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); + printf("Testing client/server: (pthread) POSIX shared memory + flash " + "log...\n"); + WH_TEST_ASSERT( + 0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); #endif /* defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) */ #endif /* defined(WOLFHSM_CFG_TEST_POSIX) */ diff --git a/test/wh_test_common.c b/test/wh_test_common.c index 1fb61d6eb..ff3efad0a 100644 --- a/test/wh_test_common.c +++ b/test/wh_test_common.c @@ -31,9 +31,11 @@ /** * Helper function to configure and select an NVM backend for testing. * - * @param type The type of NVM backend to configure (see NvmTestBackendType). + * @param type The type of NVM backend to configure (see + * NvmTestBackendType). * @param nvmSetup Pointer to a union of NVM backend setup structures (output). - * @param nvmCfg Pointer to the NVM configuration structure to populate (output). + * @param nvmCfg Pointer to the NVM configuration structure to populate + * (output). * @param fCfg Pointer to the RamSim flash configuration structure. * @param fCtx Pointer to the RamSim flash context structure. * @param fCb Pointer to the RamSim flash callback structure. diff --git a/test/wh_test_common.h b/test/wh_test_common.h index 6acecfaaf..03aaebde4 100644 --- a/test/wh_test_common.h +++ b/test/wh_test_common.h @@ -26,10 +26,10 @@ #include #endif -#include -#include -#include -#include +#include +#include +#include +#include #define WH_TEST_FAIL (-1) #define WH_TEST_SUCCESS (0) @@ -110,7 +110,6 @@ } while (0) - typedef enum { NVM_TEST_BACKEND_FLASH = 0, #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index 6142020e5..7f443f513 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -3672,9 +3672,9 @@ static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whNvmUnion nvm_setup; whNvmConfig n_conf[1]; - whNvmContext nvm[1] = {{0}}; + whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); @@ -3712,11 +3712,13 @@ static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) int whTest_Crypto(void) { printf("Testing crypto: (pthread) mem...\n"); - WH_TEST_RETURN_ON_FAIL(wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH)); + WH_TEST_RETURN_ON_FAIL( + wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) printf("Testing crypto: (pthread) mem (flash log)...\n"); - WH_TEST_RETURN_ON_FAIL(wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); + WH_TEST_RETURN_ON_FAIL( + wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); #endif return 0; diff --git a/test/wh_test_nvm_flash.c b/test/wh_test_nvm_flash.c index 1b50a8776..e8883098c 100644 --- a/test/wh_test_nvm_flash.c +++ b/test/wh_test_nvm_flash.c @@ -156,8 +156,7 @@ static void _ShowList(const whNvmCb* cb, void* context) #endif -static int addObjectWithReadBackCheck(const whNvmCb* cb, - void* context, +static int addObjectWithReadBackCheck(const whNvmCb* cb, void* context, whNvmMetadata* meta, whNvmSize data_len, const uint8_t* data) @@ -317,7 +316,7 @@ int whTest_Flash(const whFlashCb* fcb, void* fctx, const void* cfg) return 0; } -int whTest_NvmFlashCfg(void* cfg, void* context, const whNvmCb *cb) +int whTest_NvmFlashCfg(void* cfg, void* context, const whNvmCb* cb) { int ret = 0; @@ -425,7 +424,8 @@ int whTest_NvmFlashCfg(void* cfg, void* context, const whNvmCb *cb) goto cleanup; } - if ((ret = cb->Read(context, ids[i], 0, metaBuf.len, dataBuf)) != 0) { + if ((ret = cb->Read(context, ids[i], 0, metaBuf.len, dataBuf)) != + 0) { WH_ERROR_PRINT("Read after reclaim returned %d\n", ret); goto cleanup; } @@ -495,9 +495,10 @@ int whTest_NvmFlash_RamSim(void) .config = myHalFlashCfg, }; whNvmFlashContext nvmFlashCtx[1] = {0}; - const whNvmCb nvmFlashCb[1] = {WH_NVM_FLASH_CB}; + const whNvmCb nvmFlashCb[1] = {WH_NVM_FLASH_CB}; - WH_TEST_RETURN_ON_FAIL(whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb)); + WH_TEST_RETURN_ON_FAIL( + whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) whNvmFlashLogConfig myLogCfg = { @@ -506,12 +507,11 @@ int whTest_NvmFlash_RamSim(void) .flash_cfg = myHalFlashCfg, }; whNvmFlashLogContext nvmLogCtx[1] = {0}; - const whNvmCb nvmLogCb[1] = {WH_NVM_FLASH_LOG_CB}; + const whNvmCb nvmLogCb[1] = {WH_NVM_FLASH_LOG_CB}; WH_TEST_RETURN_ON_FAIL(whTest_NvmFlashCfg(&myLogCfg, nvmLogCtx, nvmLogCb)); #endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ return 0; - } static int @@ -644,7 +644,7 @@ int whTest_NvmFlash_PosixFileSim(void) .config = myHalFlashConfig, }; whNvmFlashContext nvmFlashCtx[1] = {0}; - const whNvmCb nvmFlashCb[1] = {WH_NVM_FLASH_CB}; + const whNvmCb nvmFlashCb[1] = {WH_NVM_FLASH_CB}; WH_TEST_ASSERT(0 == whTest_NvmFlashCfg(&myNvmCfg, nvmFlashCtx, nvmFlashCb)); @@ -662,7 +662,7 @@ int whTest_NvmFlash_PosixFileSim(void) .flash_cfg = myHalFlashConfig, }; whNvmFlashLogContext nvmLogCtx[1] = {0}; - const whNvmCb nvmLogCb[1] = {WH_NVM_FLASH_LOG_CB}; + const whNvmCb nvmLogCb[1] = {WH_NVM_FLASH_LOG_CB}; WH_TEST_RETURN_ON_FAIL(whTest_NvmFlashCfg(&myLogCfg, nvmLogCtx, nvmLogCb)); #endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ diff --git a/test/wh_test_server_img_mgr.c b/test/wh_test_server_img_mgr.c index 83b2b5d6b..c28a11b70 100644 --- a/test/wh_test_server_img_mgr.c +++ b/test/wh_test_server_img_mgr.c @@ -1229,7 +1229,7 @@ int whTest_ServerImgMgr(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whNvmUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; diff --git a/wolfhsm/wh_nvm.h b/wolfhsm/wh_nvm.h index f52e3e99b..a0c8cefd1 100644 --- a/wolfhsm/wh_nvm.h +++ b/wolfhsm/wh_nvm.h @@ -82,8 +82,8 @@ typedef struct { const whNvmId* id_list); /* Read the data of the object starting at the byte offset */ - int (*Read)(void* context, whNvmId id, whNvmSize offset, - whNvmSize data_len, uint8_t* data); + int (*Read)(void* context, whNvmId id, whNvmSize offset, whNvmSize data_len, + uint8_t* data); } whNvmCb; @@ -126,6 +126,6 @@ int wh_Nvm_DestroyObjects(whNvmContext* context, whNvmId list_count, const whNvmId* id_list); int wh_Nvm_Read(whNvmContext* context, whNvmId id, whNvmSize offset, - whNvmSize data_len, uint8_t* data); + whNvmSize data_len, uint8_t* data); #endif /* !WOLFHSM_WH_NVM_H_ */ diff --git a/wolfhsm/wh_nvm_flash.h b/wolfhsm/wh_nvm_flash.h index 622f5c484..b928a59c7 100644 --- a/wolfhsm/wh_nvm_flash.h +++ b/wolfhsm/wh_nvm_flash.h @@ -100,8 +100,8 @@ int wh_NvmFlash_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, const uint8_t* data); int wh_NvmFlash_DestroyObjects(void* c, whNvmId list_count, const whNvmId* id_list); -int wh_NvmFlash_Read(void* c, whNvmId id, whNvmSize offset, - whNvmSize data_len, uint8_t* data); +int wh_NvmFlash_Read(void* c, whNvmId id, whNvmSize offset, whNvmSize data_len, + uint8_t* data); #define WH_NVM_FLASH_CB \ { \ diff --git a/wolfhsm/wh_nvm_flash_log.h b/wolfhsm/wh_nvm_flash_log.h index ef378ca04..42d879623 100644 --- a/wolfhsm/wh_nvm_flash_log.h +++ b/wolfhsm/wh_nvm_flash_log.h @@ -10,7 +10,8 @@ * * 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. + * 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 . @@ -68,31 +69,31 @@ typedef struct { int wh_NvmFlashLog_Init(void* c, const void* cf); int wh_NvmFlashLog_Cleanup(void* c); -int wh_NvmFlashLog_List(void* c, - whNvmAccess access, whNvmFlags flags, whNvmId start_id, - whNvmId *out_avail_objects, whNvmId *out_id); -int wh_NvmFlashLog_GetAvailable(void* c, - uint32_t *out_avail_size, whNvmId *out_avail_objects, - uint32_t *out_reclaim_size, whNvmId *out_reclaim_objects); +int wh_NvmFlashLog_List(void* c, whNvmAccess access, whNvmFlags flags, + whNvmId start_id, whNvmId* out_avail_objects, + whNvmId* out_id); +int wh_NvmFlashLog_GetAvailable(void* c, uint32_t* out_avail_size, + whNvmId* out_avail_objects, + uint32_t* out_reclaim_size, + whNvmId* out_reclaim_objects); int wh_NvmFlashLog_GetMetadata(void* c, whNvmId id, whNvmMetadata* meta); -int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, - whNvmSize data_len, const uint8_t* data); +int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, + const uint8_t* data); int wh_NvmFlashLog_DestroyObjects(void* c, whNvmId list_count, - const whNvmId* id_list); + const whNvmId* id_list); int wh_NvmFlashLog_Read(void* c, whNvmId id, whNvmSize offset, - whNvmSize data_len, uint8_t* data); + whNvmSize data_len, uint8_t* data); -#define WH_NVM_FLASH_LOG_CB \ -{ \ - .Init = wh_NvmFlashLog_Init, \ - .Cleanup = wh_NvmFlashLog_Cleanup, \ - .List = wh_NvmFlashLog_List, \ - .GetAvailable = wh_NvmFlashLog_GetAvailable, \ - .GetMetadata = wh_NvmFlashLog_GetMetadata, \ - .AddObject = wh_NvmFlashLog_AddObject, \ - .DestroyObjects = wh_NvmFlashLog_DestroyObjects, \ - .Read = wh_NvmFlashLog_Read, \ -} +#define WH_NVM_FLASH_LOG_CB \ + { \ + .Init = wh_NvmFlashLog_Init, .Cleanup = wh_NvmFlashLog_Cleanup, \ + .List = wh_NvmFlashLog_List, \ + .GetAvailable = wh_NvmFlashLog_GetAvailable, \ + .GetMetadata = wh_NvmFlashLog_GetMetadata, \ + .AddObject = wh_NvmFlashLog_AddObject, \ + .DestroyObjects = wh_NvmFlashLog_DestroyObjects, \ + .Read = wh_NvmFlashLog_Read, \ + } #endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ From a92ecaa312f9b7a6b6ffb1103acfc0bc80ddc8ec Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 13 Oct 2025 10:20:38 +0200 Subject: [PATCH 16/22] nvm_flash_log: move configuration define in test/config/wolfhsm_cfg.h --- test/Makefile | 2 -- test/config/wolfhsm_cfg.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Makefile b/test/Makefile index 8ce179392..ad6393e34 100644 --- a/test/Makefile +++ b/test/Makefile @@ -123,8 +123,6 @@ else DEF += -DWOLFHSM_CFG_IS_TEST_SERVER endif -# Test NVM Flash Log implementation -DEF += -DWOLFHSM_CFG_SERVER_NVM_FLASH_LOG ## Source files # Assembly source files diff --git a/test/config/wolfhsm_cfg.h b/test/config/wolfhsm_cfg.h index cf9068221..4a0762140 100644 --- a/test/config/wolfhsm_cfg.h +++ b/test/config/wolfhsm_cfg.h @@ -56,4 +56,6 @@ #define WOLFHSM_CFG_CANCEL_API #endif +#define WOLFHSM_CFG_SERVER_NVM_FLASH_LOG + #endif /* WOLFHSM_CFG_H_ */ From 2dc6af56ab0c3a15ea3ac511878e047e13c03833 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 13 Oct 2025 10:39:46 +0200 Subject: [PATCH 17/22] nvm_flash_log: better naming for test structure and functions --- test/wh_test_cert.c | 6 +++--- test/wh_test_cert.h | 4 ++-- test/wh_test_clientserver.c | 18 +++++++++--------- test/wh_test_common.c | 7 ++++--- test/wh_test_common.h | 11 ++++++----- test/wh_test_crypto.c | 6 +++--- test/wh_test_nvm_flash.c | 3 +++ test/wh_test_server_img_mgr.c | 6 +++--- test/wh_test_server_img_mgr.h | 2 +- 9 files changed, 34 insertions(+), 29 deletions(-) diff --git a/test/wh_test_cert.c b/test/wh_test_cert.c index 574666898..9710d7958 100644 --- a/test/wh_test_cert.c +++ b/test/wh_test_cert.c @@ -578,7 +578,7 @@ static int whTest_CertNonExportable(whClientContext* client) #endif /* WOLFHSM_CFG_ENABLE_CLIENT */ #ifdef WOLFHSM_CFG_ENABLE_SERVER -int whTest_CertRamSim(NvmTestBackendType nvmType) +int whTest_CertRamSim(whTestNvmBackendType nvmType) { int rc = WH_ERROR_OK; const uint32_t BUFFER_SIZE = 1024; @@ -614,12 +614,12 @@ int whTest_CertRamSim(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whTestNvmBackendUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( - whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + whTest_NvmCfgBackend(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO whServerCryptoContext crypto[1] = {{ diff --git a/test/wh_test_cert.h b/test/wh_test_cert.h index 36269dc80..d5d002eb6 100644 --- a/test/wh_test_cert.h +++ b/test/wh_test_cert.h @@ -29,7 +29,7 @@ #include "wh_test_common.h" /* Run certificate configuration tests */ -int whTest_CertRamSim(NvmTestBackendType nvmType); +int whTest_CertRamSim(whTestNvmBackendType nvmType); int whTest_CertServerCfg(whServerConfig* serverCfg); int whTest_CertClient(whClientContext* client); #if defined(WOLFHSM_CFG_DMA) @@ -43,4 +43,4 @@ int whTest_CertClientAcertDma_ClientServerTestInternal(whClientContext* client); #endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER_ACERT */ -#endif /* !WOLFHSM_WH_TEST_CERT_H_ */ \ No newline at end of file +#endif /* !WOLFHSM_WH_TEST_CERT_H_ */ diff --git a/test/wh_test_clientserver.c b/test/wh_test_clientserver.c index 47ec064b6..6d0a4ff52 100644 --- a/test/wh_test_clientserver.c +++ b/test/wh_test_clientserver.c @@ -726,7 +726,7 @@ static int _testOutOfBoundsNvmReads(whClientContext* client, return WH_ERROR_OK; } -int whTest_ClientServerSequential(NvmTestBackendType nvmType) +int whTest_ClientServerSequential(whTestNvmBackendType nvmType) { int ret = 0; @@ -779,12 +779,12 @@ int whTest_ClientServerSequential(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whTestNvmBackendUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( - whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + whTest_NvmCfgBackend(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO whServerCryptoContext crypto[1] = {{ @@ -1757,7 +1757,7 @@ static void _whClientServerThreadTest(whClientConfig* c_conf, } } -static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) +static int wh_ClientServer_MemThreadTest(whTestNvmBackendType nvmType) { uint8_t req[BUFFER_SIZE] = {0}; uint8_t resp[BUFFER_SIZE] = {0}; @@ -1802,12 +1802,12 @@ static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whTestNvmBackendUnion nvm_setup; whNvmConfig n_conf[1] = {0}; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( - whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + whTest_NvmCfgBackend(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO /* Crypto context */ @@ -1845,7 +1845,7 @@ static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) } -static int wh_ClientServer_PosixMemMapThreadTest(NvmTestBackendType nvmType) +static int wh_ClientServer_PosixMemMapThreadTest(whTestNvmBackendType nvmType) { posixTransportShmConfig tmcf[1] = {{ .name = "/wh_test_clientserver_shm", @@ -1887,12 +1887,12 @@ static int wh_ClientServer_PosixMemMapThreadTest(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whTestNvmBackendUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( - whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + whTest_NvmCfgBackend(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); #ifndef WOLFHSM_CFG_NO_CRYPTO /* Crypto context */ diff --git a/test/wh_test_common.c b/test/wh_test_common.c index ff3efad0a..ee585184d 100644 --- a/test/wh_test_common.c +++ b/test/wh_test_common.c @@ -42,9 +42,10 @@ * * @return WH_ERROR_OK on success, or WH_ERROR_BADARGS on failure. */ -int whTest_NvmSetup(NvmTestBackendType type, whNvmUnion* nvmSetup, - whNvmConfig* nvmCfg, whFlashRamsimCfg* fCfg, - whFlashRamsimCtx* fCtx, const whFlashCb* fCb) +int whTest_NvmCfgBackend(whTestNvmBackendType type, + whTestNvmBackendUnion* nvmSetup, whNvmConfig* nvmCfg, + whFlashRamsimCfg* fCfg, whFlashRamsimCtx* fCtx, + const whFlashCb* fCb) { WH_TEST_ASSERT(nvmSetup != NULL); diff --git a/test/wh_test_common.h b/test/wh_test_common.h index 03aaebde4..4391eef52 100644 --- a/test/wh_test_common.h +++ b/test/wh_test_common.h @@ -116,7 +116,7 @@ typedef enum { NVM_TEST_BACKEND_FLASH_LOG, #endif NVM_TEST_BACKEND_COUNT -} NvmTestBackendType; +} whTestNvmBackendType; /* union helper struct to be able to test more than one NVM implementation */ typedef struct { @@ -132,9 +132,10 @@ typedef struct { }; #endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ }; -} whNvmUnion; +} whTestNvmBackendUnion; -int whTest_NvmSetup(NvmTestBackendType type, whNvmUnion* nvmSetup, - whNvmConfig* nvmCfg, whFlashRamsimCfg* fCfg, - whFlashRamsimCtx* fCtx, const whFlashCb* fCb); +int whTest_NvmCfgBackend(whTestNvmBackendType type, + whTestNvmBackendUnion* nvmSetup, whNvmConfig* nvmCfg, + whFlashRamsimCfg* fCfg, whFlashRamsimCtx* fCtx, + const whFlashCb* fCb); #endif /* WH_TEST_COMMON_H_ */ diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index 7f443f513..8203389f5 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -3615,7 +3615,7 @@ static void _whClientServerThreadTest(whClientConfig* c_conf, } -static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) +static int wh_ClientServer_MemThreadTest(whTestNvmBackendType nvmType) { uint8_t req[BUFFER_SIZE] = {0}; uint8_t resp[BUFFER_SIZE] = {0}; @@ -3672,12 +3672,12 @@ static int wh_ClientServer_MemThreadTest(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whTestNvmBackendUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( - whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + whTest_NvmCfgBackend(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); /* Crypto context */ whServerCryptoContext crypto[1] = {{ diff --git a/test/wh_test_nvm_flash.c b/test/wh_test_nvm_flash.c index e8883098c..7ddc41845 100644 --- a/test/wh_test_nvm_flash.c +++ b/test/wh_test_nvm_flash.c @@ -655,7 +655,9 @@ int whTest_NvmFlash_PosixFileSim(void) WH_TEST_ASSERT(myHalFlashConfig[0].partition_size >= WH_NVM_FLASH_LOG_PARTITION_SIZE); myHalFlashConfig[0].partition_size = WH_NVM_FLASH_LOG_PARTITION_SIZE; + memset(myHalFlashContext, 0, sizeof(myHalFlashContext)); + whNvmFlashLogConfig myLogCfg = { .flash_cb = myCb, .flash_ctx = myHalFlashContext, @@ -663,6 +665,7 @@ int whTest_NvmFlash_PosixFileSim(void) }; whNvmFlashLogContext nvmLogCtx[1] = {0}; const whNvmCb nvmLogCb[1] = {WH_NVM_FLASH_LOG_CB}; + WH_TEST_RETURN_ON_FAIL(whTest_NvmFlashCfg(&myLogCfg, nvmLogCtx, nvmLogCb)); #endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ diff --git a/test/wh_test_server_img_mgr.c b/test/wh_test_server_img_mgr.c index c28a11b70..f4bf68d54 100644 --- a/test/wh_test_server_img_mgr.c +++ b/test/wh_test_server_img_mgr.c @@ -1192,7 +1192,7 @@ static int whTest_ServerImgMgrServerCfgRsa2048(whServerConfig* serverCfg) } #endif /* !NO_RSA */ -int whTest_ServerImgMgr(NvmTestBackendType nvmType) +int whTest_ServerImgMgr(whTestNvmBackendType nvmType) { int rc = 0; const uint32_t BUFFER_SIZE = 1024; @@ -1229,12 +1229,12 @@ int whTest_ServerImgMgr(NvmTestBackendType nvmType) }}; const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; - whNvmUnion nvm_setup; + whTestNvmBackendUnion nvm_setup; whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( - whTest_NvmSetup(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); + whTest_NvmCfgBackend(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); whServerCryptoContext crypto[1] = {{ .devId = INVALID_DEVID, diff --git a/test/wh_test_server_img_mgr.h b/test/wh_test_server_img_mgr.h index e748d9e35..1ba8d41eb 100644 --- a/test/wh_test_server_img_mgr.h +++ b/test/wh_test_server_img_mgr.h @@ -22,6 +22,6 @@ #include "wh_test_common.h" -int whTest_ServerImgMgr(NvmTestBackendType nvmType); +int whTest_ServerImgMgr(whTestNvmBackendType nvmType); #endif /* WH_TEST_SERVER_IMG_MGR_H */ From 419c2cb65a1aebb40f4dedb654dfcfd3235a14be Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 13 Oct 2025 11:19:49 +0200 Subject: [PATCH 18/22] nvm_flash_log: erase inactive partition on partition commit --- src/wh_nvm_flash_log.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 2c18fa259..88bbad452 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -413,6 +413,9 @@ static int nfl_PartitionNewEpochOrFallback(whNvmFlashLogContext* ctx) nfl_PartitionRead(ctx); } + /* erase in-active partition, this ensure objects are truly destroyed */ + nfl_PartitionErase(ctx, ctx->active_partition == 0 ? 1 : 0); + return ret; } From 948b3d9beebecf5fcc5e1f7e3ab45cc5b280ca9e Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 13 Oct 2025 11:20:08 +0200 Subject: [PATCH 19/22] nvm_flash_log: fix object limit in addObject --- src/wh_nvm_flash_log.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index 88bbad452..b47023b36 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -613,9 +613,6 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, return WH_ERROR_BADARGS; count = nfl_ObjectCount(ctx, NULL); - if (count >= WOLFHSM_CFG_NVM_OBJECT_COUNT) - return WH_ERROR_NOSPACE; - available_space = ctx->partition_size - sizeof(whNvmFlashLogPartitionHeader) - ctx->directory.header.size; @@ -624,11 +621,15 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, if (old_obj != NULL) { available_space += sizeof(whNvmFlashLogMetadata) + PAD_SIZE(old_obj->meta.len); + count -= 1; } if (PAD_SIZE(data_len) + sizeof(whNvmFlashLogMetadata) > available_space) return WH_ERROR_NOSPACE; + if (count >= WOLFHSM_CFG_NVM_OBJECT_COUNT) + return WH_ERROR_NOSPACE; + if (old_obj) { ret = nfl_ObjectDestroy(ctx, meta->id); if (ret != WH_ERROR_OK) From 1ff33d37e2af8d42a54c95008bbcce53ff55d483 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 13 Oct 2025 11:23:44 +0200 Subject: [PATCH 20/22] git-clang-format fixes --- src/wh_nvm_flash_log.c | 2 +- test/wh_test_cert.c | 2 +- test/wh_test_clientserver.c | 8 ++++---- test/wh_test_crypto.c | 2 +- test/wh_test_server_img_mgr.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wh_nvm_flash_log.c b/src/wh_nvm_flash_log.c index b47023b36..e0ca8d489 100644 --- a/src/wh_nvm_flash_log.c +++ b/src/wh_nvm_flash_log.c @@ -612,7 +612,7 @@ int wh_NvmFlashLog_AddObject(void* c, whNvmMetadata* meta, whNvmSize data_len, (data_len > 0 && data == NULL)) return WH_ERROR_BADARGS; - count = nfl_ObjectCount(ctx, NULL); + count = nfl_ObjectCount(ctx, NULL); available_space = ctx->partition_size - sizeof(whNvmFlashLogPartitionHeader) - ctx->directory.header.size; diff --git a/test/wh_test_cert.c b/test/wh_test_cert.c index 9710d7958..b48cda9f9 100644 --- a/test/wh_test_cert.c +++ b/test/wh_test_cert.c @@ -615,7 +615,7 @@ int whTest_CertRamSim(whTestNvmBackendType nvmType) const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; whTestNvmBackendUnion nvm_setup; - whNvmConfig n_conf[1]; + whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( diff --git a/test/wh_test_clientserver.c b/test/wh_test_clientserver.c index 6d0a4ff52..38415179d 100644 --- a/test/wh_test_clientserver.c +++ b/test/wh_test_clientserver.c @@ -780,7 +780,7 @@ int whTest_ClientServerSequential(whTestNvmBackendType nvmType) const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; whTestNvmBackendUnion nvm_setup; - whNvmConfig n_conf[1]; + whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( @@ -1803,8 +1803,8 @@ static int wh_ClientServer_MemThreadTest(whTestNvmBackendType nvmType) const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; whTestNvmBackendUnion nvm_setup; - whNvmConfig n_conf[1] = {0}; - whNvmContext nvm[1] = {{0}}; + whNvmConfig n_conf[1] = {0}; + whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( whTest_NvmCfgBackend(nvmType, &nvm_setup, n_conf, fc_conf, fc, fcb)); @@ -1888,7 +1888,7 @@ static int wh_ClientServer_PosixMemMapThreadTest(whTestNvmBackendType nvmType) const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; whTestNvmBackendUnion nvm_setup; - whNvmConfig n_conf[1]; + whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index 8203389f5..f9d57f404 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -3673,7 +3673,7 @@ static int wh_ClientServer_MemThreadTest(whTestNvmBackendType nvmType) const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; whTestNvmBackendUnion nvm_setup; - whNvmConfig n_conf[1]; + whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( diff --git a/test/wh_test_server_img_mgr.c b/test/wh_test_server_img_mgr.c index f4bf68d54..ec2cfd7ca 100644 --- a/test/wh_test_server_img_mgr.c +++ b/test/wh_test_server_img_mgr.c @@ -1230,7 +1230,7 @@ int whTest_ServerImgMgr(whTestNvmBackendType nvmType) const whFlashCb fcb[1] = {WH_FLASH_RAMSIM_CB}; whTestNvmBackendUnion nvm_setup; - whNvmConfig n_conf[1]; + whNvmConfig n_conf[1]; whNvmContext nvm[1] = {{0}}; WH_TEST_RETURN_ON_FAIL( From e544f3cdb3894dd8f75cf0076a033c5f61d239cd Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Wed, 15 Oct 2025 19:08:11 +0200 Subject: [PATCH 21/22] nvm_flash_log: test: remove useless assert --- test/wh_test_common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/test/wh_test_common.c b/test/wh_test_common.c index ee585184d..9d1c19479 100644 --- a/test/wh_test_common.c +++ b/test/wh_test_common.c @@ -85,7 +85,6 @@ int whTest_NvmCfgBackend(whTestNvmBackendType type, break; default: - WH_TEST_ASSERT(0); return WH_ERROR_BADARGS; } From fb860465b3e510bff8718a2c5610cd3c8ee7f3ec Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Wed, 15 Oct 2025 19:08:41 +0200 Subject: [PATCH 22/22] nvm_flash_log: test: rename nvm backend enums --- test/wh_test.c | 8 ++++---- test/wh_test_clientserver.c | 12 ++++++------ test/wh_test_common.c | 4 ++-- test/wh_test_common.h | 6 +++--- test/wh_test_crypto.c | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/test/wh_test.c b/test/wh_test.c index c68a63cab..31124a6e4 100644 --- a/test/wh_test.c +++ b/test/wh_test.c @@ -66,10 +66,10 @@ int whTest_Unit(void) WH_TEST_ASSERT(0 == whTest_Flash_RamSim()); WH_TEST_ASSERT(0 == whTest_NvmFlash()); #if defined(WOLFHSM_CFG_CERTIFICATE_MANAGER) && !defined(WOLFHSM_CFG_NO_CRYPTO) - WH_TEST_ASSERT(0 == whTest_CertRamSim(NVM_TEST_BACKEND_FLASH)); + WH_TEST_ASSERT(0 == whTest_CertRamSim(WH_NVM_TEST_BACKEND_FLASH)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) - WH_TEST_ASSERT(0 == whTest_CertRamSim(NVM_TEST_BACKEND_FLASH_LOG)); + WH_TEST_ASSERT(0 == whTest_CertRamSim(WH_NVM_TEST_BACKEND_FLASH_LOG)); #endif /* WOLFHSM_CFG_SERVER_NVM_FLASH_LOG */ #endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER && !WOLFHSM_CFG_NO_CRYPTO */ @@ -85,10 +85,10 @@ int whTest_Unit(void) #if defined(WOLFHSM_CFG_SERVER_IMG_MGR) && !defined(WOLFHSM_CFG_NO_CRYPTO) /* Image Manager Tests */ - WH_TEST_ASSERT(0 == whTest_ServerImgMgr(NVM_TEST_BACKEND_FLASH)); + WH_TEST_ASSERT(0 == whTest_ServerImgMgr(WH_NVM_TEST_BACKEND_FLASH)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) - WH_TEST_ASSERT(0 == whTest_ServerImgMgr(NVM_TEST_BACKEND_FLASH_LOG)); + WH_TEST_ASSERT(0 == whTest_ServerImgMgr(WH_NVM_TEST_BACKEND_FLASH_LOG)); #endif #endif /* WOLFHSM_CFG_SERVER_IMG_MGR && !WOLFHSM_CFG_NO_CRYPTO */ diff --git a/test/wh_test_clientserver.c b/test/wh_test_clientserver.c index 38415179d..c91d67581 100644 --- a/test/wh_test_clientserver.c +++ b/test/wh_test_clientserver.c @@ -1933,31 +1933,31 @@ static int wh_ClientServer_PosixMemMapThreadTest(whTestNvmBackendType nvmType) int whTest_ClientServer(void) { printf("Testing client/server sequential: mem...\n"); - WH_TEST_ASSERT(0 == whTest_ClientServerSequential(NVM_TEST_BACKEND_FLASH)); + WH_TEST_ASSERT(0 == whTest_ClientServerSequential(WH_NVM_TEST_BACKEND_FLASH)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) printf("Testing client/server sequential: mem + flash log...\n"); WH_TEST_ASSERT(0 == - whTest_ClientServerSequential(NVM_TEST_BACKEND_FLASH_LOG)); + whTest_ClientServerSequential(WH_NVM_TEST_BACKEND_FLASH_LOG)); #endif /* defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) */ #if defined(WOLFHSM_CFG_TEST_POSIX) printf("Testing client/server: (pthread) mem...\n"); - WH_TEST_ASSERT(0 == wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH)); + WH_TEST_ASSERT(0 == wh_ClientServer_MemThreadTest(WH_NVM_TEST_BACKEND_FLASH)); printf("Testing client/server: (pthread) POSIX shared memory ...\n"); WH_TEST_ASSERT( - 0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH)); + 0 == wh_ClientServer_PosixMemMapThreadTest(WH_NVM_TEST_BACKEND_FLASH)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) printf("Testing client/server: (pthread) mem + flash log...\n"); WH_TEST_ASSERT(0 == - wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); + wh_ClientServer_MemThreadTest(WH_NVM_TEST_BACKEND_FLASH_LOG)); printf("Testing client/server: (pthread) POSIX shared memory + flash " "log...\n"); WH_TEST_ASSERT( - 0 == wh_ClientServer_PosixMemMapThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); + 0 == wh_ClientServer_PosixMemMapThreadTest(WH_NVM_TEST_BACKEND_FLASH_LOG)); #endif /* defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) */ #endif /* defined(WOLFHSM_CFG_TEST_POSIX) */ diff --git a/test/wh_test_common.c b/test/wh_test_common.c index 9d1c19479..2cac0aebb 100644 --- a/test/wh_test_common.c +++ b/test/wh_test_common.c @@ -54,7 +54,7 @@ int whTest_NvmCfgBackend(whTestNvmBackendType type, switch (type) { #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) - case NVM_TEST_BACKEND_FLASH_LOG: + case WH_NVM_TEST_BACKEND_FLASH_LOG: nvmSetup->nvmFlashLogCfg.flash_cb = fCb; /* restrict simulated flash partition to nvm_flash_log_partition */ WH_TEST_ASSERT(fCfg->size >= WH_NVM_FLASH_LOG_PARTITION_SIZE * 2); @@ -70,7 +70,7 @@ int whTest_NvmCfgBackend(whTestNvmBackendType type, nvmCfg->config = &nvmSetup->nvmFlashLogCfg; break; #endif - case NVM_TEST_BACKEND_FLASH: + case WH_NVM_TEST_BACKEND_FLASH: /* NVM Flash Configuration using RamSim HAL Flash */ nvmSetup->nvmFlashCfg.cb = fCb; nvmSetup->nvmFlashCfg.context = fCtx; diff --git a/test/wh_test_common.h b/test/wh_test_common.h index 4391eef52..c1bc5a08f 100644 --- a/test/wh_test_common.h +++ b/test/wh_test_common.h @@ -111,11 +111,11 @@ typedef enum { - NVM_TEST_BACKEND_FLASH = 0, + WH_NVM_TEST_BACKEND_FLASH = 0, #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) - NVM_TEST_BACKEND_FLASH_LOG, + WH_NVM_TEST_BACKEND_FLASH_LOG, #endif - NVM_TEST_BACKEND_COUNT + WH_NVM_TEST_BACKEND_COUNT } whTestNvmBackendType; /* union helper struct to be able to test more than one NVM implementation */ diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index f9d57f404..f6556046e 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -3713,12 +3713,12 @@ int whTest_Crypto(void) { printf("Testing crypto: (pthread) mem...\n"); WH_TEST_RETURN_ON_FAIL( - wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH)); + wh_ClientServer_MemThreadTest(WH_NVM_TEST_BACKEND_FLASH)); #if defined(WOLFHSM_CFG_SERVER_NVM_FLASH_LOG) printf("Testing crypto: (pthread) mem (flash log)...\n"); WH_TEST_RETURN_ON_FAIL( - wh_ClientServer_MemThreadTest(NVM_TEST_BACKEND_FLASH_LOG)); + wh_ClientServer_MemThreadTest(WH_NVM_TEST_BACKEND_FLASH_LOG)); #endif return 0;