diff --git a/.github/workflows/build-and-run-examples.yml b/.github/workflows/build-and-run-examples.yml index 80451dda..2b59d66a 100644 --- a/.github/workflows/build-and-run-examples.yml +++ b/.github/workflows/build-and-run-examples.yml @@ -8,8 +8,11 @@ on: jobs: build: - + strategy: + matrix: + transport: [ 'tcp', 'shm', 'dma' ] runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@master @@ -22,28 +25,38 @@ jobs: path: wolfssl # Build examples - - name: Build POSIX TCP server - run: cd examples/posix/tcp/wh_server_tcp && make -j WOLFSSL_DIR=../../../../wolfssl - - name: Build POSIX TCP client - run: cd examples/posix/tcp/wh_client_tcp && make -j WOLFSSL_DIR=../../../../wolfssl + - name: Build POSIX server + run: | + if [ "${{ matrix.transport }}" = "dma" ]; then + cd examples/posix/wh_posix_server && DMA=1 make -j WOLFSSL_DIR=../../../wolfssl + else + cd examples/posix/wh_posix_server && make -j WOLFSSL_DIR=../../../wolfssl + fi + - name: Build POSIX client + run: | + if [ "${{ matrix.transport }}" = "dma" ]; then + cd examples/posix/wh_posix_client && DMA=1 make -j WOLFSSL_DIR=../../../wolfssl + else + cd examples/posix/wh_posix_client && make -j WOLFSSL_DIR=../../../wolfssl + fi # Start the server in the background - - name: Run POSIX TCP server + - name: Run POSIX server run: | - cd examples/posix/tcp/wh_server_tcp - ./Build/wh_server_tcp.elf & - TCP_SERVER_PID=$! - echo "TCP_SERVER_PID=$TCP_SERVER_PID" >> $GITHUB_ENV + cd examples/posix/wh_posix_server + ./Build/wh_posix_server.elf --type ${{ matrix.transport }} & + POSIX_SERVER_PID=$! + echo "POSIX_SERVER_PID=$POSIX_SERVER_PID" >> $GITHUB_ENV # Run the client that connects to the server - - name: Run POSIX TCP client + - name: Run POSIX client run: | - cd examples/posix/tcp/wh_client_tcp - ./Build/wh_client_tcp.elf + cd examples/posix/wh_posix_client + ./Build/wh_posix_client.elf --type ${{ matrix.transport }} # Optional: Kill the server process if it doesn't exit on its own - - name: Cleanup POSIX TCP server + - name: Cleanup POSIX server if: always() - run: kill $TCP_SERVER_PID || true + run: kill $POSIX_SERVER_PID || true diff --git a/.github/workflows/build-and-test-clientonly.yml b/.github/workflows/build-and-test-clientonly.yml index c56821b3..d4647c21 100644 --- a/.github/workflows/build-and-test-clientonly.yml +++ b/.github/workflows/build-and-test-clientonly.yml @@ -28,18 +28,18 @@ jobs: with: repository: wolfssl/wolfssl path: wolfssl - + # Build example server - - name: Build POSIX TCP server + - name: Build POSIX server run: | - cd examples/posix/tcp/wh_server_tcp - make -j SHE=1 WOLFSSL_DIR=../../../../wolfssl + cd examples/posix/wh_posix_server + make -j SHE=1 WOLFSSL_DIR=../../../wolfssl # Start the server in the background - - name: Run POSIX TCP server + - name: Run POSIX server run: | - cd examples/posix/tcp/wh_server_tcp - ./Build/wh_server_tcp.elf & + cd examples/posix/wh_posix_server + ./Build/wh_posix_server.elf & TCP_SERVER_PID=$! echo "TCP_SERVER_PID=$TCP_SERVER_PID" >> $GITHUB_ENV @@ -54,4 +54,4 @@ jobs: - name: Cleanup POSIX TCP server if: always() run: kill $TCP_SERVER_PID || true - \ No newline at end of file + diff --git a/benchmark/Makefile b/benchmark/Makefile index 03c6d758..48ba9c32 100644 --- a/benchmark/Makefile +++ b/benchmark/Makefile @@ -73,6 +73,11 @@ CFLAGS += $(DBGFLAGS) LDFLAGS += $(DBGFLAGS) endif +ifneq ($(DEBUG),1) +CFLAGS += -O2 +endif + + # Add address sanitizer option ifeq ($(ASAN),1) CFLAGS += -fsanitize=address @@ -133,7 +138,6 @@ SRC_C += $(wildcard $(PROJECT_DIR)/*.c) SRC_C += $(wildcard $(MODULES_DIR)/*.c) ## Automated processing below - FILENAMES_C = $(notdir $(SRC_C)) OBJS_C = $(addprefix $(BUILD_DIR)/, $(FILENAMES_C:.c=.o)) vpath %.c $(dir $(SRC_C)) diff --git a/benchmark/bench_modules/wh_bench_mod_sha2.c b/benchmark/bench_modules/wh_bench_mod_sha2.c index f75d8f68..74df2ddd 100644 --- a/benchmark/bench_modules/wh_bench_mod_sha2.c +++ b/benchmark/bench_modules/wh_bench_mod_sha2.c @@ -19,12 +19,17 @@ #include "wh_bench_mod.h" #include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_client_crypto.h" #include "wolfssl/wolfcrypt/hash.h" #include "wolfssl/wolfcrypt/sha256.h" #if defined(WOLFHSM_CFG_BENCH_ENABLE) +#if defined(WOLFHSM_CFG_DMA) && defined(WOLFHSM_CFG_TEST_POSIX) +#include "port/posix/posix_transport_shm.h" +#endif /* WOLFHSM_CFG_DMA && WOLFHSM_CFG_POSIX_TRANSPORT */ + #if !defined(NO_SHA256) int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, @@ -33,17 +38,39 @@ int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, (void)client; int ret = 0; - wc_Sha256 sha256[1]; - uint8_t out[WC_SHA256_DIGEST_SIZE]; + wc_Sha256* sha256 = NULL; + wc_Sha256 sha256Stack; + uint8_t outStack[WC_SHA256_DIGEST_SIZE]; + uint8_t* out; int i = 0; int sha256Initialized = 0; const uint8_t* in; size_t inLen; + sha256 = &sha256Stack; + out = outStack; + #if defined(WOLFHSM_CFG_DMA) if (devId == WH_DEV_ID_DMA) { - in = WH_BENCH_DMA_BUFFER; inLen = WOLFHSM_CFG_BENCH_DMA_BUFFER_SIZE; + if (ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { + /* if static memory was used with DMA then use XMALLOC */ + void* heap = + posixTransportShm_GetDmaHeap(client->comm->transport_context); + in = XMALLOC(inLen, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (in == NULL) { + WH_BENCH_PRINTF("Failed to allocate memory for DMA\n"); + return WH_ERROR_NOSPACE; + } + out = XMALLOC(WC_SHA256_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (out == NULL) { + WH_BENCH_PRINTF("Failed to allocate memory for DMA\n"); + return WH_ERROR_NOSPACE; + } + } + else { + in = WH_BENCH_DMA_BUFFER; + } } else #endif @@ -111,6 +138,16 @@ int _benchSha256(whClientContext* client, whBenchOpContext* ctx, int id, (void)wc_Sha256Free(sha256); } +#if defined(WOLFHSM_CFG_DMA) + if (devId == WH_DEV_ID_DMA && + ctx->transportType == WH_BENCH_TRANSPORT_POSIX_DMA) { + /* if static memory was used with DMA then use XFREE */ + void* heap = + posixTransportShm_GetDmaHeap(client->comm->transport_context); + XFREE((uint8_t*)in, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(out, heap, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif return ret; } diff --git a/benchmark/config/user_settings.h b/benchmark/config/user_settings.h index 7cd4dcbb..3426ab01 100644 --- a/benchmark/config/user_settings.h +++ b/benchmark/config/user_settings.h @@ -197,6 +197,11 @@ extern "C" { #endif #endif +#ifdef WOLFHSM_CFG_DMA +/* use static memory to divide up DMA shared buffer */ +#undef WOLFSSL_STATIC_MEMORY +#define WOLFSSL_STATIC_MEMORY +#endif #ifdef __cplusplus } diff --git a/benchmark/config/wolfhsm_cfg.h b/benchmark/config/wolfhsm_cfg.h index e2169a5c..2a2fa7d3 100644 --- a/benchmark/config/wolfhsm_cfg.h +++ b/benchmark/config/wolfhsm_cfg.h @@ -35,7 +35,7 @@ #define WOLFHSM_CFG_SERVER_KEYCACHE_BUFSIZE 300 #define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_COUNT 2 #define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_BUFSIZE WOLFHSM_CFG_COMM_DATA_LEN -#define WOLFHSM_CFG_SERVER_DMAADDR_COUNT 8 +#define WOLFHSM_CFG_DMAADDR_COUNT 8 #define WOLFHSM_CFG_SERVER_CUSTOMCB_COUNT 6 #define WOLFHSM_CFG_CERTIFICATE_MANAGER diff --git a/benchmark/wh_bench.c b/benchmark/wh_bench.c index b0768edf..914004da 100644 --- a/benchmark/wh_bench.c +++ b/benchmark/wh_bench.c @@ -39,6 +39,12 @@ #include "wolfhsm/wh_client.h" #include "wolfhsm/wh_utils.h" +#if defined(WOLFHSM_CFG_TEST_POSIX) +/* Include transport-specific headers */ +#include "port/posix/posix_transport_shm.h" +#include "port/posix/posix_transport_tcp.h" +#endif /* WOLFHSM_CFG_TEST_POSIX */ + #include "wh_bench.h" #include "wh_bench_mod_all.h" #include "wh_bench_ops.h" @@ -398,8 +404,19 @@ static int _registerBenchModules(whBenchOpContext* benchCtx) return ret; } +void wh_Bench_ListModules(void) +{ + int i; + WH_BENCH_PRINTF("Modules:\n"); + WH_BENCH_PRINTF("Index: Name\n"); + for (i = 0; i < BENCH_MODULE_IDX_COUNT; i++) { + WH_BENCH_PRINTF("%d: %s\n", i, g_benchModules[i].name); + } +} + /* Placeholder for the benchmarking function */ -static int _runClientBenchmarks(whClientContext* client) +static int _runClientBenchmarks(whClientContext* client, int transport, + int moduleIndex) { int ret = 0; whBenchOpContext benchCtx; @@ -413,6 +430,7 @@ static int _runClientBenchmarks(whClientContext* client) WH_BENCH_PRINTF("Failed to initialize benchmark context: %d\n", ret); return ret; } + benchCtx.transportType = transport; /* Register operations to benchmark */ ret = _registerBenchModules(&benchCtx); @@ -421,8 +439,10 @@ static int _runClientBenchmarks(whClientContext* client) return ret; } - /* Iterate over all benchmark modules and run them */ - for (i = 0; i < BENCH_MODULE_IDX_COUNT; i++) { + /* Run specific module or all modules */ + if (moduleIndex >= 0 && moduleIndex < BENCH_MODULE_IDX_COUNT) { + /* Run specific module */ + i = moduleIndex; WH_BENCH_PRINTF("Benchmarking \"%s\"...\n", g_benchModules[i].name); ret = g_benchModules[i].func(client, &benchCtx, g_benchModules[i].id, g_benchModules[i].params); @@ -432,17 +452,48 @@ static int _runClientBenchmarks(whClientContext* client) if (ret == WH_ERROR_NOTIMPL) { WH_BENCH_PRINTF(" -> SKIPPED \"%s\"\n", g_benchModules[i].name); ret = 0; - continue; } - WH_BENCH_PRINTF("Benchmark module \"%s\" failed with error: %d\n", - g_benchModules[i].name, ret); - return ret; + else { + WH_BENCH_PRINTF( + "Benchmark module \"%s\" failed with error: %d\n", + g_benchModules[i].name, ret); + return ret; + } } else { /* Print results for this module */ wh_Bench_PrintIntermediateResult(&benchCtx, g_benchModules[i].id); } } + else { + /* Run all modules */ + for (i = 0; i < BENCH_MODULE_IDX_COUNT; i++) { + WH_BENCH_PRINTF("Benchmarking \"%s\"...\n", g_benchModules[i].name); + ret = + g_benchModules[i].func(client, &benchCtx, g_benchModules[i].id, + g_benchModules[i].params); + /* Allow skipping not implemented modules. Return code could be + * wolfCrypt or wolfSSL error */ + if (ret != 0) { + if (ret == WH_ERROR_NOTIMPL) { + WH_BENCH_PRINTF(" -> SKIPPED \"%s\"\n", + g_benchModules[i].name); + ret = 0; + } + else { + WH_BENCH_PRINTF( + "Benchmark module \"%s\" failed with error: %d\n", + g_benchModules[i].name, ret); + return ret; + } + } + else { + /* Print results for this module */ + wh_Bench_PrintIntermediateResult(&benchCtx, + g_benchModules[i].id); + } + } + } /* Print benchmark results */ wh_Bench_PrintResults(&benchCtx); @@ -457,9 +508,42 @@ static int _runClientBenchmarks(whClientContext* client) return ret; } + +/* additional sanity check in case main() is not used for if the transport + * requested has been enabled */ +static int wh_Bench_CheckTransport(int transport) +{ + switch (transport) { + case WH_BENCH_TRANSPORT_MEM: + break; + case WH_BENCH_TRANSPORT_POSIX_DMA: +#if !defined(WOLFSSL_STATIC_MEMORY) || !defined(WOLFHSM_CFG_TEST_POSIX) + return WH_ERROR_BADARGS; +#else + break; +#endif + case WH_BENCH_TRANSPORT_POSIX_TCP: +#if !defined(WOLFHSM_CFG_TEST_POSIX) + return WH_ERROR_BADARGS; +#else + break; +#endif + case WH_BENCH_TRANSPORT_POSIX_SHM: +#if !defined(WOLFHSM_CFG_TEST_POSIX) + return WH_ERROR_BADARGS; +#else + break; +#endif + default: + return WH_ERROR_BADARGS; + } + return WH_ERROR_OK; +} + + /* Initializes a client context based on the provided config, runs the * benchmarks, then cleans up the context */ -int wh_Bench_ClientCfg(whClientConfig* clientCfg) +int wh_Bench_ClientCfg(whClientConfig* clientCfg, int transport) { int ret = 0; whClientContext client[1] = {0}; @@ -470,6 +554,12 @@ int wh_Bench_ClientCfg(whClientConfig* clientCfg) return WH_ERROR_BADARGS; } + ret = wh_Bench_CheckTransport(transport); + if (ret != WH_ERROR_OK) { + WH_BENCH_PRINTF("Transport not supported: %d\n", ret); + return ret; + } + /* Initialize the client */ ret = wh_Client_Init(client, clientCfg); if (ret != 0) { @@ -477,6 +567,29 @@ int wh_Bench_ClientCfg(whClientConfig* clientCfg) return ret; } +#if defined(WOLFSSL_STATIC_MEMORY) && defined(WOLFHSM_CFG_TEST_POSIX) + if (transport == WH_BENCH_TRANSPORT_POSIX_DMA) { + static const unsigned int listSz = 9; + static const uint32_t sizeList[] = {176, 256, 288, 704, 1056, + 1712, 2112, 2368, 33800}; + static const uint32_t distList[] = {3, 1, 1, 1, 1, 1, 1, 3, 1}; + WOLFSSL_HEAP_HINT* heap = NULL; + + ret = wc_LoadStaticMemory_ex(&heap, listSz, sizeList, distList, NULL, 0, + 0, 0); + if (ret != 0) { + WH_BENCH_PRINTF("Failed to load static memory: %d\n", ret); + return ret; + } + ret = posixTransportShm_SetDmaHeap(clientCfg->comm->transport_context, + (void*)heap); + if (ret != 0) { + WH_BENCH_PRINTF("Failed to set heap: %d\n", ret); + return ret; + } + } +#endif + /* Establish communication with the server */ ret = wh_Client_CommInit(client, &client_id, &server_id); if (ret != 0) { @@ -487,7 +600,8 @@ int wh_Bench_ClientCfg(whClientConfig* clientCfg) } /* Run the benchmarks */ - ret = _runClientBenchmarks(client); + ret = _runClientBenchmarks(client, transport, + -1); /* -1 means run all modules */ /* Clean up */ wh_Client_CommClose(client); @@ -497,13 +611,14 @@ int wh_Bench_ClientCfg(whClientConfig* clientCfg) } /* Runs the benchmarks on an already initialized client context */ -int wh_Bench_ClientCtx(whClientContext* client) +int wh_Bench_ClientCtx(whClientContext* client, int transport) { if (client == NULL) { return WH_ERROR_BADARGS; } - return _runClientBenchmarks(client); + return _runClientBenchmarks(client, transport, + -1); /* -1 means run all modules */ } @@ -553,11 +668,80 @@ int wh_Bench_ServerCfgLoop(whServerConfig* serverCfg) } #if defined(WOLFHSM_CFG_TEST_POSIX) -static void* _whBenchClientTask(void* cf) +typedef struct { + whClientConfig* config; + int moduleIndex; + int transport; +} whBenchClientTaskData; + +static void* _whBenchClientTask(void* data) { - if (wh_Bench_ClientCfg(cf) != 0) { - WH_BENCH_PRINTF("Client benchmark failed\n"); + whBenchClientTaskData* taskData = (whBenchClientTaskData*)data; + whClientContext client[1] = {0}; + uint32_t client_id = 0; + uint32_t server_id = 0; + int ret = 0; + + /* Initialize the client */ + sleep(1); /* Give the server a chance to setup DMA */ + ret = wh_Client_Init(client, taskData->config); + if (ret != WH_ERROR_OK) { + WH_BENCH_PRINTF("Failed to initialize client: %d\n", ret); + return NULL; + } + +#if defined(WOLFSSL_STATIC_MEMORY) && defined(WOLFHSM_CFG_TEST_POSIX) + if (taskData->transport == WH_BENCH_TRANSPORT_POSIX_DMA) { + static const unsigned int listSz = 9; + static const uint32_t sizeList[] = {176, 256, 288, 704, 1056, + 1712, 2112, 2368, 33800}; + static const uint32_t distList[] = {3, 1, 1, 1, 1, 1, 1, 3, 1}; + WOLFSSL_HEAP_HINT* heap = NULL; + posixTransportShmContext* shmCtx; + void* dma; + size_t dmaSz; + + shmCtx = (posixTransportShmContext*) + taskData->config->comm->transport_context; + ret = posixTransportShm_GetDma(shmCtx, &dma, &dmaSz); + if (ret != 0) { + printf("Failed to get DMA\n"); + return NULL; + } + + ret = wc_LoadStaticMemory_ex(&heap, listSz, sizeList, distList, dma, + dmaSz, 0, 0); + if (ret != 0) { + WH_BENCH_PRINTF("Failed to load static memory: %d\n", ret); + return NULL; + } + ret = posixTransportShm_SetDmaHeap(shmCtx, (void*)heap); + if (ret != 0) { + WH_BENCH_PRINTF("Failed to set heap: %d\n", ret); + return NULL; + } + } +#endif + + /* Establish communication with the server */ + ret = wh_Client_CommInit(client, &client_id, &server_id); + if (ret != 0) { + WH_BENCH_PRINTF("Failed to establish communication with server: %d\n", + ret); + wh_Client_Cleanup(client); + return NULL; + } + + /* Run the benchmarks */ + ret = _runClientBenchmarks(client, taskData->transport, + taskData->moduleIndex); + if (ret != 0) { + WH_BENCH_PRINTF("Client benchmark failed: %d\n", ret); } + + /* Clean up */ + wh_Client_CommClose(client); + wh_Client_Cleanup(client); return NULL; } @@ -570,18 +754,20 @@ static void* _whBenchServerTask(void* cf) } static void _whBenchClientServerThreadTest(whClientConfig* c_conf, - whServerConfig* s_conf) + whServerConfig* s_conf, + int moduleIndex, int transport) { pthread_t cthread = {0}; pthread_t sthread = {0}; void* retval; int rc = 0; + whBenchClientTaskData clientData = {c_conf, moduleIndex, transport}; /* Create server thread first */ rc = pthread_create(&sthread, NULL, _whBenchServerTask, s_conf); if (rc == 0) { /* Create client thread */ - rc = pthread_create(&cthread, NULL, _whBenchClientTask, c_conf); + rc = pthread_create(&cthread, NULL, _whBenchClientTask, &clientData); if (rc == 0) { /* Wait for client to finish, then cancel server */ pthread_join(cthread, &retval); @@ -596,42 +782,209 @@ static void _whBenchClientServerThreadTest(whClientConfig* c_conf, } } -int wh_Bench_ClientServer_Posix(void) +/* Global static variables for transport configurations */ +static uint8_t g_mem_req[BUFFER_SIZE] = {0}; +static uint8_t g_mem_resp[BUFFER_SIZE] = {0}; +static whTransportMemConfig g_mem_tmcf = { + .req = (whTransportMemCsr*)g_mem_req, + .req_size = sizeof(g_mem_req), + .resp = (whTransportMemCsr*)g_mem_resp, + .resp_size = sizeof(g_mem_resp), +}; +static whTransportClientCb g_mem_tccb = WH_TRANSPORT_MEM_CLIENT_CB; +static whTransportMemClientContext g_mem_tmcc = {0}; +static whCommClientConfig g_mem_cc_conf = { + .transport_cb = &g_mem_tccb, + .transport_context = (void*)&g_mem_tmcc, + .transport_config = (void*)&g_mem_tmcf, + .client_id = 123, +}; + +static whTransportServerCb g_mem_tscb = WH_TRANSPORT_MEM_SERVER_CB; +static whTransportMemServerContext g_mem_tmsc = {0}; +static whCommServerConfig g_mem_cs_conf = { + .transport_cb = &g_mem_tscb, + .transport_context = (void*)&g_mem_tmsc, + .transport_config = (void*)&g_mem_tmcf, + .server_id = 124, +}; + +/* Helper function to configure client transport based on type */ +static int _configureClientTransport(whBenchTransportType transport, + whClientConfig* c_conf) { - uint8_t req[BUFFER_SIZE] = {0}; - uint8_t resp[BUFFER_SIZE] = {0}; - uint8_t memory[FLASH_RAM_SIZE] = {0}; - - /* Transport memory configuration */ - whTransportMemConfig tmcf[1] = {{ - .req = (whTransportMemCsr*)req, - .req_size = sizeof(req), - .resp = (whTransportMemCsr*)resp, - .resp_size = sizeof(resp), - }}; + int ret = WH_ERROR_OK; + + switch (transport) { + case WH_BENCH_TRANSPORT_MEM: { + /* Memory transport configuration */ + c_conf->comm = &g_mem_cc_conf; + break; + } + +#if defined(WOLFSSL_STATIC_MEMORY) && defined(WOLFHSM_CFG_TEST_POSIX) + case WH_BENCH_TRANSPORT_POSIX_DMA: { + static whClientDmaConfig dmaConfig; + + dmaConfig.cb = posixTransportShm_ClientStaticMemDmaCallback; + dmaConfig.dmaAddrAllowList = NULL; + c_conf->dmaConfig = &dmaConfig; + }; + __attribute__((fallthrough)); + /* Fall through */ +#endif + + case WH_BENCH_TRANSPORT_POSIX_SHM: { + /* Shared memory transport configuration */ + static whTransportClientCb pttcClientShmCb[1] = { + POSIX_TRANSPORT_SHM_CLIENT_CB}; + static posixTransportShmClientContext tccShm; + static posixTransportShmConfig myshmconfig = { + .name = "wh_bench_shm", + .req_size = 7000, + .resp_size = 7000, + .dma_size = 80000, + }; + static whCommClientConfig ccShmConf = { + .transport_cb = pttcClientShmCb, + .transport_context = (void*)&tccShm, + .transport_config = (void*)&myshmconfig, + .client_id = 12, + }; + + memset(&tccShm, 0, sizeof(posixTransportShmClientContext)); + c_conf->comm = &ccShmConf; + break; + } + + case WH_BENCH_TRANSPORT_POSIX_TCP: { + /* TCP transport configuration */ + static whTransportClientCb pttcClientTcpCb = PTT_CLIENT_CB; + static posixTransportTcpClientContext tccTcp; + static posixTransportTcpConfig mytcpconfig = { + .server_ip_string = "127.0.0.1", + .server_port = 23456, + }; + static whCommClientConfig ccTcpConf = { + .transport_cb = &pttcClientTcpCb, + .transport_context = (void*)&tccTcp, + .transport_config = (void*)&mytcpconfig, + .client_id = 12, + }; + + memset(&tccTcp, 0, sizeof(posixTransportTcpClientContext)); + c_conf->comm = &ccTcpConf; + break; + } + default: + ret = WH_ERROR_BADARGS; + break; + } + + return ret; +} + +/* Helper function to configure server transport based on type */ +static int _configureServerTransport(whBenchTransportType transport, + whServerConfig* s_conf) +{ + int ret = WH_ERROR_OK; + + switch (transport) { + case WH_BENCH_TRANSPORT_MEM: { + /* Memory transport configuration */ + s_conf->comm_config = &g_mem_cs_conf; + break; + } + +#if defined(WOLFSSL_STATIC_MEMORY) && defined(WOLFHSM_CFG_TEST_POSIX) + case WH_BENCH_TRANSPORT_POSIX_DMA: { + static whServerDmaConfig dmaConfig; + + dmaConfig.cb = posixTransportShm_ServerStaticMemDmaCallback; + dmaConfig.dmaAddrAllowList = NULL; + s_conf->dmaConfig = &dmaConfig; + }; + __attribute__((fallthrough)); + /* Fall through */ +#endif + + case WH_BENCH_TRANSPORT_POSIX_SHM: { + /* Shared memory transport configuration */ + static whTransportServerCb pttServerShmCb[1] = { + POSIX_TRANSPORT_SHM_SERVER_CB}; + static posixTransportShmServerContext tscShm; + static posixTransportShmConfig myshmconfig = { + .name = "wh_bench_shm", + .req_size = 7000, + .resp_size = 7000, + .dma_size = 80000, + }; + static whCommServerConfig csShmConf = { + .transport_cb = pttServerShmCb, + .transport_context = (void*)&tscShm, + .transport_config = (void*)&myshmconfig, + .server_id = 57, + }; + + memset(&tscShm, 0, sizeof(posixTransportShmServerContext)); + s_conf->comm_config = &csShmConf; + break; + } + + case WH_BENCH_TRANSPORT_POSIX_TCP: { + /* TCP transport configuration */ + static whTransportServerCb pttServerTcpCb = PTT_SERVER_CB; + static posixTransportTcpServerContext tscTcp; + static posixTransportTcpConfig mytcpconfig = { + .server_ip_string = "127.0.0.1", + .server_port = 23456, + }; + static whCommServerConfig csTcpConf = { + .transport_cb = &pttServerTcpCb, + .transport_context = (void*)&tscTcp, + .transport_config = (void*)&mytcpconfig, + .server_id = 57, + }; + + memset(&tscTcp, 0, sizeof(posixTransportTcpServerContext)); + s_conf->comm_config = &csTcpConf; + break; + } + + default: + ret = WH_ERROR_BADARGS; + break; + } + + return ret; +} + + +/* transport is the type of transport to use */ +int wh_Bench_ClientServer_Posix(int transport, int moduleIndex) +{ + static uint8_t memory[FLASH_RAM_SIZE] = {0}; + int ret = WH_ERROR_OK; /* Client configuration/contexts */ - whTransportClientCb tccb[1] = {WH_TRANSPORT_MEM_CLIENT_CB}; - whTransportMemClientContext tmcc[1] = {0}; - whCommClientConfig cc_conf[1] = {{ - .transport_cb = tccb, - .transport_context = (void*)tmcc, - .transport_config = (void*)tmcf, - .client_id = 123, - }}; - whClientConfig c_conf[1] = {{ - .comm = cc_conf, - }}; + whClientConfig c_conf[1] = {{0}}; /* Server configuration/contexts */ - whTransportServerCb tscb[1] = {WH_TRANSPORT_MEM_SERVER_CB}; - whTransportMemServerContext tmsc[1] = {0}; - whCommServerConfig cs_conf[1] = {{ - .transport_cb = tscb, - .transport_context = (void*)tmsc, - .transport_config = (void*)tmcf, - .server_id = 124, - }}; + whServerConfig s_conf[1] = {{0}}; + + /* Configure transport based on type */ + ret = _configureClientTransport(transport, c_conf); + if (ret != WH_ERROR_OK) { + WH_BENCH_PRINTF("Failed to configure client transport: %d\n", ret); + return ret; + } + + ret = _configureServerTransport(transport, s_conf); + if (ret != WH_ERROR_OK) { + WH_BENCH_PRINTF("Failed to configure server transport: %d\n", ret); + return ret; + } /* RamSim Flash state and configuration */ whFlashRamsimCtx fc[1] = {0}; @@ -667,19 +1020,25 @@ int wh_Bench_ClientServer_Posix(void) }}; #endif - whServerConfig s_conf[1] = {{ - .comm_config = cs_conf, - .nvm = nvm, + /* Set up server configuration with NVM and crypto */ + s_conf[0].nvm = nvm; #ifndef WOLFHSM_CFG_NO_CRYPTO - .crypto = crypto, - .devId = INVALID_DEVID, + s_conf[0].crypto = crypto; + s_conf[0].devId = INVALID_DEVID; #endif - }}; + + /* Initialize Flash first */ + ret = whFlashRamsim_Init(fc, fc_conf); + if (ret != 0) { + WH_BENCH_PRINTF("Failed to initialize Flash: %d\n", ret); + return ret; + } /* Initialize NVM */ - int ret = wh_Nvm_Init(nvm, n_conf); + ret = wh_Nvm_Init(nvm, n_conf); if (ret != 0) { WH_BENCH_PRINTF("Failed to initialize NVM: %d\n", ret); + whFlashRamsim_Cleanup(fc); return ret; } @@ -689,6 +1048,7 @@ int wh_Bench_ClientServer_Posix(void) if (ret != 0) { WH_BENCH_PRINTF("Failed to initialize wolfCrypt: %d\n", ret); wh_Nvm_Cleanup(nvm); + whFlashRamsim_Cleanup(fc); return ret; } @@ -698,15 +1058,17 @@ int wh_Bench_ClientServer_Posix(void) WH_BENCH_PRINTF("Failed to initialize RNG: %d\n", ret); wolfCrypt_Cleanup(); wh_Nvm_Cleanup(nvm); + whFlashRamsim_Cleanup(fc); return ret; } #endif /* Run client and server in separate threads */ - _whBenchClientServerThreadTest(c_conf, s_conf); + _whBenchClientServerThreadTest(c_conf, s_conf, moduleIndex, transport); /* Clean up */ wh_Nvm_Cleanup(nvm); + whFlashRamsim_Cleanup(fc); #ifndef WOLFHSM_CFG_NO_CRYPTO wc_FreeRng(crypto->rng); diff --git a/benchmark/wh_bench.h b/benchmark/wh_bench.h index 8bcadb45..d3db47d8 100644 --- a/benchmark/wh_bench.h +++ b/benchmark/wh_bench.h @@ -28,24 +28,29 @@ /* * Runs the client benchmarks against a server using POSIX threads + * transport: The type of transport to use for communication + * moduleIndex: The specific benchmark module to run (optional, -1 for all) * Returns 0 on success and a non-zero error code on failure */ -int wh_Bench_ClientServer_Posix(void); +int wh_Bench_ClientServer_Posix(int transport, int moduleIndex); /* * Client-side benchmarking function. Takes in a client configuration, * initializes the client, runs benchmarks against the server, then cleans up * and closes the client. */ -int wh_Bench_ClientCfg(whClientConfig* clientCfg); +int wh_Bench_ClientCfg(whClientConfig* clientCfg, int transport); /* * Client-side benchmarking function. Runs the benchmarks on an already * initialized client context with no initialization or cleanup. */ -int wh_Bench_ClientCtx(whClientContext* client); +int wh_Bench_ClientCtx(whClientContext* client, int transport); /* Server-side processing loop for benchmarking */ int wh_Bench_ServerCfgLoop(whServerConfig* serverCfg); + +/* List all modules */ +void wh_Bench_ListModules(void); #endif /* WH_BENCH_H_ */ diff --git a/benchmark/wh_bench_main.c b/benchmark/wh_bench_main.c index 57006559..3ef8e518 100644 --- a/benchmark/wh_bench_main.c +++ b/benchmark/wh_bench_main.c @@ -18,18 +18,70 @@ */ #include "wolfhsm/wh_settings.h" #include "wh_bench.h" +#include "wh_bench_ops.h" #include "wh_bench_utils.h" #if defined(WOLFHSM_CFG_BENCH_ENABLE) -int main(void) +#include +#include + +void Usage(const char* exeName) +{ + printf("Usage: %s --type --module --list\n", exeName); + printf("Type: mem, shm, tcp, dma\n"); + printf("Module: index of the module to run\n"); + printf("List: list all modules\n"); + exit(1); +} + +int main(int argc, char** argv) { - WH_BENCH_PRINTF("Running wolfHSM benchmarks\n"); + int transport = WH_BENCH_TRANSPORT_MEM; + int moduleIndex = -1; + int i; + + WH_BENCH_PRINTF("wolfHSM POSIX benchmark built with wolfSSL version %s\n", + LIBWOLFSSL_VERSION_STRING); + + /* Parse command-line arguments */ + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--type") == 0 && i + 1 < argc) { + const char* type = argv[++i]; + if (strcmp(type, "mem") == 0) { + transport = WH_BENCH_TRANSPORT_MEM; + } + else if (strcmp(type, "shm") == 0) { + transport = WH_BENCH_TRANSPORT_POSIX_SHM; + } + else if (strcmp(type, "tcp") == 0) { + transport = WH_BENCH_TRANSPORT_POSIX_TCP; + } + else if (strcmp(type, "dma") == 0) { + transport = WH_BENCH_TRANSPORT_POSIX_DMA; + } + else { + printf("Invalid transport type: %s\n", type); + Usage(argv[0]); + return -1; + } + } + else if (strcmp(argv[i], "--module") == 0 && i + 1 < argc) { + moduleIndex = atoi(argv[++i]); + } + else if (strcmp(argv[i], "--list") == 0) { + wh_Bench_ListModules(); + return 0; + } + else { + printf("Invalid argument: %s\n", argv[i]); + Usage(argv[0]); + return -1; + } + } #if defined(WOLFHSM_CFG_TEST_POSIX) - WH_BENCH_PRINTF( - "Running benchmarks with memory transport in POSIX threads\n"); - int ret = wh_Bench_ClientServer_Posix(); + int ret = wh_Bench_ClientServer_Posix(transport, moduleIndex); if (ret != 0) { WH_BENCH_PRINTF("Memory transport benchmark failed: %d\n", ret); return ret; diff --git a/benchmark/wh_bench_ops.c b/benchmark/wh_bench_ops.c index 3239c61a..dd5a478c 100644 --- a/benchmark/wh_bench_ops.c +++ b/benchmark/wh_bench_ops.c @@ -306,7 +306,21 @@ int wh_Bench_PrintResults(whBenchOpContext* ctx) return WH_ERROR_BADARGS; } - WH_BENCH_PRINTF("\nBenchmark Results:\n"); + WH_BENCH_PRINTF("\nBenchmark Results "); + switch (ctx->transportType) { + case WH_BENCH_TRANSPORT_MEM: + WH_BENCH_PRINTF("(Memory):\n"); + break; + case WH_BENCH_TRANSPORT_POSIX_SHM: + WH_BENCH_PRINTF("(Shared Memory):\n"); + break; + case WH_BENCH_TRANSPORT_POSIX_TCP: + WH_BENCH_PRINTF("(TCP):\n"); + break; + case WH_BENCH_TRANSPORT_POSIX_DMA: + WH_BENCH_PRINTF("(DMA):\n"); + break; + } WH_BENCH_PRINTF( "|--------------------------------|------------|------------|----------" "--|------------|------------|--------------------|\n"); @@ -351,23 +365,23 @@ int wh_Bench_PrintResults(whBenchOpContext* ctx) if (throughput < 1024.0) { /* Bytes per second */ - WH_BENCH_SNPRINTF(buffer, sizeof(buffer), - "%.2f B/s", throughput); + WH_BENCH_SNPRINTF(buffer, sizeof(buffer), "%.2f B/s", + throughput); } else if (throughput < 1024.0 * 1024.0) { /* Kilobytes per second */ - WH_BENCH_SNPRINTF(buffer, sizeof(buffer), - "%.2f KB/s", throughput / 1024.0); + WH_BENCH_SNPRINTF(buffer, sizeof(buffer), "%.2f KB/s", + throughput / 1024.0); } else { /* Megabytes per second */ - WH_BENCH_SNPRINTF(buffer, sizeof(buffer), - "%.2f MB/s", throughput / (1024.0 * 1024.0)); + WH_BENCH_SNPRINTF(buffer, sizeof(buffer), "%.2f MB/s", + throughput / (1024.0 * 1024.0)); } } else if (ctx->ops[i].throughputType == BENCH_THROUGHPUT_OPS) { - WH_BENCH_SNPRINTF(buffer, sizeof(buffer), - "%.2f ops/s", ctx->ops[i].throughput); + WH_BENCH_SNPRINTF(buffer, sizeof(buffer), "%.2f ops/s", + ctx->ops[i].throughput); } else { /* No throughput */ diff --git a/benchmark/wh_bench_ops.h b/benchmark/wh_bench_ops.h index ffcd9114..fbc03fb6 100644 --- a/benchmark/wh_bench_ops.h +++ b/benchmark/wh_bench_ops.h @@ -37,6 +37,17 @@ typedef enum { BENCH_THROUGHPUT_OPS /* Operations per second */ } whBenchOpThroughputType; +/* Transport type enumeration for benchmark testing */ +typedef enum { + WH_BENCH_TRANSPORT_MEM = + 0, /* Memory transport (WH_TRANSPORT_MEM_CLIENT_CB) */ + WH_BENCH_TRANSPORT_POSIX_SHM, /* Shared memory transport + (POSIX_TRANSPORT_SHM_CLIENT_CB) */ + WH_BENCH_TRANSPORT_POSIX_TCP, /* TCP transport (PTT_CLIENT_CB) */ + WH_BENCH_TRANSPORT_POSIX_DMA, /* DMA transport + (POSIX_TRANSPORT_REF_CLIENT_CB) */ +} whBenchTransportType; + typedef struct whBenchOp { /* Name of the operation being timed */ char name[MAX_OP_NAME]; @@ -65,6 +76,7 @@ typedef struct whBenchOp { typedef struct whBenchOpContext { whBenchOp ops[MAX_BENCH_OPS]; /* Array of operations */ int opCount; /* Number of registered operations */ + whBenchTransportType transportType; /* Type of transport */ } whBenchOpContext; /* @@ -100,4 +112,4 @@ int wh_Bench_Reset(whBenchOpContext* ctx); /* Clean up benchmark context */ int wh_Bench_Cleanup(whBenchOpContext* ctx); -#endif /* WH_BENCH_OPS_H_ */ \ No newline at end of file +#endif /* WH_BENCH_OPS_H_ */ diff --git a/examples/Makefile b/examples/Makefile index 4fc33c96..35f34363 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,15 +1,15 @@ -.PHONY: all posix_tcp_wh_client_tcp posix_tcp_wh_server_tcp clean +.PHONY: all wh_posix_client wh_posix_server clean -all: posix_tcp_wh_client_tcp posix_tcp_wh_server_tcp +all: wh_posix_client wh_posix_server -posix_tcp_wh_client_tcp: - make -C posix/tcp/wh_client_tcp +wh_posix_client: + make -C posix/wh_posix_client -posix_tcp_wh_server_tcp: - make -C posix/tcp/wh_server_tcp +wh_posix_server: + make -C posix/wh_posix_server clean: - make -C posix/tcp/wh_client_tcp clean - make -C posix/tcp/wh_server_tcp clean + make -C posix/wh_posix_client clean + make -C posix/wh_posix_server clean diff --git a/examples/README.md b/examples/README.md index 4973a900..0dbb23f4 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,9 +8,6 @@ This directory contains examples code demonstrating how to use various wolfHSM f ## Current Examples Currently, the only public example for wolfHSM uses the POSIX simulator. If you are interested in examples for NDA-restricted hardware platforms, please contact us at support@wolfssl.com. -### Posix TCP server and client -This example spawns a wolfHSM client and server, both in their own thread, and runs the client-side unit tests against the server. - ### Building To build the client and the server examples, wolfHSM must be configured and built along side wolfSSL. @@ -25,36 +22,48 @@ WOLFSSL_DIR ?= $(CURDIR)/../../../../wolfssl Set the `WOLFHSM_DIR` and `WOLFSSL_DIR` variables to point to your local installation of wolfHSM and wolfSSL. Now the client and server demo application can be built. -### Building wh_server_tcp -`cd` into `examples/posix/tcp/wh_server_tcp` and run `make`. Once completed, the output server executable `wh_server_tcp.elf` will be located in the `Build` directory. +### Building POSIX server example wh_posix_server +`cd` into `examples/posix/wh_posix_server` and run `make`. Once completed, the output server executable `wh_posix_server.elf` will be located in the `Build` directory. -### Building wh_client_tcp -`cd` into `examples/posix/tcp/wh_client_tcp` and run `make`. Once completed, the output server executable `wh_client_tcp.elf` will be located in the `Build` directory. +### Building POSIX client example wh_posix_client +`cd` into `examples/posix/wh_posix_client` and run `make`. Once completed, the output server executable `wh_posix_client.elf` will be located in the `Build` directory. ### Executables -Run `examples/posix/tcp/wh_server_tcp/Build/wh_server_tcp.elf` to launch the server. In a separate shell, run `examples/posix/tcp/wh_client_tcp/Build/wh_client_tcp.elf` to launch the client. +Run `examples/posix/tcp/wh_posix_server/Build/wh_posix_server.elf` to launch the server. In a separate shell, run `examples/posix/wh_posix_client/Build/wh_posix_client.elf` to launch the client. ### Initializing server NVM The server example supports two methods for initializing its Non-Volatile Memory (NVM) with cryptographic keys and objects. +#### Choosing a specific transport to use +With POSIX builds there is multiple transport types available. They can be used with the --type flag. +The types of transports are: + +- shm : Using shared memory +- tcp : Using TCP connections (default) +- dma : Builds off of shm and adds in a common buffer that is accessed by offsets passed between the client and server + +``` +./wh_server_posix.elf --type shm +``` + #### Loading a single key To load a single key with a specific keyId, use the `--key` and `--id` arguments: ``` -./wh_server_tcp.elf --key /path/to/key.der --id +./wh_posix_server.elf --key /path/to/key.der --id ``` You can also specify a client ID with the `--client` argument (default is 12): ``` -./wh_server_tcp.elf --key /path/to/key.der --id --client +./wh_posix_server.elf --key /path/to/key.der --id --client ``` #### Using an NVM initialization file For more complex scenarios requiring multiple keys or objects, use the `--nvminit` argument to specify a configuration file: ``` -./wh_server_tcp.elf --nvminit /path/to/nvminit.conf +./wh_posix_server.elf --nvminit /path/to/nvminit.conf ``` The NVM initialization file allows you to define multiple keys and objects to be loaded into the server's NVM. The file format is as follows: diff --git a/examples/posix/README.md b/examples/posix/README.md new file mode 100644 index 00000000..91642776 --- /dev/null +++ b/examples/posix/README.md @@ -0,0 +1,14 @@ +# POSIX Examples + +There are a couple of different ways POSIX can be used for transport. + +- tcp +- shm (Shared memory) +- dma (Shared memory pass by offset into DMA area making use of wolfSSL static memory feature) + +Each of these methods has its setup function in wh_posix_[server|client]_cfg.c +that contains the unique example configuration for setting each up. + +Sub directories contain the server and client logic. wh_posix_server and +wh_posix_client. Selecting which type of transport to use in the client/server +can be done by using the -t flag. i.e `./client -type shm`. diff --git a/examples/posix/tcp/wh_client_tcp/wh_client_tcp.c b/examples/posix/tcp/wh_client_tcp/wh_client_tcp.c deleted file mode 100644 index b151ee52..00000000 --- a/examples/posix/tcp/wh_client_tcp/wh_client_tcp.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * wolfHSM Client TCP Example - */ - -#include -#include /* For printf */ -#include /* For memset, memcpy */ -#include /* for read */ -#include /* For nanosleep */ - -#include "wolfhsm/wh_error.h" -#include "wolfhsm/wh_comm.h" -#include "wolfhsm/wh_utils.h" -#include "wolfhsm/wh_message.h" -#include "wolfhsm/wh_client.h" -#include "wolfhsm/wh_client_crypto.h" -#include "port/posix/posix_transport_tcp.h" - -#include "wh_demo_client_all.h" - -/** Local declarations */ -static void _sleepMs(long milliseconds); -static int wh_ClientTask(void* cf); - - -static void _sleepMs(long milliseconds) -{ - struct timespec req; - req.tv_sec = milliseconds / 1000; - req.tv_nsec = (milliseconds % 1000) * 1000000; - nanosleep(&req, NULL); -} - -enum { - REPEAT_COUNT = 10, - REQ_SIZE = 32, - RESP_SIZE = 64, - ONE_MS = 1, -}; - -#define WH_SERVER_TCP_IPSTRING "127.0.0.1" -#define WH_SERVER_TCP_PORT 23456 -#define WH_CLIENT_ID 12 - -static int wh_ClientTask(void* cf) -{ - whClientConfig* config = (whClientConfig*)cf; - int ret = 0; - whClientContext client[1]; - int counter = 1; - - uint8_t tx_req[REQ_SIZE] = {0}; - uint16_t tx_req_len = 0; - - uint8_t rx_resp[RESP_SIZE] = {0}; - uint16_t rx_resp_len = 0; - - if (config == NULL) { - return -1; - } - - ret = wh_Client_Init(client, config); - - printf("Client connecting to server...\n"); - - if (ret != 0) { - perror("Init error:"); - return -1; - } - for(counter = 0; counter < REPEAT_COUNT; counter++) - { - sprintf((char*)tx_req,"Request:%u",counter); - tx_req_len = strlen((char*)tx_req); - do { - ret = wh_Client_EchoRequest(client, - tx_req_len, tx_req); - if (ret != WH_ERROR_NOTREADY) { - if (ret == 0) { - printf("Client sent request successfully\n"); - } else { - printf("wh_CLient_EchoRequest failed with ret=%d\n", ret); - } - } - _sleepMs(ONE_MS); - } while (ret == WH_ERROR_NOTREADY); - - if (ret != 0) { - printf("Client had failure. Exiting\n"); - break; - } - - rx_resp_len = 0; - memset(rx_resp, 0, sizeof(rx_resp)); - - do { - ret = wh_Client_EchoResponse(client, - &rx_resp_len, rx_resp); - _sleepMs(ONE_MS); - } while (ret == WH_ERROR_NOTREADY); - - if (ret != 0) { - printf("Client had failure. Exiting\n"); - break; - } - } - - /* Context 1: Client Local Crypto */ - WC_RNG rng[1]; - uint8_t buffer[128] = {0}; - wc_InitRng_ex(rng, NULL, INVALID_DEVID); - wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); - wc_FreeRng(rng); - wh_Utils_Hexdump("Context 1: Client Local RNG:\n", buffer, sizeof(buffer)); - - /* Context 2: Client Remote Crypto */ - memset(buffer, 0, sizeof(buffer)); - wc_InitRng_ex(rng, NULL, WH_DEV_ID); - wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); - wc_FreeRng(rng); - wh_Utils_Hexdump("Context 2: Client Remote RNG:\n", buffer, sizeof(buffer)); - - - /* run the client demos */ - ret = wh_DemoClient_All(client); - if (ret != 0) { - printf("Client demo failed: ret=%d\n", ret); - } - - - (void)wh_Client_CommClose(client); - (void)wh_Client_Cleanup(client); - printf("Client disconnected\n"); - return ret; -} - -int main(int argc, char** argv) -{ - (void)argc; (void)argv; - - /* Client configuration/contexts */ - whTransportClientCb pttccb[1] = {PTT_CLIENT_CB}; - posixTransportTcpClientContext tcc[1] = {}; - posixTransportTcpConfig mytcpconfig[1] = {{ - .server_ip_string = WH_SERVER_TCP_IPSTRING, - .server_port = WH_SERVER_TCP_PORT, - }}; - - whCommClientConfig cc_conf[1] = {{ - .transport_cb = pttccb, - .transport_context = (void*)tcc, - .transport_config = (void*)mytcpconfig, - .client_id = WH_CLIENT_ID, - }}; - whClientConfig c_conf[1] = {{ - .comm = cc_conf, - }}; - - return wh_ClientTask(c_conf); -} \ No newline at end of file diff --git a/examples/posix/wh_posix_cfg.h b/examples/posix/wh_posix_cfg.h new file mode 100644 index 00000000..42659e0c --- /dev/null +++ b/examples/posix/wh_posix_cfg.h @@ -0,0 +1,121 @@ +/* This holds all constants used in the POSIX examples */ + +#ifndef WH_POSIX_CFG_H +#define WH_POSIX_CFG_H + +/* =========================================== + * TRANSPORT AND COMMUNICATION CONSTANTS + * =========================================== */ + +/* Client and Server IDs */ +#define WH_POSIX_CLIENT_ID 12 +#define WH_POSIX_SERVER_ID 57 +#define WH_POSIX_MAX_CLIENT_ID 255 + +/* TCP Communication */ +#define WH_POSIX_SERVER_TCP_PORT 23456 +#define WH_POSIX_SERVER_TCP_IPSTRING "127.0.0.1" + +/* Shared Memory Configuration */ +#define WH_POSIX_SHARED_MEMORY_NAME "wh_example_shm" + +/* =========================================== + * DMA AND BUFFER SIZES + * =========================================== */ + +/* Request and Response Buffer Sizes */ +#define WH_POSIX_REQ_SIZE 1024 +#define WH_POSIX_RESP_SIZE 1024 +#define WH_POSIX_DMA_SIZE 8000 + +/* Data Buffer Sizes */ +#define WH_POSIX_DATA_BUFFER_SIZE 0x400 /* 1024 bytes */ +#define WH_POSIX_KEY_BUFFER_SIZE 4096 +#define WH_POSIX_MAX_LINE_LENGTH 4608 /* 512 + PATH_MAX */ + +/* =========================================== + * FILE SYSTEM CONSTANTS + * =========================================== */ + +/* File Path Limits */ +#define WH_POSIX_PATH_MAX 4096 +#define WH_POSIX_LABEL_SIZE 256 + +/* =========================================== + * CRYPTO CONSTANTS + * =========================================== */ + +/* RSA Key Sizes */ +#define WH_POSIX_RSA_MIN_SIZE 1024 +#define WH_POSIX_RSA_2048_SIZE 2048 +#define WH_POSIX_RSA_4096_SIZE 4096 + +/* ECC Key Sizes */ +#define WH_POSIX_ECC_KEYSIZE 32 +#define WH_POSIX_FP_MAX_BITS 8192 + +/* AES Constants */ +#define WH_POSIX_AES_KEYSIZE 16 +#define WH_POSIX_AES_TEXTSIZE 16 +#define WH_POSIX_AES_AUTHSIZE 16 +#define WH_POSIX_AES_TAGSIZE 16 + +/* CMAC Constants */ +#define WH_POSIX_CMAC_TEXTSIZE 1000 + +/* Key Cache Constants */ +#define WH_POSIX_KEYCACHE_KEYSIZE 16 + +/* =========================================== + * MEMORY AND STORAGE CONSTANTS + * =========================================== */ + +/* Flash and RAM Sizes */ +#define WH_POSIX_FLASH_RAM_SIZE (1024 * 1024) /* 1MB */ +#define WH_POSIX_STATIC_MEMORY_TEST_SZ 120000 + +/* NVM Object Count */ +#define WH_POSIX_NVM_OBJECT_COUNT 30 + + +/* Macros for maximum client ID and key ID */ +#define MAX_CLIENT_ID 255 +#define MAX_KEY_ID UINT16_MAX + +/* Macros for maximum file path length (Linux PATH_MAX is a good reference) */ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +/* Parameterize MAX_LINE_LENGTH by 512 bytes + MAX_FILE_PATH_LENGTH */ +#define MAX_LINE_LENGTH (512 + PATH_MAX) + + +/* =========================================== + * STATIC MEMORY ALLOCATION SIZES + * =========================================== */ + +/* Static Memory Size List */ +#define WH_POSIX_STATIC_MEM_LIST_SIZE 9 +#define WH_POSIX_STATIC_MEM_SIZE_1 176 +#define WH_POSIX_STATIC_MEM_SIZE_2 256 +#define WH_POSIX_STATIC_MEM_SIZE_3 288 +#define WH_POSIX_STATIC_MEM_SIZE_4 704 +#define WH_POSIX_STATIC_MEM_SIZE_5 1056 +#define WH_POSIX_STATIC_MEM_SIZE_6 1712 +#define WH_POSIX_STATIC_MEM_SIZE_7 2112 +#define WH_POSIX_STATIC_MEM_SIZE_8 2368 +#define WH_POSIX_STATIC_MEM_SIZE_9 4096 + +/* Static Memory Distribution List */ +#define WH_POSIX_STATIC_MEM_DIST_1 3 +#define WH_POSIX_STATIC_MEM_DIST_2 1 +#define WH_POSIX_STATIC_MEM_DIST_3 1 +#define WH_POSIX_STATIC_MEM_DIST_4 1 +#define WH_POSIX_STATIC_MEM_DIST_5 1 +#define WH_POSIX_STATIC_MEM_DIST_6 1 +#define WH_POSIX_STATIC_MEM_DIST_7 1 +#define WH_POSIX_STATIC_MEM_DIST_8 3 +#define WH_POSIX_STATIC_MEM_DIST_9 1 + +#endif diff --git a/examples/posix/tcp/wh_client_tcp/Makefile b/examples/posix/wh_posix_client/Makefile similarity index 87% rename from examples/posix/tcp/wh_client_tcp/Makefile rename to examples/posix/wh_posix_client/Makefile index b9c62be4..f25c4e88 100644 --- a/examples/posix/tcp/wh_client_tcp/Makefile +++ b/examples/posix/wh_posix_client/Makefile @@ -2,15 +2,16 @@ ## Project name # Sets output filenames -BIN = wh_client_tcp +BIN = wh_posix_client ## Important directories # Base directory for additional project files PROJECT_DIR ?= . CONFIG_DIR ?= $(PROJECT_DIR)/config +SHARED_CONFIG_DIR ?= $(PROJECT_DIR)/../ # wolfSSL and wolfHSM directories -WOLFSSL_DIR ?= ../../../../../wolfssl -WOLFHSM_DIR ?= ../../../../ +WOLFSSL_DIR ?= ../../../../wolfssl +WOLFHSM_DIR ?= ../../../ WOLFHSM_PORT_DIR ?= $(WOLFHSM_DIR)/port/posix WOLFHSM_DEMO_CLIENT_DIR ?= $(WOLFHSM_DIR)/examples/demo/client @@ -20,6 +21,7 @@ BUILD_DIR ?= $(PROJECT_DIR)/Build # Includes INC = -I$(PROJECT_DIR) \ -I$(CONFIG_DIR) \ + -I$(SHARED_CONFIG_DIR) \ -I$(WOLFSSL_DIR) \ -I$(WOLFHSM_DIR) \ -I$(WOLFHSM_PORT_DIR) \ @@ -31,9 +33,6 @@ DEF += -D_POSIX_C_SOURCE=200809L # Library configuration defines for user-supplied settings DEF += -DWOLFSSL_USER_SETTINGS -DWOLFHSM_CFG -# Set the default device ID for wolfCrypt tests -DEF += -DWC_USE_DEVID=0x5748534D - # Architecture flags for assembler, C compiler and linker ARCHFLAGS ?= @@ -57,6 +56,9 @@ else LDFLAGS += -Wl,--gc-sections endif +# Libc for printf, libm for math (used with DH) +LIBS = -lc -lm + # LD: generate map #LDFLAGS += -Wl,-map,$(BUILD_DIR)/$(BIN).map #LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(BIN).map @@ -87,6 +89,19 @@ SRC_C += $(wildcard $(WOLFSSL_DIR)/wolfcrypt/benchmark/*.c) # wolfSSL source files SRC_C += $(wildcard $(WOLFSSL_DIR)/src/*.c) +# Set the default device ID for wolfCrypt tests +ifeq ($(DMA),1) +DEF += -DWC_USE_DEVID=0x57444D41 -DWC_NO_DEFAULT_DEVID +CFLAGS += -DWOLFHSM_CFG_DMA +else +DEF += -DWC_USE_DEVID=0x5748534D + +endif + +#wolfCrypt test/benchmark source files +SRC_C += $(wildcard $(WOLFSSL_DIR)/wolfcrypt/test/*.c) +SRC_C += $(wildcard $(WOLFSSL_DIR)/wolfcrypt/benchmark/*.c) + # wolfHSM source files SRC_C += $(wildcard $(WOLFHSM_DIR)/src/*.c) @@ -97,7 +112,7 @@ SRC_C += $(wildcard $(WOLFHSM_PORT_DIR)/*.c) SRC_C += $(wildcard $(PROJECT_DIR)/*.c) # Demo client code -SRC_C += $(wildcard $(WOLFHSM_DEMO_CLIENT_DIR)/*.c) +SRC_C += $(wildcard $(WOLFHSM_DEMO_CLIENT_DIR)/*.c) ## Automated processing below diff --git a/examples/posix/tcp/wh_client_tcp/user_settings.h b/examples/posix/wh_posix_client/user_settings.h similarity index 77% rename from examples/posix/tcp/wh_client_tcp/user_settings.h rename to examples/posix/wh_posix_client/user_settings.h index 6bb8fed5..1c10c897 100644 --- a/examples/posix/tcp/wh_client_tcp/user_settings.h +++ b/examples/posix/wh_posix_client/user_settings.h @@ -8,8 +8,8 @@ #define HAVE_ANONYMOUS_INLINE_AGGREGATES 1 /* Optional if debugging cryptocb's */ #if 0 - #define DEBUG_CRYPTOCB - #define DEBUG_CRYPTOCB_VERBOSE +#define DEBUG_CRYPTOCB +#define DEBUG_CRYPTOCB_VERBOSE #endif /* Key DER export/import support */ @@ -20,15 +20,15 @@ /* C90 compatibility, which doesn't support inline keyword */ #define NO_INLINE /* Suppresses warning in evp.c */ -#define WOLFSSL_IGNORE_FILE_WARN +#define WOLFSSL_IGNORE_FILE_WARN /* Either NO_HARDEN or set resistance and blinding */ #if 0 #define WC_NO_HARDEN #else - #define TFM_TIMING_RESISTANT - #define ECC_TIMING_RESISTANT - #define WC_RSA_BLINDING +#define TFM_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT +#define WC_RSA_BLINDING #endif @@ -47,6 +47,12 @@ #define NO_MAIN_DRIVER #define BENCH_EMBEDDED +#ifdef WOLFHSM_CFG_DMA +#undef WOLFSSL_STATIC_MEMORY +#define WOLFSSL_STATIC_MEMORY +#define WOLFSSL_STATIC_MEMORY_TEST_SZ 100000 +#endif + /* Include to ensure clock_gettime is declared for benchmark.c */ #include /* Include to support strcasecmp with POSIX build */ diff --git a/examples/posix/wh_posix_client/wh_posix_client.c b/examples/posix/wh_posix_client/wh_posix_client.c new file mode 100644 index 00000000..d9ba435b --- /dev/null +++ b/examples/posix/wh_posix_client/wh_posix_client.c @@ -0,0 +1,211 @@ +/* + * wolfHSM Client POSIX Example + */ + +#include +#include /* For printf */ +#include /* For memset, memcpy */ +#include /* for read */ +#include /* For nanosleep */ + +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_comm.h" +#include "wolfhsm/wh_utils.h" +#include "wolfhsm/wh_message.h" +#include "wolfhsm/wh_client.h" +#include "wolfhsm/wh_client_crypto.h" +#include "port/posix/posix_transport_tcp.h" +#include "port/posix/posix_transport_shm.h" + +#include "examples/demo/client/wh_demo_client_all.h" +#include "wh_posix_cfg.h" +#include "wh_posix_client_cfg.h" + +#ifndef WOLFHSM_CFG_NO_CRYPTO +/* included to print out the version of wolfSSL linked with */ +#include "wolfssl/version.h" +#endif + +/** Local declarations */ +static void _sleepMs(long milliseconds); +static int wh_ClientTask(void* cf, const char* type, int test); + + +static void _sleepMs(long milliseconds) +{ + struct timespec req; + req.tv_sec = milliseconds / 1000; + req.tv_nsec = (milliseconds % 1000) * 1000000; + nanosleep(&req, NULL); +} + +enum { + REPEAT_COUNT = 20, + REQ_SIZE = 32, + RESP_SIZE = 64, + ONE_MS = 1, +}; + +#define WH_SERVER_TCP_IPSTRING "127.0.0.1" +#define WH_SERVER_TCP_PORT 23456 +#define WH_CLIENT_ID 12 + +static int wh_ClientTask(void* cf, const char* type, int test) +{ + whClientConfig* config = (whClientConfig*)cf; + int ret = 0; + whClientContext client[1]; + int counter = 1; + + uint8_t tx_req[REQ_SIZE] = {0}; + uint16_t tx_req_len = 0; + + uint8_t rx_resp[RESP_SIZE] = {0}; + uint16_t rx_resp_len = 0; + + if (config == NULL) { + return -1; + } + + ret = wh_Client_Init(client, config); + + if (strcmp(type, "dma") == 0) { +#ifdef WOLFSSL_STATIC_MEMORY + printf("Setting up DMA heap with static memory buckets\n"); + + ret = wh_PosixClient_ExampleSetupDmaMemory(client, config); + if (ret != 0) { + printf("Failed to setup DMA heap\n"); + return -1; + } +#else + return -1; +#endif + } + + printf("Client connecting to server...\n"); + if (test) { + return wh_DemoClient_All(client); + } + + if (ret != 0) { + perror("Init error:"); + return -1; + } + + for (counter = 0; counter < REPEAT_COUNT; counter++) { + sprintf((char*)tx_req, "Request:%u", counter); + tx_req_len = strlen((char*)tx_req); + do { + ret = wh_Client_EchoRequest(client, tx_req_len, tx_req); + if (ret != WH_ERROR_NOTREADY) { + if (ret != 0) { + printf("wh_Client_EchoRequest failed with ret=%d\n", ret); + } + } + _sleepMs(ONE_MS); + } while (ret == WH_ERROR_NOTREADY); + + if (ret != 0) { + printf("Client had failure. Exiting\n"); + break; + } + + rx_resp_len = 0; + memset(rx_resp, 0, sizeof(rx_resp)); + + do { + ret = wh_Client_EchoResponse(client, &rx_resp_len, rx_resp); + _sleepMs(ONE_MS); + } while (ret == WH_ERROR_NOTREADY); + + if (ret != 0) { + printf("Client had failure. Exiting\n"); + break; + } + } + + /* Context 1: Client Local Crypto */ + WC_RNG rng[1]; + uint8_t buffer[128] = {0}; + wc_InitRng_ex(rng, NULL, INVALID_DEVID); + wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); + wc_FreeRng(rng); + wh_Utils_Hexdump("Context 1: Client Local RNG:\n", buffer, sizeof(buffer)); + + /* Context 2: Client Remote Crypto */ + memset(buffer, 0, sizeof(buffer)); + wc_InitRng_ex(rng, NULL, WH_DEV_ID); + wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); + wc_FreeRng(rng); + wh_Utils_Hexdump("Context 2: Client Remote RNG:\n", buffer, sizeof(buffer)); + + + (void)wh_Client_CommClose(client); + (void)wh_Client_Cleanup(client); + printf("Client disconnected\n"); + return ret; +} + +void Usage(const char* exeName) +{ + printf("Usage: %s --type --test\n", exeName); + printf("Example: %s --type tcp\n", exeName); + printf("type: tcp (default), shm\n"); +} + +int main(int argc, char** argv) +{ + const char* type = "tcp"; + int test = 0; /* flag if running wolfcrypt test */ + whClientConfig c_conf[1]; + int i; + + (void)argc; + (void)argv; + + memset(c_conf, 0, sizeof(whClientConfig)); + printf("Example wolfHSM POSIX client "); +#ifndef WOLFHSM_CFG_NO_CRYPTO + printf("built with wolfSSL version %s\n", LIBWOLFSSL_VERSION_STRING); +#else + printf("built with WOLFHSM_CFG_NO_CRYPTO\n"); +#endif + + /* Parse command-line arguments */ + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--type") == 0 && i + 1 < argc) { + type = argv[++i]; + } + else if (strcmp(argv[i], "--test") == 0) { + test = 1; + } + else { + printf("Invalid argument: %s\n", argv[i]); + Usage(argv[0]); + return -1; + } + } + + if (strcmp(type, "tcp") == 0) { + printf("Using TCP transport\n"); + wh_PosixClient_ExampleTcpConfig(c_conf); + } + else if (strcmp(type, "shm") == 0) { + printf("Using shared memory transport\n"); + wh_PosixClient_ExampleShmConfig(c_conf); + } +#ifdef WOLFSSL_STATIC_MEMORY + else if (strcmp(type, "dma") == 0) { + printf("Using DMA with shared memory transport\n"); + wh_PosixClient_ExampleShmDmaConfig(c_conf); + } +#endif + else { + printf("Invalid client type: %s\n", type); + Usage(argv[0]); + return -1; + } + + return wh_ClientTask(c_conf, type, test); +} diff --git a/examples/posix/wh_posix_client/wh_posix_client_cfg.c b/examples/posix/wh_posix_client/wh_posix_client_cfg.c new file mode 100644 index 00000000..bd594214 --- /dev/null +++ b/examples/posix/wh_posix_client/wh_posix_client_cfg.c @@ -0,0 +1,147 @@ +/* + * wolfHSM Client POSIX Example + */ + +#include "wh_posix_cfg.h" +#include "wh_posix_client_cfg.h" + +#include "wolfhsm/wh_client.h" +#include "wolfhsm/wh_error.h" + +#include "port/posix/posix_transport_shm.h" +#include "port/posix/posix_transport_tcp.h" + +#include + +posixTransportShmClientContext tccShm; +posixTransportTcpClientContext tccTcp; + +posixTransportShmConfig shmConfig; +posixTransportTcpConfig tcpConfig; + +whCommClientConfig c_comm; + +whTransportClientCb shmCb = POSIX_TRANSPORT_SHM_CLIENT_CB; +whTransportClientCb tcpCb = PTT_CLIENT_CB; + +#ifdef WOLFSSL_STATIC_MEMORY +whTransportClientCb dmaCb = POSIX_TRANSPORT_SHM_CLIENT_CB; +whClientDmaConfig dmaConfig; + +const word32 sizeList[] = { + WH_POSIX_STATIC_MEM_SIZE_1, WH_POSIX_STATIC_MEM_SIZE_2, + WH_POSIX_STATIC_MEM_SIZE_3, WH_POSIX_STATIC_MEM_SIZE_4, + WH_POSIX_STATIC_MEM_SIZE_5, WH_POSIX_STATIC_MEM_SIZE_6, + WH_POSIX_STATIC_MEM_SIZE_7, WH_POSIX_STATIC_MEM_SIZE_8, + WH_POSIX_STATIC_MEM_SIZE_9}; +const word32 distList[] = { + WH_POSIX_STATIC_MEM_DIST_1, WH_POSIX_STATIC_MEM_DIST_2, + WH_POSIX_STATIC_MEM_DIST_3, WH_POSIX_STATIC_MEM_DIST_4, + WH_POSIX_STATIC_MEM_DIST_5, WH_POSIX_STATIC_MEM_DIST_6, + WH_POSIX_STATIC_MEM_DIST_7, WH_POSIX_STATIC_MEM_DIST_8, + WH_POSIX_STATIC_MEM_DIST_9}; + + +int wh_PosixClient_ExampleSetupDmaMemory(void* ctx, void* conf) +{ + void* dma; + size_t dmaSz; + WOLFSSL_HEAP_HINT* hint = NULL; + int ret; + whClientConfig* c_conf = (whClientConfig*)conf; + posixTransportShmContext* shmCtx; + + shmCtx = (posixTransportShmContext*)c_conf->comm->transport_context; + ret = posixTransportShm_GetDma(shmCtx, &dma, &dmaSz); + if (ret != 0) { + printf("Failed to get DMA\n"); + return -1; + } + + ret = wc_LoadStaticMemory_ex(&hint, WH_POSIX_STATIC_MEM_LIST_SIZE, sizeList, + distList, dma, dmaSz, 0, 0); + if (ret != 0) { + printf("Failed to load static memory\n"); + return -1; + } + + ret = posixTransportShm_SetDmaHeap(shmCtx, (void*)hint); + if (ret != 0) { + printf("Failed to set heap\n"); + return -1; + } + + (void)ctx; + return 0; +} + + +/* client configuration setup example for transport */ +int wh_PosixClient_ExampleShmDmaConfig(void* conf) +{ + whClientConfig* c_conf = (whClientConfig*)conf; + + memset(&tccShm, 0, sizeof(posixTransportShmClientContext)); + memset(&c_comm, 0, sizeof(whCommClientConfig)); + + shmConfig.name = WH_POSIX_SHARED_MEMORY_NAME; + shmConfig.req_size = WH_POSIX_REQ_SIZE; + shmConfig.resp_size = WH_POSIX_RESP_SIZE; + shmConfig.dma_size = WH_POSIX_DMA_SIZE; + + dmaConfig.cb = posixTransportShm_ClientStaticMemDmaCallback; + dmaConfig.dmaAddrAllowList = NULL; + + c_comm.transport_cb = &dmaCb; + c_comm.transport_context = (void*)&tccShm; + c_comm.transport_config = (void*)&shmConfig; + c_comm.client_id = WH_POSIX_CLIENT_ID; + + c_conf->dmaConfig = &dmaConfig; + c_conf->comm = &c_comm; + + return WH_ERROR_OK; +} +#endif + +/* client configuration setup example for transport */ +int wh_PosixClient_ExampleTcpConfig(void* conf) +{ + whClientConfig* c_conf = (whClientConfig*)conf; + + memset(&tccTcp, 0, sizeof(posixTransportTcpClientContext)); + + tcpConfig.server_ip_string = WH_POSIX_SERVER_TCP_IPSTRING; + tcpConfig.server_port = WH_POSIX_SERVER_TCP_PORT; + + c_comm.transport_cb = &tcpCb; + c_comm.transport_context = (void*)&tccTcp; + c_comm.transport_config = (void*)&tcpConfig; + c_comm.client_id = WH_POSIX_CLIENT_ID; + c_conf->comm = &c_comm; + + return WH_ERROR_OK; +} + + +/* client configuration setup example for transport */ +int wh_PosixClient_ExampleShmConfig(void* conf) +{ + whClientConfig* c_conf = (whClientConfig*)conf; + + memset(&tccShm, 0, sizeof(posixTransportShmClientContext)); + memset(&c_comm, 0, sizeof(whCommClientConfig)); + + shmConfig.name = WH_POSIX_SHARED_MEMORY_NAME; + shmConfig.req_size = WH_POSIX_REQ_SIZE; + shmConfig.resp_size = WH_POSIX_RESP_SIZE; + shmConfig.dma_size = WH_POSIX_DMA_SIZE; + + c_comm.transport_cb = &shmCb; + c_comm.transport_context = (void*)&tccShm; + c_comm.transport_config = (void*)&shmConfig; + c_comm.client_id = WH_POSIX_CLIENT_ID; + c_conf->comm = &c_comm; + + return WH_ERROR_OK; +} diff --git a/examples/posix/wh_posix_client/wh_posix_client_cfg.h b/examples/posix/wh_posix_client/wh_posix_client_cfg.h new file mode 100644 index 00000000..5931150c --- /dev/null +++ b/examples/posix/wh_posix_client/wh_posix_client_cfg.h @@ -0,0 +1,8 @@ +#ifndef WH_POSIX_CLIENT_CFG_H +#define WH_POSIX_CLIENT_CFG_H + +int wh_PosixClient_ExampleShmDmaConfig(void* c_conf); +int wh_PosixClient_ExampleShmConfig(void* c_conf); +int wh_PosixClient_ExampleTcpConfig(void* c_conf); +int wh_PosixClient_ExampleSetupDmaMemory(void* ctx, void* c_conf); +#endif /* WH_POSIX_CLIENT_CFG_H */ \ No newline at end of file diff --git a/examples/posix/tcp/wh_client_tcp/wolfhsm_cfg.h b/examples/posix/wh_posix_client/wolfhsm_cfg.h similarity index 100% rename from examples/posix/tcp/wh_client_tcp/wolfhsm_cfg.h rename to examples/posix/wh_posix_client/wolfhsm_cfg.h diff --git a/examples/posix/tcp/wh_server_tcp/Makefile b/examples/posix/wh_posix_server/Makefile similarity index 94% rename from examples/posix/tcp/wh_server_tcp/Makefile rename to examples/posix/wh_posix_server/Makefile index aa34be94..4b878721 100644 --- a/examples/posix/tcp/wh_server_tcp/Makefile +++ b/examples/posix/wh_posix_server/Makefile @@ -2,15 +2,16 @@ ## Project name # Sets output filenames -BIN = wh_server_tcp +BIN = wh_posix_server ## Important directories # Base directory for additional project files PROJECT_DIR ?= . CONFIG_DIR ?= $(PROJECT_DIR)/config +SHARED_CONFIG_DIR ?= $(PROJECT_DIR)/../ # wolfSSL and wolfHSM directories -WOLFSSL_DIR ?= ../../../../../wolfssl -WOLFHSM_DIR ?= ../../../../ +WOLFSSL_DIR ?= ../../../../wolfssl +WOLFHSM_DIR ?= ../../../ WOLFHSM_PORT_DIR ?= $(WOLFHSM_DIR)/port/posix # Output directory for build files @@ -19,6 +20,7 @@ BUILD_DIR ?= $(PROJECT_DIR)/Build # Includes INC = -I$(PROJECT_DIR) \ -I$(CONFIG_DIR) \ + -I$(SHARED_CONFIG_DIR) \ -I$(WOLFSSL_DIR) \ -I$(WOLFHSM_DIR) \ -I$(WOLFHSM_PORT_DIR) @@ -69,6 +71,10 @@ ifeq ($(SHE),1) CFLAGS += -DWOLFHSM_CFG_SHE_EXTENSION endif +ifeq ($(DMA),1) +CFLAGS += -DWOLFHSM_CFG_DMA +endif + ## Source files # Assembly source files SRC_ASM += @@ -87,7 +93,6 @@ SRC_C += $(wildcard $(WOLFHSM_PORT_DIR)/*.c) # Project SRC_C += $(wildcard $(PROJECT_DIR)/*.c) - ## Automated processing below FILENAMES_C = $(notdir $(SRC_C)) diff --git a/examples/posix/tcp/wh_server_tcp/user_settings.h b/examples/posix/wh_posix_server/user_settings.h similarity index 93% rename from examples/posix/tcp/wh_server_tcp/user_settings.h rename to examples/posix/wh_posix_server/user_settings.h index c27dc438..45bf0167 100644 --- a/examples/posix/tcp/wh_server_tcp/user_settings.h +++ b/examples/posix/wh_posix_server/user_settings.h @@ -177,16 +177,20 @@ extern "C" { /* ------------------------------------------------------------------------- */ #if 0 /* Static memory requires fast math or SP math with no malloc */ - #define WOLFSSL_STATIC_MEMORY +#define WOLFSSL_STATIC_MEMORY /* Disable fallback malloc/free */ - #define WOLFSSL_NO_MALLOC - #if 1 - #define WOLFSSL_MALLOC_CHECK /* trap malloc failure */ - #endif +#define WOLFSSL_NO_MALLOC +#if 1 +#define WOLFSSL_MALLOC_CHECK /* trap malloc failure */ +#endif /* optional malloc check */ +#endif /* optional static memory */ + +#ifdef WOLFHSM_CFG_DMA +#undef WOLFSSL_STATIC_MEMORY +#define WOLFSSL_STATIC_MEMORY #endif - #ifdef __cplusplus } #endif diff --git a/examples/posix/wh_posix_server/wh_posix_server.c b/examples/posix/wh_posix_server/wh_posix_server.c new file mode 100644 index 00000000..34ce8226 --- /dev/null +++ b/examples/posix/wh_posix_server/wh_posix_server.c @@ -0,0 +1,407 @@ +/* + * Example server app using POSIX transport + */ + +#include +#include /* For printf */ +#include /* For atoi */ +#include /* For memset, memcpy, strcmp */ +#include +#include +#include +#include /* for read/close */ +#include /* For nanosleep */ +#include +#include + +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_comm.h" +#include "wolfhsm/wh_common.h" +#include "wolfhsm/wh_utils.h" +#include "wolfhsm/wh_message.h" +#include "wolfhsm/wh_server.h" +#include "wolfhsm/wh_server_keystore.h" + +#ifndef WOLFHSM_CFG_NO_CRYPTO +/* included to print out the version of wolfSSL linked with */ +#include "wolfssl/version.h" +#endif + +#include "wh_posix_cfg.h" +#include "wh_posix_server_cfg.h" + +/** Local declarations */ +static int wh_ServerTask(void* cf, const char* keyFilePath, int keyId, + int clientId); + +static void _sleepMs(long milliseconds); +static int _hardwareCryptoCb(int devId, struct wc_CryptoInfo* info, void* ctx); + +static void _sleepMs(long milliseconds) +{ + struct timespec req; + req.tv_sec = milliseconds / 1000; + req.tv_nsec = (milliseconds % 1000) * 1000000; + nanosleep(&req, NULL); +} + +enum { + ONE_MS = 1, +}; + +#define WH_SERVER_TCP_IPSTRING "127.0.0.1" +#define WH_SERVER_TCP_PORT 23456 +#define WH_SERVER_ID 57 +const char* type = "tcp"; /* default to tcp type */ + +static int loadAndStoreKeys(whServerContext* server, whKeyId* outKeyId, + const char* keyFilePath, int keyId, int clientId) +{ + int ret; + int keyFd; + int keySz; + char keyLabel[] = "baby's first key"; + uint8_t keyBuf[4096]; + whNvmMetadata meta = {0}; + + /* open the key file */ + ret = keyFd = open(keyFilePath, O_RDONLY, 0); + if (ret < 0) { + printf("Failed to open %s %d\n", keyFilePath, ret); + return ret; + } + + /* read the key to local buffer */ + ret = keySz = read(keyFd, keyBuf, sizeof(keyBuf)); + if (ret < 0) { + printf("Failed to read %s %d\n", keyFilePath, ret); + close(keyFd); + return ret; + } + ret = 0; + close(keyFd); + + printf( + "Loading key from %s (size=%d) with keyId=0x%02X and clientId=0x%01X\n", + keyFilePath, keySz, keyId, clientId); + + /* cache the key in the HSM, get HSM assigned keyId */ + /* set the metadata fields */ + meta.id = WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, clientId, keyId); + meta.flags = 0; + meta.len = keySz; + memcpy(meta.label, keyLabel, strlen(keyLabel)); + + /* Get HSM assigned keyId if not set */ + if (keyId == WH_KEYID_ERASED) { + ret = wh_Server_KeystoreGetUniqueId(server, &meta.id); + printf("got unique ID = 0x%02X\n", meta.id & WH_KEYID_MASK); + } + printf( + "key NVM ID = 0x%04X\n\ttype=0x%01X\n\tuser=0x%01X\n\tkeyId=0x%02X\n", + meta.id, WH_KEYID_TYPE(meta.id), WH_KEYID_USER(meta.id), + WH_KEYID_ID(meta.id)); + + if (ret == 0) { + ret = wh_Server_KeystoreCacheKey(server, &meta, keyBuf); + if (ret != 0) { + printf("Failed to wh_Server_KeystoreCacheKey, ret=%d\n", ret); + return ret; + } + } + else { + printf("Failed to wh_Server_KeystoreGetUniqueId, ret=%d\n", ret); + return ret; + } + + *outKeyId = meta.id; + return ret; +} + + +static int wh_ServerTask(void* cf, const char* keyFilePath, int keyId, + int clientId) +{ + whServerContext server[1]; + whServerConfig* config = (whServerConfig*)cf; + int ret = 0; + whCommConnected last_state = WH_COMM_DISCONNECTED; + whKeyId loadedKeyId; + + if (config == NULL) { + return -1; + } + + ret = wh_Server_Init(server, config); + + /* Load keys into cache if file path is provided */ + if (keyFilePath != NULL) { + ret = loadAndStoreKeys(server, &loadedKeyId, keyFilePath, keyId, + clientId); + if (ret != 0) { + printf("server failed to load key, ret=%d\n", ret); + (void)wh_Server_Cleanup(server); + return ret; + } + } + + if (ret == 0) { + printf("Waiting for connection...\n"); + if (strcmp(type, "shm") == 0 || strcmp(type, "dma") == 0) { + /* Shared memory assumes connected once memory is setup */ + wh_Server_SetConnected(server, WH_COMM_CONNECTED); + } + + while (1) { + ret = wh_Server_HandleRequestMessage(server); + if (ret == WH_ERROR_NOTREADY) { + _sleepMs(ONE_MS); + } + else if (ret != WH_ERROR_OK) { + printf("Failed to wh_Server_HandleRequestMessage: %d\n", ret); + break; + } + else { + whCommConnected current_state; + int get_conn_result = + wh_Server_GetConnected(server, ¤t_state); + if (get_conn_result == WH_ERROR_OK) { + if (current_state == WH_COMM_CONNECTED && + last_state == WH_COMM_DISCONNECTED) { + printf("Server connected\n"); + last_state = WH_COMM_CONNECTED; + } + else if (current_state == WH_COMM_DISCONNECTED && + last_state == WH_COMM_CONNECTED) { + printf("Server disconnected\n"); + last_state = WH_COMM_DISCONNECTED; + + /* POSIX TCP transport requires server to be + * re-initialized in order to reconnect */ + + (void)wh_Server_Cleanup(server); + + /* Reinitialize the server */ + ret = wh_Server_Init(server, config); + if (ret != 0) { + printf("Failed to reinitialize server: %d\n", ret); + break; + } + + if (ret == WH_ERROR_OK && (strcmp(type, "shm") == 0 || + strcmp(type, "dma") == 0)) { + /* Shared memory assumes connected once memory is + * setup */ + wh_Server_SetConnected(server, WH_COMM_CONNECTED); + } + + /* Reload keys into cache if file path was provided */ + if (keyFilePath != NULL) { + ret = + loadAndStoreKeys(server, &loadedKeyId, + keyFilePath, keyId, clientId); + if (ret != 0) { + printf("server failed to load key, ret=%d\n", + ret); + break; + } + } + } + } + else { + printf("Failed to get connection state: %d\n", + get_conn_result); + } + } + } + } + return ret; +} + +static int _hardwareCryptoCb(int devId, struct wc_CryptoInfo* info, void* ctx) +{ + (void)devId; + (void)ctx; + + /* Default response */ + int ret = CRYPTOCB_UNAVAILABLE; + switch (info->algo_type) { + case WC_ALGO_TYPE_RNG: { + /*printf("Hardware Crypto Callback: RNG operation requested\n");*/ + /* Extract info parameters */ + uint8_t* out = info->rng.out; + uint32_t size = info->rng.sz; + + /* III Not random, just simple counter */ + static uint16_t my_counter = 1; + if (my_counter > 4096) { + /* Only allow 4096 bytes to be generated */ + ret = CRYPTOCB_UNAVAILABLE; + } + else { + uint32_t i = 0; + for (i = 0; i < size; i++) { + out[i] = (uint8_t)my_counter++; + } + ret = 0; + } + break; + } + default: + /*printf("Hardware Crypto Callback: Unsupported algorithm type\n"); + */ + ret = CRYPTOCB_UNAVAILABLE; + } + return ret; +} + +static void Usage(const char* exeName) +{ + printf("Usage: %s --key --id --client " + "--nvminit --type \n", + exeName); + printf("Example: %s --key key.bin --id 123 --client 456 " + "--nvminit nvm_init.txt --type tcp\n", + exeName); + printf("type: tcp (default), shm, dma\n"); +} + + +int main(int argc, char** argv) +{ + int rc = 0; + const char* keyFilePath = NULL; + const char* nvmInitFilePath = NULL; + int keyId = WH_KEYID_ERASED; /* Default key ID if none provided */ + int clientId = 12; /* Default client ID if none provided */ + uint8_t memory[WH_POSIX_FLASH_RAM_SIZE] = {0}; + whServerConfig s_conf[1]; + + printf("Example wolfHSM POSIX server "); +#ifndef WOLFHSM_CFG_NO_CRYPTO + printf("built with wolfSSL version %s\n", LIBWOLFSSL_VERSION_STRING); +#else + printf("built with WOLFHSM_CFG_NO_CRYPTO\n"); +#endif + + /* Parse command-line arguments */ + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--key") == 0 && i + 1 < argc) { + keyFilePath = argv[++i]; + } + else if (strcmp(argv[i], "--id") == 0 && i + 1 < argc) { + keyId = atoi(argv[++i]); + } + else if (strcmp(argv[i], "--client") == 0 && i + 1 < argc) { + clientId = atoi(argv[++i]); + } + else if (strcmp(argv[i], "--nvminit") == 0 && i + 1 < argc) { + nvmInitFilePath = argv[++i]; + } + else if (strcmp(argv[i], "--type") == 0 && i + 1 < argc) { + type = argv[++i]; + } + else { + printf("Invalid argument: %s\n", argv[i]); + Usage(argv[0]); + return -1; + } + } + + /* Server configuration/context */ + memset(s_conf, 0, sizeof(whServerConfig)); + if (strcmp(type, "tcp") == 0) { + printf("Using TCP transport\n"); + wh_PosixServer_ExampleTcpConfig(s_conf); + } + else if (strcmp(type, "shm") == 0) { + printf("Using shared memory transport\n"); + wh_PosixServer_ExampleShmConfig(s_conf); + } +#ifdef WOLFSSL_STATIC_MEMORY + else if (strcmp(type, "dma") == 0) { + printf("Using DMA with shared memory transport\n"); + wh_PosixServer_ExampleShmDmaConfig(s_conf); + } +#endif + else { + printf("Invalid server type: %s\n", type); + return -1; + } + + /* RamSim Flash state and configuration */ + rc = wh_PosixServer_ExampleRamSimConfig(s_conf, memory); + if (rc != WH_ERROR_OK) { + printf("Failed to initialize RAMSim: %d\n", rc); + return rc; + } + + /* NVM Flash Configuration using RamSim HAL Flash */ + rc = wh_PosixServer_ExampleNvmConfig(s_conf, nvmInitFilePath); + if (rc != WH_ERROR_OK) { + printf("Failed to initialize NVM: %d\n", rc); + return rc; + } + + /* Crypto context */ + whServerCryptoContext crypto[1] = {{ + .devId = INVALID_DEVID, + }}; + +#if defined(WOLFHSM_CFG_SHE_EXTENSION) + whServerSheContext she[1] = {{0}}; +#endif + + + s_conf->crypto = crypto; + s_conf->devId = INVALID_DEVID; +#if defined(WOLFHSM_CFG_SHE_EXTENSION) + s_conf->she = she; +#endif + + /* Initialize crypto library and hardware */ + wolfCrypt_Init(); + + /* Context 3: Server Software Crypto */ + WC_RNG rng[1]; + uint8_t buffer[128] = {0}; + wc_InitRng_ex(rng, NULL, INVALID_DEVID); + wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); + wc_FreeRng(rng); + wh_Utils_Hexdump("Context 3: Server SW RNG:\n", buffer, sizeof(buffer)); + +/* Context 4: Server Hardware Crypto */ +#define HW_DEV_ID 100 + memset(buffer, 0, sizeof(buffer)); + wc_CryptoCb_RegisterDevice(HW_DEV_ID, _hardwareCryptoCb, NULL); + wc_InitRng_ex(rng, NULL, HW_DEV_ID); + wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); + wc_FreeRng(rng); + wh_Utils_Hexdump("Context 4: Server HW RNG:\n", buffer, sizeof(buffer)); + + /* Context 5: Set default server crypto to use cryptocb */ + crypto->devId = HW_DEV_ID; + printf("Context 5: Setting up default server crypto with devId=%d\n", + crypto->devId); + + rc = wc_InitRng_ex(crypto->rng, NULL, crypto->devId); + if (rc != 0) { + printf("Failed to wc_InitRng_ex: %d\n", rc); + return rc; + } + + rc = wh_ServerTask(s_conf, keyFilePath, keyId, clientId); + + rc = wc_FreeRng(crypto->rng); + if (rc != 0) { + printf("Failed to wc_FreeRng: %d\n", rc); + return rc; + } + rc = wolfCrypt_Cleanup(); + if (rc != 0) { + printf("Failed to wolfCrypt_Cleanup: %d\n", rc); + return rc; + } + + return rc; +} diff --git a/examples/posix/tcp/wh_server_tcp/wh_server_tcp.c b/examples/posix/wh_posix_server/wh_posix_server_cfg.c similarity index 50% rename from examples/posix/tcp/wh_server_tcp/wh_server_tcp.c rename to examples/posix/wh_posix_server/wh_posix_server_cfg.c index 26ae2acf..c694422d 100644 --- a/examples/posix/tcp/wh_server_tcp/wh_server_tcp.c +++ b/examples/posix/wh_posix_server/wh_posix_server_cfg.c @@ -1,50 +1,131 @@ /* - * Example server app using POSIX TCP transport + * Example server app using POSIX transport */ -#include -#include /* For printf */ -#include /* For atoi */ -#include /* For memset, memcpy, strcmp */ -#include -#include -#include -#include /* for read/close */ -#include /* For nanosleep */ -#include -#include +#include "wh_posix_cfg.h" +#include "wh_posix_server_cfg.h" -#include "wolfhsm/wh_error.h" -#include "wolfhsm/wh_comm.h" -#include "wolfhsm/wh_common.h" -#include "wolfhsm/wh_utils.h" -#include "wolfhsm/wh_message.h" #include "wolfhsm/wh_server.h" -#include "wolfhsm/wh_server_keystore.h" +#include "wolfhsm/wh_error.h" #include "wolfhsm/wh_nvm.h" #include "wolfhsm/wh_nvm_flash.h" #include "wolfhsm/wh_flash_ramsim.h" +#include "port/posix/posix_transport_shm.h" #include "port/posix/posix_transport_tcp.h" -/** Local declarations */ -static int wh_ServerTask(void* cf, const char* keyFilePath, int keyId, - int clientId); +posixTransportShmConfig shmConfig; +posixTransportTcpConfig tcpConfig; + +whCommServerConfig s_comm; + +whTransportServerCb tcpCb = PTT_SERVER_CB; +whTransportServerCb shmCb = POSIX_TRANSPORT_SHM_SERVER_CB; +posixTransportShmServerContext tscShm; +posixTransportTcpServerContext tscTcp; + +#ifdef WOLFSSL_STATIC_MEMORY +whTransportServerCb dmaCb = POSIX_TRANSPORT_SHM_SERVER_CB; +posixTransportShmServerContext tscDma; +whServerDmaConfig dmaConfig; + +/* Server configuration setup example for transport + * Does not setup flash, nvm, crypto, she, etc. */ +int wh_PosixServer_ExampleShmDmaConfig(void* conf) +{ + whServerConfig* s_conf = (whServerConfig*)conf; -static void _sleepMs(long milliseconds); -static int _hardwareCryptoCb(int devId, struct wc_CryptoInfo* info, void* ctx); + memset(&tscDma, 0, sizeof(posixTransportShmServerContext)); + memset(&s_comm, 0, sizeof(whCommServerConfig)); -/* Macros for maximum client ID and key ID */ -#define MAX_CLIENT_ID 255 -#define MAX_KEY_ID UINT16_MAX + shmConfig.name = WH_POSIX_SHARED_MEMORY_NAME; + shmConfig.req_size = WH_POSIX_REQ_SIZE; + shmConfig.resp_size = WH_POSIX_RESP_SIZE; + shmConfig.dma_size = WH_POSIX_DMA_SIZE; -/* Macros for maximum file path length (Linux PATH_MAX is a good reference) */ -#ifndef PATH_MAX -#define PATH_MAX 4096 + dmaConfig.cb = posixTransportShm_ServerStaticMemDmaCallback; + dmaConfig.dmaAddrAllowList = NULL; + + s_comm.transport_cb = &dmaCb; + s_comm.transport_context = (void*)&tscDma; + s_comm.transport_config = (void*)&shmConfig; + s_comm.server_id = WH_POSIX_SERVER_ID; + + s_conf->dmaConfig = &dmaConfig; + s_conf->comm_config = &s_comm; + + return WH_ERROR_OK; +} #endif -/* Parameterize MAX_LINE_LENGTH by 512 bytes + MAX_FILE_PATH_LENGTH */ -#define MAX_LINE_LENGTH (512 + PATH_MAX) + +/* Server configuration setup example for transport + * Does not setup flash, nvm, crypto, she, etc. */ +int wh_PosixServer_ExampleShmConfig(void* conf) +{ + whServerConfig* s_conf = (whServerConfig*)conf; + + memset(&tscShm, 0, sizeof(posixTransportShmServerContext)); + memset(&s_comm, 0, sizeof(whCommServerConfig)); + + shmConfig.name = WH_POSIX_SHARED_MEMORY_NAME; + shmConfig.req_size = WH_POSIX_REQ_SIZE; + shmConfig.resp_size = WH_POSIX_RESP_SIZE; + shmConfig.dma_size = WH_POSIX_DMA_SIZE; + + s_comm.transport_cb = &shmCb; + s_comm.transport_context = (void*)&tscShm; + s_comm.transport_config = (void*)&shmConfig; + s_comm.server_id = WH_POSIX_SERVER_ID; + + s_conf->comm_config = &s_comm; + + return WH_ERROR_OK; +} + + +/* Server configuration setup example for transport + * Does not setup flash, nvm, crypto, she, etc. */ +int wh_PosixServer_ExampleTcpConfig(void* conf) +{ + whServerConfig* s_conf = (whServerConfig*)conf; + + /* Server configuration/context */ + memset(&tscTcp, 0, sizeof(posixTransportTcpServerContext)); + + tcpConfig.server_ip_string = WH_POSIX_SERVER_TCP_IPSTRING; + tcpConfig.server_port = WH_POSIX_SERVER_TCP_PORT; + + s_comm.transport_cb = &tcpCb; + s_comm.transport_context = (void*)&tscTcp; + s_comm.transport_config = (void*)&tcpConfig; + s_comm.server_id = WH_POSIX_SERVER_ID; + + s_conf->comm_config = &s_comm; + + return WH_ERROR_OK; +} + +static const whFlashCb fcb = WH_FLASH_RAMSIM_CB; +static whFlashRamsimCfg fc_conf; + +int wh_PosixServer_ExampleRamSimConfig(void* conf, uint8_t* memory) +{ + whServerConfig* s_conf = (whServerConfig*)conf; + + fc_conf.size = WH_POSIX_FLASH_RAM_SIZE, + fc_conf.sectorSize = WH_POSIX_FLASH_RAM_SIZE / 2, fc_conf.pageSize = 8; + fc_conf.erasedByte = (uint8_t)0; + fc_conf.memory = memory; + + (void)s_conf; + return WH_ERROR_OK; +} + + +/*******************************************************/ +/* NVM related functions */ +/*******************************************************/ /* Structure representing an entry in the linked list */ typedef struct Entry { @@ -76,22 +157,6 @@ static int parseInteger(const char* str, uint32_t maxValue, uint32_t* result); static void parseNvmInitFile(const char* filePath); static int initializeNvm(whNvmContext* nvmContext, const char* nvmInitFilePath); -static void _sleepMs(long milliseconds) -{ - struct timespec req; - req.tv_sec = milliseconds / 1000; - req.tv_nsec = (milliseconds % 1000) * 1000000; - nanosleep(&req, NULL); -} - -enum { - ONE_MS = 1, - FLASH_RAM_SIZE = 1024 * 1024, -}; - -#define WH_SERVER_TCP_IPSTRING "127.0.0.1" -#define WH_SERVER_TCP_PORT 23456 -#define WH_SERVER_ID 57 /* Creates a new entry in the linked list based on the provided parameters */ static Entry* createEntry(uint8_t clientId, uint16_t id, uint16_t access, @@ -411,282 +476,29 @@ static int initializeNvm(whNvmContext* nvmContext, const char* nvmInitFilePath) return 0; } -static int loadAndStoreKeys(whServerContext* server, whKeyId* outKeyId, - const char* keyFilePath, int keyId, int clientId) -{ - int ret; - int keyFd; - int keySz; - char keyLabel[] = "baby's first key"; - uint8_t keyBuf[4096]; - whNvmMetadata meta = {0}; - - /* open the key file */ - ret = keyFd = open(keyFilePath, O_RDONLY, 0); - if (ret < 0) { - printf("Failed to open %s %d\n", keyFilePath, ret); - return ret; - } - /* read the key to local buffer */ - ret = keySz = read(keyFd, keyBuf, sizeof(keyBuf)); - if (ret < 0) { - printf("Failed to read %s %d\n", keyFilePath, ret); - close(keyFd); - return ret; - } - ret = 0; - close(keyFd); - - printf( - "Loading key from %s (size=%d) with keyId=0x%02X and clientId=0x%01X\n", - keyFilePath, keySz, keyId, clientId); - - /* cache the key in the HSM, get HSM assigned keyId */ - /* set the metadata fields */ - meta.id = WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, clientId, keyId); - meta.flags = 0; - meta.len = keySz; - memcpy(meta.label, keyLabel, strlen(keyLabel)); - - /* Get HSM assigned keyId if not set */ - if (keyId == WH_KEYID_ERASED) { - ret = wh_Server_KeystoreGetUniqueId(server, &meta.id); - printf("got unique ID = 0x%02X\n", meta.id & WH_KEYID_MASK); - } - printf( - "key NVM ID = 0x%04X\n\ttype=0x%01X\n\tuser=0x%01X\n\tkeyId=0x%02X\n", - meta.id, WH_KEYID_TYPE(meta.id), WH_KEYID_USER(meta.id), - WH_KEYID_ID(meta.id)); - - if (ret == 0) { - ret = wh_Server_KeystoreCacheKey(server, &meta, keyBuf); - if (ret != 0) { - printf("Failed to wh_Server_KeystoreCacheKey, ret=%d\n", ret); - return ret; - } - } - else { - printf("Failed to wh_Server_KeystoreGetUniqueId, ret=%d\n", ret); - return ret; - } - - *outKeyId = meta.id; - return ret; -} - - -static int wh_ServerTask(void* cf, const char* keyFilePath, int keyId, - int clientId) -{ - whServerContext server[1]; - whServerConfig* config = (whServerConfig*)cf; - int ret = 0; - whCommConnected last_state = WH_COMM_DISCONNECTED; - whKeyId loadedKeyId; - - if (config == NULL) { - return -1; - } - - ret = wh_Server_Init(server, config); - - /* Load keys into cache if file path is provided */ - if (keyFilePath != NULL) { - ret = loadAndStoreKeys(server, &loadedKeyId, keyFilePath, keyId, - clientId); - if (ret != 0) { - printf("server failed to load key, ret=%d\n", ret); - (void)wh_Server_Cleanup(server); - return ret; - } - } - - - if (ret == 0) { - printf("Waiting for connection...\n"); - while (1) { - ret = wh_Server_HandleRequestMessage(server); - if (ret == WH_ERROR_NOTREADY) { - _sleepMs(ONE_MS); - } - else if (ret != WH_ERROR_OK) { - printf("Failed to wh_Server_HandleRequestMessage: %d\n", ret); - break; - } - else { - whCommConnected current_state; - int get_conn_result = - wh_Server_GetConnected(server, ¤t_state); - if (get_conn_result == WH_ERROR_OK) { - if (current_state == WH_COMM_CONNECTED && - last_state == WH_COMM_DISCONNECTED) { - printf("Server connected\n"); - last_state = WH_COMM_CONNECTED; - } - else if (current_state == WH_COMM_DISCONNECTED && - last_state == WH_COMM_CONNECTED) { - printf("Server disconnected\n"); - last_state = WH_COMM_DISCONNECTED; - - /* POSIX TCP transport requires server to be - * re-initialized in order to reconnect */ - - (void)wh_Server_Cleanup(server); - - /* Reinitialize the server */ - ret = wh_Server_Init(server, config); - if (ret != 0) { - printf("Failed to reinitialize server: %d\n", ret); - break; - } - - /* Reload keys into cache if file path was provided */ - if (keyFilePath != NULL) { - ret = - loadAndStoreKeys(server, &loadedKeyId, - keyFilePath, keyId, clientId); - if (ret != 0) { - printf("server failed to load key, ret=%d\n", - ret); - break; - } - } - } - } - else { - printf("Failed to get connection state: %d\n", - get_conn_result); - } - } - } - } - return ret; -} - -static int _hardwareCryptoCb(int devId, struct wc_CryptoInfo* info, - void* ctx) -{ - (void)devId; - (void)ctx; - - /* Default response */ - int ret = CRYPTOCB_UNAVAILABLE; - switch(info->algo_type) { - case WC_ALGO_TYPE_RNG: { - /*printf("Hardware Crypto Callback: RNG operation requested\n");*/ - /* Extract info parameters */ - uint8_t* out = info->rng.out; - uint32_t size = info->rng.sz; - - /* III Not random, just simple counter */ - static uint16_t my_counter = 1; - if(my_counter > 4096) { - /* Only allow 4096 bytes to be generated */ - ret= CRYPTOCB_UNAVAILABLE; - } else { - uint32_t i = 0; - for (i = 0; i < size; i++) { - out[i] = (uint8_t)my_counter++; - } - ret = 0; - } - break; - } - default: - /*printf("Hardware Crypto Callback: Unsupported algorithm type\n"); */ - ret = CRYPTOCB_UNAVAILABLE; - } - return ret; -} - -int main(int argc, char** argv) +int wh_PosixServer_ExampleNvmConfig(void* conf, const char* nvmInitFilePath) { - int rc = 0; - const char* keyFilePath = NULL; - const char* nvmInitFilePath = NULL; - int keyId = WH_KEYID_ERASED; /* Default key ID if none provided */ - int clientId = 12; /* Default client ID if none provided */ - uint8_t memory[FLASH_RAM_SIZE] = {0}; - - - /* Parse command-line arguments */ - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--key") == 0 && i + 1 < argc) { - keyFilePath = argv[++i]; - } - else if (strcmp(argv[i], "--id") == 0 && i + 1 < argc) { - keyId = atoi(argv[++i]); - } - else if (strcmp(argv[i], "--client") == 0 && i + 1 < argc) { - clientId = atoi(argv[++i]); - } - else if (strcmp(argv[i], "--nvminit") == 0 && i + 1 < argc) { - nvmInitFilePath = argv[++i]; - } - } - - /* Server configuration/context */ - whTransportServerCb ptttcb[1] = {PTT_SERVER_CB}; - posixTransportTcpServerContext tsc[1] = {}; - posixTransportTcpConfig mytcpconfig[1] = {{ - .server_ip_string = WH_SERVER_TCP_IPSTRING, - .server_port = WH_SERVER_TCP_PORT, - }}; - whCommServerConfig cs_conf[1] = {{ - .transport_cb = ptttcb, - .transport_context = (void*)tsc, - .transport_config = (void*)mytcpconfig, - .server_id = WH_SERVER_ID, - }}; - - /* RamSim Flash state and configuration */ - whFlashRamsimCtx fc[1] = {0}; - whFlashRamsimCfg fc_conf[1] = {{ - .size = FLASH_RAM_SIZE, - .sectorSize = FLASH_RAM_SIZE / 2, - .pageSize = 8, - .erasedByte = (uint8_t)0, - .memory = memory, - }}; - 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, - }}; - whNvmContext nvm[1] = {{0}}; - - /* Crypto context */ - whServerCryptoContext crypto[1] = {{ - .devId = INVALID_DEVID, - }}; - -#if defined(WOLFHSM_CFG_SHE_EXTENSION) - whServerSheContext she[1] = {{0}}; -#endif - - whServerConfig s_conf[1] = {{ - .comm_config = cs_conf, - .nvm = nvm, - .crypto = crypto, - .devId = INVALID_DEVID, -#if defined(WOLFHSM_CFG_SHE_EXTENSION) - .she = she, -#endif - }}; - - rc = wh_Nvm_Init(nvm, n_conf); + int rc; + whServerConfig* s_conf = (whServerConfig*)conf; + static whNvmConfig n_conf = {0}; + static whNvmFlashConfig nf_conf; + static whNvmFlashContext nfc[1] = {0}; + static whNvmCb nfcb[1] = {WH_NVM_FLASH_CB}; + static whNvmContext nvm[1] = {{0}}; + static whFlashRamsimCtx fc = {0}; + + + nf_conf.cb = &fcb; + nf_conf.context = &fc; + nf_conf.config = &fc_conf; + + n_conf.cb = nfcb; + n_conf.context = nfc; + n_conf.config = &nf_conf; + + s_conf->nvm = nvm; + rc = wh_Nvm_Init(nvm, &n_conf); if (rc != 0) { printf("Failed to initialize NVM: %d\n", rc); return rc; @@ -703,49 +515,5 @@ int main(int argc, char** argv) printf("NVM initialization completed successfully\n"); } - /* Initialize crypto library and hardware */ - wolfCrypt_Init(); - - /* Context 3: Server Software Crypto */ - WC_RNG rng[1]; - uint8_t buffer[128] = {0}; - wc_InitRng_ex(rng, NULL, INVALID_DEVID); - wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); - wc_FreeRng(rng); - wh_Utils_Hexdump("Context 3: Server SW RNG:\n", buffer, sizeof(buffer)); - - /* Context 4: Server Hardware Crypto */ - #define HW_DEV_ID 100 - memset(buffer, 0, sizeof(buffer)); - wc_CryptoCb_RegisterDevice(HW_DEV_ID, _hardwareCryptoCb, NULL); - wc_InitRng_ex(rng, NULL, HW_DEV_ID); - wc_RNG_GenerateBlock(rng, buffer, sizeof(buffer)); - wc_FreeRng(rng); - wh_Utils_Hexdump("Context 4: Server HW RNG:\n", buffer, sizeof(buffer)); - - /* Context 5: Set default server crypto to use cryptocb */ - crypto->devId = HW_DEV_ID; - printf("Context 5: Setting up default server crypto with devId=%d\n", - crypto->devId); - - rc = wc_InitRng_ex(crypto->rng, NULL, crypto->devId); - if (rc != 0) { - printf("Failed to wc_InitRng_ex: %d\n", rc); - return rc; - } - - rc = wh_ServerTask(s_conf, keyFilePath, keyId, clientId); - - rc = wc_FreeRng(crypto->rng); - if (rc != 0) { - printf("Failed to wc_FreeRng: %d\n", rc); - return rc; - } - rc = wolfCrypt_Cleanup(); - if (rc != 0) { - printf("Failed to wolfCrypt_Cleanup: %d\n", rc); - return rc; - } - - return rc; + return WH_ERROR_OK; } diff --git a/examples/posix/wh_posix_server/wh_posix_server_cfg.h b/examples/posix/wh_posix_server/wh_posix_server_cfg.h new file mode 100644 index 00000000..6b859887 --- /dev/null +++ b/examples/posix/wh_posix_server/wh_posix_server_cfg.h @@ -0,0 +1,12 @@ +#ifndef WH_POSIX_SERVER_CFG_H +#define WH_POSIX_SERVER_CFG_H + +#include + +int wh_PosixServer_ExampleShmDmaConfig(void* s_conf); +int wh_PosixServer_ExampleShmConfig(void* s_conf); +int wh_PosixServer_ExampleTcpConfig(void* s_conf); +int wh_PosixServer_ExampleNvmConfig(void* conf, const char* nvmInitFilePath); +int wh_PosixServer_ExampleRamSimConfig(void* conf, uint8_t* memory); + +#endif /* WH_POSIX_SERVER_CFG_H */ \ No newline at end of file diff --git a/examples/posix/tcp/wh_server_tcp/wolfhsm_cfg.h b/examples/posix/wh_posix_server/wolfhsm_cfg.h similarity index 100% rename from examples/posix/tcp/wh_server_tcp/wolfhsm_cfg.h rename to examples/posix/wh_posix_server/wolfhsm_cfg.h diff --git a/port/posix/posix_transport_shm.c b/port/posix/posix_transport_shm.c index 5ae1679e..33dc7136 100644 --- a/port/posix/posix_transport_shm.c +++ b/port/posix/posix_transport_shm.c @@ -20,13 +20,13 @@ * port/posix/posix_transport_shm.c */ -#include /* For O_* constants */ -#include /* For shm_open, mmap */ -#include /* For mode constants */ -#include /* For ftruncate, getpid, sleep */ -#include /* For errno */ -#include /* For exit */ -#include /* For memset */ +#include /* For O_* constants */ +#include /* For shm_open, mmap */ +#include /* For mode constants */ +#include /* For ftruncate, getpid, sleep */ +#include /* For errno */ +#include /* For exit */ +#include /* For memset */ #include #include @@ -42,58 +42,61 @@ #define PTSHM_HEADER_SIZE 64 typedef union { struct { - uint32_t initialized; /* Set non-zero when setup */ - uint16_t req_size; /* Size of request buffer */ - uint16_t resp_size; /* Size of response buffer */ - size_t dma_size; /* Size of shared DMA space */ - pid_t creator_pid; /* Process ID of the creator */ - pid_t user_pid; /* Process ID of user */ + uint32_t initialized; /* Set non-zero when setup */ + uint16_t req_size; /* Size of request buffer */ + uint16_t resp_size; /* Size of response buffer */ + size_t dma_size; /* Size of shared DMA space */ + pid_t creator_pid; /* Process ID of the creator */ + pid_t user_pid; /* Process ID of user */ }; uint8_t WH_PAD[PTSHM_HEADER_SIZE]; } ptshmHeader; typedef struct { - void* ptr; - size_t size; + void* ptr; + size_t size; ptshmHeader* header; - uint8_t* req; - uint8_t* resp; - uint8_t* dma; - size_t dma_size; - uint16_t req_size; - uint16_t resp_size; + uint8_t* req; + uint8_t* resp; + uint8_t* dma; + size_t dma_size; + uint16_t req_size; + uint16_t resp_size; } ptshmMapping; enum { - PTSHM_INITIALIZED_NONE = 0, - PTSHM_INITIALIZED_CLEANUP = 1, - PTSHM_INITIALIZED_CREATOR = 2, - PTSHM_INITIALIZED_USER = 3, + PTSHM_INITIALIZED_NONE = 0, + PTSHM_INITIALIZED_CLEANUP = 1, + PTSHM_INITIALIZED_CREATOR = 2, + PTSHM_INITIALIZED_USER = 3, }; /** Local declarations */ /* Memory map and interpret the header block */ static int posixTransportShm_Map(int fd, size_t size, ptshmMapping* map); -/* Use and map a shared object for transport */ -static int posixTransportShm_UseMap(char* name, ptshmMapping* map); - +#if defined(WOLFHSM_CFG_ENABLE_SERVER) /* Create and map a shared object for transport */ static int posixTransportShm_CreateMap(char* name, uint16_t req_size, - uint16_t resp_size, size_t dma_size, ptshmMapping* map); + uint16_t resp_size, size_t dma_size, + ptshmMapping* map); +#endif -/* Map the shared object if not already mapped */ -static int posixTransportShm_HandleMap(posixTransportShmContext *ctx); +#if defined(WOLFHSM_CFG_ENABLE_CLIENT) +/* Use and map a shared object for transport */ +static int posixTransportShm_UseMap(char* name, ptshmMapping* map); +/* Map the shared object if not already mapped */ +static int posixTransportShm_HandleMap(posixTransportShmContext* ctx); +#endif /** Local Definitions */ static int posixTransportShm_Map(int fd, size_t size, ptshmMapping* map) { - int ret = WH_ERROR_OK; + int ret = WH_ERROR_OK; void* ptr = NULL; - if ( (fd < 0) || - (map == NULL) ) { + if ((fd < 0) || (map == NULL)) { return WH_ERROR_BADARGS; } @@ -101,47 +104,48 @@ static int posixTransportShm_Map(int fd, size_t size, ptshmMapping* map) ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr != MAP_FAILED) { memset(map, 0, sizeof(*map)); - map->ptr = ptr; - map->size = size; - map->header = (ptshmHeader*)ptr; - map->req = (uint8_t*)(map->header + 1); - map->resp = map->req + map->header->req_size; - map->dma = map->resp + map->header->resp_size; - } else { + map->ptr = ptr; + map->size = size; + map->header = (ptshmHeader*)ptr; + map->req = (uint8_t*)(map->header + 1); + map->resp = map->req + map->header->req_size; + map->dma = map->resp + map->header->resp_size; + map->dma_size = map->header->dma_size; + } + else { ret = WH_ERROR_ABORTED; } return ret; } - +#if defined(WOLFHSM_CFG_ENABLE_CLIENT) static int posixTransportShm_UseMap(char* name, ptshmMapping* map) { int ret = WH_ERROR_OK; - int fd = -1; + int fd = -1; - if( (name == NULL) || (map == NULL)) { + if ((name == NULL) || (map == NULL)) { return WH_ERROR_BADARGS; } fd = shm_open(name, O_RDWR, 0); if (fd >= 0) { /* Check the size */ - struct stat st[1] = { 0 }; - ret = fstat(fd, st); + struct stat st[1] = {0}; + ret = fstat(fd, st); if (ret == 0) { if (st->st_size != 0) { /* Map the header and get configuration */ - ptshmHeader* header = (ptshmHeader*)mmap(NULL, sizeof(*header), - PROT_READ, MAP_SHARED, fd, 0); + ptshmHeader* header = (ptshmHeader*)mmap( + NULL, sizeof(*header), PROT_READ, MAP_SHARED, fd, 0); if (header != MAP_FAILED) { size_t size = 0; if (header->initialized == PTSHM_INITIALIZED_CREATOR) { /* Read provided sizes */ - size = sizeof(*header) + - header->req_size + - header->resp_size + - header->dma_size; - } else { + size = sizeof(*header) + header->req_size + + header->resp_size + header->dma_size; + } + else { /* Header not configured */ ret = WH_ERROR_NOTREADY; } @@ -159,40 +163,46 @@ static int posixTransportShm_UseMap(char* name, ptshmMapping* map) map->header->initialized = PTSHM_INITIALIZED_USER; } } - } else { + } + else { /* Mapping the header failed */ ret = WH_ERROR_ABORTED; } - } else { + } + else { /* ftruncate has not completed */ ret = WH_ERROR_NOTREADY; } (void)close(fd); - } else { + } + else { /* Problem getting file stat */ ret = WH_ERROR_ABORTED; } - } else { + } + else { if (errno == ENOENT) { /* File does not exist */ ret = WH_ERROR_NOTFOUND; - } else { + } + else { /* Some other error */ ret = WH_ERROR_ABORTED; } } return ret; } +#endif /* WOLFHSM_CFG_ENABLE_CLIENT */ - +#if defined(WOLFHSM_CFG_ENABLE_SERVER) static int posixTransportShm_CreateMap(char* name, uint16_t req_size, - uint16_t resp_size, size_t dma_size, ptshmMapping* map) + uint16_t resp_size, size_t dma_size, + ptshmMapping* map) { int ret = WH_ERROR_OK; - int fd = -1; + int fd = -1; - if ( (name == NULL) || - (map == NULL) ) { + if ((name == NULL) || (map == NULL)) { return WH_ERROR_BADARGS; } @@ -206,12 +216,13 @@ static int posixTransportShm_CreateMap(char* name, uint16_t req_size, size_t size = sizeof(*(map->header)) + req_size + resp_size + dma_size; if (ftruncate(fd, size) == 0) { /* Map the header and set the configuration */ - ptshmHeader* header = (ptshmHeader*)mmap(NULL, sizeof(*header), - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + ptshmHeader* header = + (ptshmHeader*)mmap(NULL, sizeof(*header), + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (header != MAP_FAILED) { - header->req_size = req_size; - header->resp_size = resp_size; - header->dma_size = dma_size; + header->req_size = req_size; + header->resp_size = resp_size; + header->dma_size = dma_size; header->creator_pid = getpid(); XMEMFENCE(); header->initialized = PTSHM_INITIALIZED_CREATOR; @@ -219,36 +230,40 @@ static int posixTransportShm_CreateMap(char* name, uint16_t req_size, /* Unmap the header and remap the full area */ (void)munmap((void*)header, sizeof(*header)); ret = posixTransportShm_Map(fd, size, map); - } else { + } + else { /* Problem mapping the header */ ret = WH_ERROR_ABORTED; } - } else { + } + else { /* Problem setting the size. */ ret = WH_ERROR_ABORTED; } close(fd); - } else { + } + else { /* Problem creating the shared memory */ ret = WH_ERROR_ABORTED; } return ret; } +#endif /* WOLFHSM_CFG_ENABLE_SERVER */ +#if defined(WOLFHSM_CFG_ENABLE_CLIENT) /* Map the shared object if not already mapped */ -static int posixTransportShm_HandleMap(posixTransportShmContext *ctx) +static int posixTransportShm_HandleMap(posixTransportShmContext* ctx) { - int ret = WH_ERROR_OK; - ptshmMapping map[1] = { 0 }; - whTransportMemConfig tMemCfg[1] = { 0 }; + int ret = WH_ERROR_OK; + ptshmMapping map[1] = {0}; + whTransportMemConfig tMemCfg[1] = {0}; if (ctx == NULL) { return WH_ERROR_BADARGS; } - if ( (ret == WH_ERROR_OK) && - (ctx->state == PTSHM_STATE_NONE) ) { + if ((ret == WH_ERROR_OK) && (ctx->state == PTSHM_STATE_NONE)) { /* Attempt to map */ ret = posixTransportShm_UseMap(ctx->name, map); if (ret == WH_ERROR_OK) { @@ -260,40 +275,41 @@ static int posixTransportShm_HandleMap(posixTransportShmContext *ctx) /* Initialize the shared memory transport */ ret = wh_TransportMem_InitClear(ctx->transportMemCtx, tMemCfg, NULL, - NULL); + NULL); if (ret == WH_ERROR_OK) { - ctx->ptr = map->ptr; - ctx->size = map->size; - ctx->dma = map->dma; + ctx->ptr = map->ptr; + ctx->size = map->size; + ctx->dma = map->dma; ctx->dma_size = map->dma_size; - ctx->state = PTSHM_STATE_INITIALIZED; + ctx->state = PTSHM_STATE_INITIALIZED; if (ctx->connectcb != NULL) { ctx->connectcb(ctx->connectcb_arg, WH_COMM_CONNECTED); } - } else { + } + else { /* Problem initializing the transport */ (void)munmap(map->ptr, map->size); } } } - if ( (ret == WH_ERROR_OK) && - ((ctx->state == PTSHM_STATE_MAPPED) || - (ctx->state == PTSHM_STATE_DONE) ) ) { + if ((ret == WH_ERROR_OK) && ((ctx->state == PTSHM_STATE_MAPPED) || + (ctx->state == PTSHM_STATE_DONE))) { /* Mapped is invalid for a client */ ret = WH_ERROR_ABORTED; }; return ret; } +#endif /* WOLFHSM_CFG_ENABLE_CLIENT */ /** Custom functions */ int posixTransportShm_IsConnected(posixTransportShmContext* ctx, - whCommConnected *out_connected) + whCommConnected* out_connected) { - ptshmHeader* header = NULL; + ptshmHeader* header = NULL; whCommConnected connected = WH_COMM_DISCONNECTED; if (ctx == NULL) { return WH_ERROR_BADARGS; @@ -313,15 +329,14 @@ int posixTransportShm_IsConnected(posixTransportShmContext* ctx, int posixTransportShm_GetCreatorPid(posixTransportShmContext* ctx, - pid_t *out_pid) + pid_t* out_pid) { ptshmHeader* header = NULL; if (ctx == NULL) { return WH_ERROR_BADARGS; } header = (ptshmHeader*)ctx->ptr; - if ( (header == NULL) || - (header->initialized < PTSHM_INITIALIZED_CREATOR) ) { + if ((header == NULL) || (header->initialized < PTSHM_INITIALIZED_CREATOR)) { return WH_ERROR_NOTREADY; } if (out_pid != NULL) { @@ -331,28 +346,25 @@ int posixTransportShm_GetCreatorPid(posixTransportShmContext* ctx, } -int posixTransportShm_GetUserPid(posixTransportShmContext* ctx, - pid_t *out_pid) +int posixTransportShm_GetUserPid(posixTransportShmContext* ctx, pid_t* out_pid) { ptshmHeader* header = NULL; if (ctx == NULL) { return WH_ERROR_BADARGS; } header = (ptshmHeader*)ctx->ptr; - if ( (header == NULL) || - (header->initialized < PTSHM_INITIALIZED_USER) ) { + if ((header == NULL) || (header->initialized < PTSHM_INITIALIZED_USER)) { return WH_ERROR_NOTREADY; } if (out_pid != NULL) { *out_pid = header->user_pid; } return WH_ERROR_OK; - } -int posixTransportShm_GetDma(posixTransportShmContext* ctx, - void* *out_dma, size_t *out_size) +int posixTransportShm_GetDma(posixTransportShmContext* ctx, void** out_dma, + size_t* out_size) { if (ctx == NULL) { return WH_ERROR_BADARGS; @@ -367,33 +379,29 @@ int posixTransportShm_GetDma(posixTransportShmContext* ctx, } +#if defined(WOLFHSM_CFG_ENABLE_SERVER) /** Callback function definitions */ int posixTransportShm_ServerInit(void* c, const void* cf, whCommSetConnectedCb connectcb, void* connectcb_arg) { - posixTransportShmContext* ctx = (posixTransportShmContext*)c; - posixTransportShmConfig* config = (posixTransportShmConfig*)cf; - int ret = WH_ERROR_OK; - ptshmMapping map[1] = { 0 }; - whTransportMemConfig tMemCfg[1] = { 0 }; - - if ( (ctx == NULL) || - (config == NULL) || - (config->name == NULL) ) { + posixTransportShmContext* ctx = (posixTransportShmContext*)c; + posixTransportShmConfig* config = (posixTransportShmConfig*)cf; + int ret = WH_ERROR_OK; + ptshmMapping map[1] = {0}; + whTransportMemConfig tMemCfg[1] = {0}; + + if ((ctx == NULL) || (config == NULL) || (config->name == NULL)) { return WH_ERROR_BADARGS; } - ret = posixTransportShm_CreateMap( config->name, - config->req_size, - config->resp_size, - config->dma_size, - map); + ret = posixTransportShm_CreateMap(config->name, config->req_size, + config->resp_size, config->dma_size, map); if (ret == WH_ERROR_OK) { memset(ctx, 0, sizeof(*ctx)); snprintf(ctx->name, sizeof(ctx->name), "%s", config->name); - ctx->connectcb = connectcb; + ctx->connectcb = connectcb; ctx->connectcb_arg = connectcb_arg; /* Configure the underlying transport context */ @@ -406,14 +414,14 @@ int posixTransportShm_ServerInit(void* c, const void* cf, ret = wh_TransportMem_Init(ctx->transportMemCtx, tMemCfg, NULL, NULL); if (ret == WH_ERROR_OK) { - ctx->ptr = map->ptr; - ctx->size = map->size; - ctx->dma = map->dma; + ctx->ptr = map->ptr; + ctx->size = map->size; + ctx->dma = map->dma; ctx->dma_size = map->dma_size; ctx->state = PTSHM_STATE_MAPPED; - - } else { + } + else { /* Problem initializing the transport */ (void)munmap(map->ptr, map->size); (void)shm_unlink(config->name); @@ -421,36 +429,36 @@ int posixTransportShm_ServerInit(void* c, const void* cf, } return ret; } +#endif /* WOLFHSM_CFG_ENABLE_SERVER */ +#if defined(WOLFHSM_CFG_ENABLE_CLIENT) int posixTransportShm_ClientInit(void* c, const void* cf, whCommSetConnectedCb connectcb, void* connectcb_arg) { - posixTransportShmContext* ctx = (posixTransportShmContext*)c; - posixTransportShmConfig* config = (posixTransportShmConfig*)cf; - int ret = WH_ERROR_OK; + posixTransportShmContext* ctx = (posixTransportShmContext*)c; + posixTransportShmConfig* config = (posixTransportShmConfig*)cf; + int ret = WH_ERROR_OK; - if ( (ctx == NULL) || - (config == NULL) || - (config->name == NULL)) { + if ((ctx == NULL) || (config == NULL) || (config->name == NULL)) { return WH_ERROR_BADARGS; } memset(ctx, 0, sizeof(*ctx)); snprintf(ctx->name, sizeof(ctx->name), "%s", config->name); - ctx->connectcb = connectcb; + ctx->connectcb = connectcb; ctx->connectcb_arg = connectcb_arg; ret = posixTransportShm_HandleMap(ctx); - if ( (ret == WH_ERROR_NOTFOUND) || - (ret == WH_ERROR_NOTREADY) ) { + if ((ret == WH_ERROR_NOTFOUND) || (ret == WH_ERROR_NOTREADY)) { /* Good enough for now. Set to ok. */ ret = WH_ERROR_OK; } return ret; } +#endif /* WOLFHSM_CFG_ENABLE_CLIENT */ int posixTransportShm_Cleanup(void* c) @@ -477,7 +485,7 @@ int posixTransportShm_Cleanup(void* c) int posixTransportShm_SendRequest(void* c, uint16_t len, const void* data) { posixTransportShmContext* ctx = (posixTransportShmContext*)c; - int ret = WH_ERROR_OK; + int ret = WH_ERROR_OK; /* Only need to check NULL, mem transport checks other state info */ if (ctx == NULL) { @@ -485,33 +493,34 @@ int posixTransportShm_SendRequest(void* c, uint16_t len, const void* data) } /* Check connected status */ - switch(ctx->state) { - case PTSHM_STATE_NONE: - ret = posixTransportShm_HandleMap(ctx); - if (ret == WH_ERROR_OK) { - if(ctx->connectcb != NULL) { - ctx->connectcb(ctx->connectcb_arg, WH_COMM_CONNECTED); + switch (ctx->state) { + case PTSHM_STATE_NONE: + ret = posixTransportShm_HandleMap(ctx); + if (ret == WH_ERROR_OK) { + if (ctx->connectcb != NULL) { + ctx->connectcb(ctx->connectcb_arg, WH_COMM_CONNECTED); + } } - } else { - if (ret == WH_ERROR_NOTFOUND) { - /* Server hasn't created the object yet */ - ret = WH_ERROR_NOTREADY; + else { + if (ret == WH_ERROR_NOTFOUND) { + /* Server hasn't created the object yet */ + ret = WH_ERROR_NOTREADY; + } } - } - break; + break; - case PTSHM_STATE_MAPPED: - /* Invalid state for a client */ - ret = WH_ERROR_BADARGS; - break; + case PTSHM_STATE_MAPPED: + /* Invalid state for a client */ + ret = WH_ERROR_BADARGS; + break; - case PTSHM_STATE_INITIALIZED: - ret = WH_ERROR_OK; - break; + case PTSHM_STATE_INITIALIZED: + ret = WH_ERROR_OK; + break; - case PTSHM_STATE_DONE: - default: - ret = WH_ERROR_ABORTED; + case PTSHM_STATE_DONE: + default: + ret = WH_ERROR_ABORTED; } if (ret == WH_ERROR_OK) { @@ -531,6 +540,85 @@ int posixTransportShm_RecvResponse(void* c, uint16_t* out_len, void* data) return wh_TransportMem_RecvResponse(ctx->transportMemCtx, out_len, data); } + +#ifdef WOLFHSM_CFG_DMA +/** DMA function callbacks that can make use of WOLFSSL_STATIC_MEMORY using + * the POSIX shared memory transport. + */ + +int posixTransportShm_ClientStaticMemDmaCallback( + struct whClientContext_t* client, uintptr_t clientAddr, + void** xformedCliAddr, size_t len, whDmaOper oper, whDmaFlags flags) +{ + int ret = WH_ERROR_OK; + int isInDma = 0; + void* dmaPtr; + size_t dmaSize; + uintptr_t dmaBuffer; /* buffer in DMA space */ + uintptr_t dmaOffset; + void* heap = NULL; + + /* NULL pointer maps to NULL, short circuit here */ + if (clientAddr == 0 || len == 0) { + *xformedCliAddr = NULL; + return WH_ERROR_OK; + } + + /* First check if the address is in the expected DMA area */ + ret = posixTransportShm_GetDma(client->comm->transport_context, &dmaPtr, + &dmaSize); + if (ret != WH_ERROR_OK) { + return ret; + } + + if ((dmaPtr != NULL) && (dmaSize > 0) && (len < dmaSize) && + (clientAddr >= (uintptr_t)dmaPtr) && + (clientAddr < (uintptr_t)(dmaPtr + dmaSize - len))) { + dmaBuffer = clientAddr; + isInDma = 1; + } + else { + heap = client->dma.heap; + if (heap == NULL) { + return WH_ERROR_NOTREADY; + } + } + + if (oper == WH_DMA_OPER_CLIENT_READ_PRE || + oper == WH_DMA_OPER_CLIENT_WRITE_PRE) { + if (isInDma == 0) { + dmaBuffer = (uintptr_t)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dmaBuffer == 0) { + return WH_ERROR_NOSPACE; + } + dmaOffset = dmaBuffer - (uintptr_t)dmaPtr; + memcpy((void*)dmaBuffer, (void*)clientAddr, len); + } + else { + dmaOffset = clientAddr - (uintptr_t)dmaPtr; + } + /* return an offset into the DMA area */ + *xformedCliAddr = (void*)dmaOffset; + } + else if (oper == WH_DMA_OPER_CLIENT_READ_POST) { + if (isInDma == 0) { + uint8_t* ptr = (uint8_t*)dmaPtr + (uintptr_t)*xformedCliAddr; + XFREE(ptr, heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } + else if (oper == WH_DMA_OPER_CLIENT_WRITE_POST) { + if (isInDma == 0) { + uint8_t* ptr = (uint8_t*)dmaPtr + (uintptr_t)*xformedCliAddr; + memcpy((void*)clientAddr, ptr, + len); /* copy results of what server wrote */ + XFREE(ptr, heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } + + (void)flags; + return ret; +} +#endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFHSM_CFG_ENABLE_CLIENT */ #if defined(WOLFHSM_CFG_ENABLE_SERVER) @@ -549,40 +637,39 @@ int posixTransportShm_SendResponse(void* c, uint16_t len, const void* data) int posixTransportShm_RecvRequest(void* c, uint16_t* out_len, void* data) { posixTransportShmContext* ctx = (posixTransportShmContext*)c; - int ret = WH_ERROR_OK; + int ret = WH_ERROR_OK; if (ctx == NULL) { return WH_ERROR_BADARGS; } /* Check connected status */ - switch(ctx->state) { - case PTSHM_STATE_NONE: - /* Server should not get this state */ - ret = WH_ERROR_BADARGS; - break; - - case PTSHM_STATE_MAPPED: - { - /* Check to see if client connected */ - whCommConnected connected = WH_COMM_DISCONNECTED; - posixTransportShm_IsConnected(ctx, &connected); - if (connected == WH_COMM_CONNECTED) { - ctx->state = PTSHM_STATE_INITIALIZED; - if (ctx->connectcb != NULL) { - ctx->connectcb(ctx->connectcb_arg, connected); + switch (ctx->state) { + case PTSHM_STATE_NONE: + /* Server should not get this state */ + ret = WH_ERROR_BADARGS; + break; + + case PTSHM_STATE_MAPPED: { + /* Check to see if client connected */ + whCommConnected connected = WH_COMM_DISCONNECTED; + posixTransportShm_IsConnected(ctx, &connected); + if (connected == WH_COMM_CONNECTED) { + ctx->state = PTSHM_STATE_INITIALIZED; + if (ctx->connectcb != NULL) { + ctx->connectcb(ctx->connectcb_arg, connected); + } + ret = WH_ERROR_OK; } - ret = WH_ERROR_OK; - } - } break; + } break; - case PTSHM_STATE_INITIALIZED: - ret = WH_ERROR_OK; - break; + case PTSHM_STATE_INITIALIZED: + ret = WH_ERROR_OK; + break; - case PTSHM_STATE_DONE: - default: - ret = WH_ERROR_ABORTED; + case PTSHM_STATE_DONE: + default: + ret = WH_ERROR_ABORTED; } if (ret == WH_ERROR_OK) { @@ -590,4 +677,72 @@ int posixTransportShm_RecvRequest(void* c, uint16_t* out_len, void* data) } return ret; } -#endif \ No newline at end of file + +#ifdef WOLFHSM_CFG_DMA +/* Generic offset into the DMA area. This function can operate with no knowledge + * of what structures the DMA area is. It takes in an offset, validates it, and + * returns the pointer into the DMA area based off of the offset. */ +int posixTransportShm_ServerStaticMemDmaCallback( + whServerContext* server, uintptr_t clientAddr, void** xformedCliAddr, + size_t len, whServerDmaOper oper, whServerDmaFlags flags) +{ + posixTransportShmContext* ctx; + void* dma_ptr; + size_t dma_size; + int ret; + + (void)oper; + (void)flags; + + if (server == NULL || xformedCliAddr == NULL) { + return WH_ERROR_BADARGS; + } + + /* Get the transport context from the server's communication context */ + ctx = (posixTransportShmContext*)server->comm->transport_context; + if (ctx == NULL) { + return WH_ERROR_BADARGS; + } + + /* Get the DMA section pointer and size */ + ret = posixTransportShm_GetDma(ctx, &dma_ptr, &dma_size); + if (ret != WH_ERROR_OK) { + return ret; + } + + if (dma_ptr == NULL || dma_size == 0) { + return WH_ERROR_NOTREADY; + } + + if (len > dma_size || clientAddr > dma_size - len) { + return WH_ERROR_BADARGS; + } + + /* Return the transformed address (DMA pointer + offset) */ + *xformedCliAddr = (void*)((uintptr_t)dma_ptr + clientAddr); + return WH_ERROR_OK; +} +#endif /* WOLFHSM_CFG_DMA */ +#endif /* WOLFHSM_CFG_ENABLE_SERVER */ + +#if defined(WOLFHSM_CFG_DMA) +int posixTransportShm_SetDmaHeap(posixTransportShmContext* ctx, void* heap) +{ + if (ctx == NULL) { + return WH_ERROR_BADARGS; + } + ctx->heap = heap; + return WH_ERROR_OK; +} + + +void* posixTransportShm_GetDmaHeap(posixTransportShmContext* ctx) +{ + void* ret = NULL; + + if (ctx != NULL) { + ret = ctx->heap; + } + return ret; +} +#endif /* WOLFHSM_CFG_DMA */ diff --git a/port/posix/posix_transport_shm.h b/port/posix/posix_transport_shm.h index 73d4f5ef..e3b59fbb 100644 --- a/port/posix/posix_transport_shm.h +++ b/port/posix/posix_transport_shm.h @@ -86,6 +86,7 @@ typedef struct { whTransportMemContext transportMemCtx[1]; whCommSetConnectedCb connectcb; void* connectcb_arg; + void* heap; /* heap hint used in pass by reference */ } posixTransportShmContext; /* Naming conveniences. Reuses the same types. */ @@ -105,6 +106,31 @@ int posixTransportShm_GetDma(posixTransportShmContext* ctx, void* *out_dma, size_t *out_size); +/** + * @brief Setter function for the current heap hint + * + * This function is used to set the current heap hint set for use with the + * transport context. + * + * @param[in] ctx Pointer to the transport context. + * @param[in] heap Pointer to the heap hint + * @return int Returns WH_ERROR_OK on success, or WH_ERROR_BADARGS if the + * arguments are invalid. + */ +int posixTransportShm_SetDmaHeap(posixTransportShmContext* ctx, void* heap); + +/** + * @brief Getter function for the current heap hint + * + * This function is used to get the current heap hint set for use with the + * transport context. + * + * @param[in] ctx Pointer to the transport context. + * @return a pointer to the heap hint + */ +void* posixTransportShm_GetDmaHeap(posixTransportShmContext* ctx); + + /** Callback function declarations */ int posixTransportShm_ClientInit(void* c, const void* cf, whCommSetConnectedCb connectcb, @@ -135,4 +161,21 @@ int posixTransportShm_RecvResponse(void* c, uint16_t* out_len, void* data); .Cleanup = posixTransportShm_Cleanup, \ } + +#ifdef WOLFHSM_CFG_DMA +#include "wolfhsm/wh_dma.h" + +#include "wolfhsm/wh_server.h" +int posixTransportShm_ServerStaticMemDmaCallback( + whServerContext* server, uintptr_t clientAddr, void** xformedCliAddr, + size_t len, whServerDmaOper oper, whServerDmaFlags flags); + +#include "wolfhsm/wh_client.h" +int posixTransportShm_ClientStaticMemDmaCallback(whClientContext* client, + uintptr_t clientAddr, + void** xformedCliAddr, + size_t len, whDmaOper oper, + whDmaFlags flags); + +#endif #endif /* !PORT_POSIX_POSIX_TRANSPORT_SHM_H_ */ diff --git a/src/wh_client.c b/src/wh_client.c index 1ed60964..5845827e 100644 --- a/src/wh_client.c +++ b/src/wh_client.c @@ -59,7 +59,6 @@ #include "wolfhsm/wh_message_counter.h" #include "wolfhsm/wh_client.h" - #ifndef WOLFHSM_CFG_NO_CRYPTO const int WH_DEV_IDS_ARRAY[WH_NUM_DEVIDS] = { WH_DEV_ID, @@ -98,6 +97,13 @@ int wh_Client_Init(whClientContext* c, const whClientConfig* config) #ifdef WOLFHSM_CFG_DMA if (rc == 0) { + /* Initialize DMA configuration and callbacks, if provided */ + if (NULL != config->dmaConfig) { + c->dma.dmaAddrAllowList = + config->dmaConfig->dmaAddrAllowList; + c->dma.cb = config->dmaConfig->cb; + } + rc = wc_CryptoCb_RegisterDevice(WH_DEV_ID_DMA, wh_Client_CryptoCbDma, c); if (rc != 0) { @@ -743,10 +749,12 @@ int wh_Client_KeyCacheRequest_ex(whClientContext* c, uint32_t flags, else { req->labelSz = labelSz; /* write label */ - if (labelSz > WH_NVM_LABEL_LEN) + if (labelSz > WH_NVM_LABEL_LEN) { memcpy(req->label, label, WH_NVM_LABEL_LEN); - else + } + else { memcpy(req->label, label, labelSz); + } } /* write in */ @@ -1497,7 +1505,6 @@ int wh_Client_KeyExportDma(whClientContext* c, uint16_t keyId, } return ret; } - #endif /* WOLFHSM_CFG_DMA */ #endif /* WOLFHSM_CFG_ENABLE_CLIENT */ diff --git a/src/wh_client_crypto.c b/src/wh_client_crypto.c index a64ebfe1..104c33ef 100644 --- a/src/wh_client_crypto.c +++ b/src/wh_client_crypto.c @@ -2737,6 +2737,7 @@ int wh_Client_Sha256(whClientContext* ctx, wc_Sha256* sha256, const uint8_t* in, return ret; } +#ifdef WOLFHSM_CFG_DMA int wh_Client_Sha256Dma(whClientContext* ctx, wc_Sha256* sha, const uint8_t* in, uint32_t inLen, uint8_t* out) { @@ -2747,6 +2748,12 @@ int wh_Client_Sha256Dma(whClientContext* ctx, wc_Sha256* sha, const uint8_t* in, uint8_t* dataPtr = NULL; whMessageCrypto_Sha2DmaRequest* req = NULL; whMessageCrypto_Sha2DmaResponse* resp = NULL; + uintptr_t inAddr = 0; /* The req->input.addr is reused elsewhere, this + local variable is to keep track of the resulting + DMA translation to pass back to the callback on + POST operations. */ + uintptr_t outAddr = 0; + uintptr_t stateAddr = 0; /* Get data pointer from the context to use as request/response storage */ dataPtr = (uint8_t*)wh_CommClient_GetDataPtr(ctx->comm); @@ -2758,20 +2765,41 @@ int wh_Client_Sha256Dma(whClientContext* ctx, wc_Sha256* sha, const uint8_t* in, req = (whMessageCrypto_Sha2DmaRequest*)_createCryptoRequest( dataPtr, WC_HASH_TYPE_SHA256); - - /* Caller invoked SHA Update: - * wc_CryptoCb_Sha256Hash(sha256, data, len, NULL) */ - if (in != NULL) { + /* map addresses and setup default request structure */ + if (in != NULL || out != NULL) { req->finalize = 0; - req->state.addr = (uint64_t)(uintptr_t)sha256; req->state.sz = sizeof(*sha256); - req->input.addr = (uint64_t)(uintptr_t)in; req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; req->output.sz = WC_SHA256_DIGEST_SIZE; /* not needed, but YOLO */ + + /* Perform address translations */ + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha256, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + req->state.addr = stateAddr; + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_PRE, (whDmaFlags){0}); + req->input.addr = inAddr; + } + + if (ret == WH_ERROR_OK) { + ret = wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_PRE, (whDmaFlags){0}); + req->output.addr = outAddr; + } + } + + /* Caller invoked SHA Update: + * wc_CryptoCb_Sha256Hash(sha256, data, len, NULL) */ + if ((ret == WH_ERROR_OK) && (in != NULL)) { #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA256 DMA UPDATE: inAddr=%p, inSz=%u\n", in, inLen); #endif + ret = wh_Client_SendRequest( ctx, group, WC_ALGO_TYPE_HASH, sizeof(whMessageCrypto_GenericRequestHeader) + sizeof(*req), @@ -2798,14 +2826,7 @@ int wh_Client_Sha256Dma(whClientContext* ctx, wc_Sha256* sha, const uint8_t* in, * wc_CryptoCb_Sha256Hash(sha256, NULL, 0, * hash) */ if ((ret == WH_ERROR_OK) && (out != NULL)) { /* Packet will have been trashed, so re-populate all fields */ - req->finalize = 1; - req->state.addr = (uint64_t)(uintptr_t)sha256; - req->state.sz = sizeof(*sha256); - req->input.addr = (uint64_t)(uintptr_t)in; - req->input.sz = inLen; - req->output.addr = (uint64_t)(uintptr_t)out; - req->output.sz = WC_SHA256_DIGEST_SIZE; /* not needed, but YOLO */ - + req->finalize = 1; #ifdef DEBUG_CRYPTOCB_VERBOSE printf("[client] SHA256 DMA FINAL: outAddr=%p\n", out); #endif @@ -2833,8 +2854,25 @@ int wh_Client_Sha256Dma(whClientContext* ctx, wc_Sha256* sha, const uint8_t* in, } } + /* This is called regardless of successful operation to give the callback a + * chance for cleanup. i.e if XMALLOC had been used and XFREE call is + * needed. Don't override return value with closing process address calls.*/ + if (in != NULL || out != NULL) { + /* post operation address translations */ + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)sha256, (void**)&stateAddr, req->state.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)in, (void**)&inAddr, req->input.sz, + WH_DMA_OPER_CLIENT_READ_POST, (whDmaFlags){0}); + (void)wh_Client_DmaProcessClientAddress( + ctx, (uintptr_t)out, (void**)&outAddr, req->output.sz, + WH_DMA_OPER_CLIENT_WRITE_POST, (whDmaFlags){0}); + } + return ret; } +#endif /* WOLFHSM_CFG_DMA */ #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA224 diff --git a/src/wh_client_dma.c b/src/wh_client_dma.c new file mode 100644 index 00000000..7dee4bef --- /dev/null +++ b/src/wh_client_dma.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 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 . + */ +/* + * src/wh_client_dma.c + */ + +/* Pick up compile-time configuration */ +#include "wolfhsm/wh_settings.h" + +#ifdef WOLFHSM_CFG_DMA + +#include +#include +#include + +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_client.h" + + +int wh_Client_DmaRegisterAllowList(whClientContext* client, + const whDmaAddrAllowList* allowlist) +{ + if (NULL == client || NULL == allowlist) { + return WH_ERROR_BADARGS; + } + + client->dma.dmaAddrAllowList = allowlist; + + return WH_ERROR_OK; +} + +int wh_Client_DmaRegisterCb(whClientContext* client, whClientDmaClientMemCb cb) +{ + /* No NULL check for cb, since it is optional and always NULL checked before + * it is called */ + if (NULL == client) { + return WH_ERROR_BADARGS; + } + + client->dma.cb = cb; + + return WH_ERROR_OK; +} + + +/* Processes the given client address and translates it into a value that the + * server will understand. This can be used to map the address into a known + * location of shared memory. This also handles post translate operations + * given the whDmaOper passed in. */ +int wh_Client_DmaProcessClientAddress(whClientContext* client, + uintptr_t clientAddr, + void** xformedCliAddr, size_t len, + whDmaOper oper, whDmaFlags flags) +{ + int rc = WH_ERROR_OK; + + if (NULL == xformedCliAddr) { + return WH_ERROR_BADARGS; + } + + /* Perform user-supplied address transformation, cache manipulation, etc */ + if (NULL != client->dma.cb) { + rc = client->dma.cb(client, clientAddr, xformedCliAddr, len, oper, + flags); + if (rc != WH_ERROR_OK) { + return rc; + } + } + else { + /* Transformed address defaults to raw client address */ + *xformedCliAddr = (void*)((uintptr_t)clientAddr); + } + + /* if the client has a allowlist registered, check address against it */ + if (rc == WH_ERROR_OK && len > 0) { + rc = wh_Dma_CheckMemOperAgainstAllowList(client->dma.dmaAddrAllowList, + oper, *xformedCliAddr, len); + } + return rc; +} +#endif /* WOLFHSM_CFG_DMA */ diff --git a/src/wh_comm.c b/src/wh_comm.c index 4b0acafd..b8e4f647 100644 --- a/src/wh_comm.c +++ b/src/wh_comm.c @@ -101,11 +101,9 @@ int wh_CommClient_SendRequest(whCommClient* context, uint16_t magic, { int rc = 0; - if ( (context == NULL) || - (context->hdr == NULL) || - (context->initialized == 0) || - (context->transport_cb == NULL) || - (context->transport_cb->Send == NULL)) { + if ((context == NULL) || (context->hdr == NULL) || + (context->initialized == 0) || (context->transport_cb == NULL) || + (context->transport_cb->Send == NULL)) { return WH_ERROR_BADARGS; } @@ -146,11 +144,9 @@ int wh_CommClient_RecvResponse(whCommClient* context, uint16_t size = sizeof(context->packet); uint16_t data_size = 0; - if ( (context == NULL) || - (context->hdr == NULL) || - (context->initialized == 0) || - (context->transport_cb == NULL) || - (context->transport_cb->Recv == NULL)){ + if ((context == NULL) || (context->hdr == NULL) || + (context->initialized == 0) || (context->transport_cb == NULL) || + (context->transport_cb->Recv == NULL)) { return WH_ERROR_BADARGS; } @@ -258,11 +254,9 @@ int wh_CommServer_RecvRequest(whCommServer* context, uint16_t size = sizeof(context->packet); uint16_t data_size = 0; - if ( (context == NULL) || - (context->hdr == NULL) || - (context->initialized == 0) || - (context->transport_cb == NULL) || - (context->transport_cb->Recv == NULL)) { + if ((context == NULL) || (context->hdr == NULL) || + (context->initialized == 0) || (context->transport_cb == NULL) || + (context->transport_cb->Recv == NULL)) { return WH_ERROR_BADARGS; } @@ -300,11 +294,9 @@ int wh_CommServer_SendResponse(whCommServer* context, { int rc = 0; - if ( (context == NULL) || - (context->hdr == NULL) || - (context->initialized == 0) || - (context->transport_cb == NULL) || - (context->transport_cb->Send == NULL)){ + if ((context == NULL) || (context->hdr == NULL) || + (context->initialized == 0) || (context->transport_cb == NULL) || + (context->transport_cb->Send == NULL)) { return WH_ERROR_BADARGS; } diff --git a/src/wh_dma.c b/src/wh_dma.c new file mode 100644 index 00000000..a99fddcc --- /dev/null +++ b/src/wh_dma.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2024 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 . + */ +/* + * src/wh_dma.c + */ + +/* Pick up compile-time configuration */ +#include "wolfhsm/wh_settings.h" + +#ifdef WOLFHSM_CFG_DMA + +#include +#include +#include + +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_dma.h" + +/* internal DMA function declarations */ +static int _checkOperValid(whDmaOper oper); +static int _checkAddrAgainstAllowList(const whDmaAddrList allowList, void* addr, + size_t size); + +static int _checkOperValid(whDmaOper oper) +{ + if (oper < WH_DMA_OPER_CLIENT_READ_PRE || + oper > WH_DMA_OPER_CLIENT_WRITE_POST) { + return WH_ERROR_BADARGS; + } + + return WH_ERROR_OK; +} + +static int _checkAddrAgainstAllowList(const whDmaAddrList allowList, void* addr, + size_t size) +{ + uintptr_t startAddr = (uintptr_t)addr; + uintptr_t endAddr = startAddr + size; + int i = 0; + + if (0 == size) { + return WH_ERROR_BADARGS; + } + + /* Check if the address range is fully within a allowlist entry */ + for (i = 0; i < WOLFHSM_CFG_DMAADDR_COUNT; i++) { + uintptr_t allowListStartAddr = (uintptr_t)allowList[i].addr; + uintptr_t allowListEndAddr = allowListStartAddr + allowList[i].size; + + if (0 == allowList[i].size) { + continue; + } + + if (startAddr >= allowListStartAddr && endAddr <= allowListEndAddr) { + return WH_ERROR_OK; + } + } + + return WH_ERROR_ACCESS; +} + + +static int _checkMemOperAgainstAllowList(const whDmaAddrAllowList* allowlist, + whDmaOper oper, void* addr, + size_t size) +{ + int rc = WH_ERROR_OK; + + rc = _checkOperValid(oper); + if (rc != WH_ERROR_OK) { + return rc; + } + + /* If no allowlist is registered, anything goes */ + if (allowlist == NULL) { + return WH_ERROR_OK; + } + + /* If a read/write operation is requested, check the transformed address + * against the appropriate allowlist + * + * TODO: do we need to allowlist check on POST in case there are subsequent + * memory operations for some reason? + */ + if (oper == WH_DMA_OPER_CLIENT_READ_PRE) { + rc = _checkAddrAgainstAllowList(allowlist->readList, addr, size); + } + else if (oper == WH_DMA_OPER_CLIENT_WRITE_PRE) { + rc = _checkAddrAgainstAllowList(allowlist->writeList, addr, size); + } + + return rc; +} + + +int wh_Dma_CheckMemOperAgainstAllowList(const whDmaAddrAllowList* allowlist, + whDmaOper oper, void* addr, size_t size) +{ + if (0 == size) { + return WH_ERROR_BADARGS; + } + + return _checkMemOperAgainstAllowList(allowlist, oper, addr, size); +} + +#endif /* WOLFHSM_CFG_DMA */ diff --git a/src/wh_server.c b/src/wh_server.c index c33f0c51..8ce2902b 100644 --- a/src/wh_server.c +++ b/src/wh_server.c @@ -121,6 +121,7 @@ int wh_Server_Cleanup(whServerContext* server) return WH_ERROR_OK; } + int wh_Server_SetConnected(whServerContext *server, whCommConnected connected) { if (server == NULL) { @@ -212,7 +213,7 @@ static int _wh_Server_HandleCommRequest(whServerContext* server, resp.cfg_comm_data_len = WOLFHSM_CFG_COMM_DATA_LEN; resp.cfg_nvm_object_count = WOLFHSM_CFG_NVM_OBJECT_COUNT; resp.cfg_server_customcb_count = WOLFHSM_CFG_SERVER_CUSTOMCB_COUNT; - resp.cfg_server_dmaaddr_count = WOLFHSM_CFG_SERVER_DMAADDR_COUNT; + resp.cfg_server_dmaaddr_count = WOLFHSM_CFG_DMAADDR_COUNT; resp.cfg_server_keycache_bufsize = WOLFHSM_CFG_SERVER_KEYCACHE_BUFSIZE; resp.cfg_server_keycache_count = WOLFHSM_CFG_SERVER_KEYCACHE_COUNT; resp.cfg_server_keycache_bigbufsize = WOLFHSM_CFG_SERVER_KEYCACHE_BIG_BUFSIZE; diff --git a/src/wh_server_crypto.c b/src/wh_server_crypto.c index b98e2df4..e794a84d 100644 --- a/src/wh_server_crypto.c +++ b/src/wh_server_crypto.c @@ -2908,7 +2908,7 @@ int wh_Server_HandleCryptoRequest(whServerContext* ctx, uint16_t magic, /* Propagate error code to client in response packet header. Crypto handlers * have already populated the response packet with the output data. */ - respHeader.rc = ret; + respHeader.rc = ret; respHeader.algoType = rqstHeader.algoType; wh_MessageCrypto_TranslateGenericResponseHeader( magic, &respHeader, @@ -2946,11 +2946,11 @@ static int _HandleSha256Dma(whServerContext* ctx, uint16_t magic, uint16_t seq, (void)seq; (void)inSize; - int ret = 0; - whMessageCrypto_Sha2DmaRequest req; - whMessageCrypto_Sha2DmaResponse res; - wc_Sha256 sha256[1]; - int clientDevId; + int ret = 0; + whMessageCrypto_Sha2DmaRequest req; + whMessageCrypto_Sha2DmaResponse res; + wc_Sha256 sha256[1]; + int clientDevId; /* Translate the request */ ret = wh_MessageCrypto_TranslateSha2DmaRequest( diff --git a/src/wh_server_dma.c b/src/wh_server_dma.c index 718841fb..46b71f6d 100644 --- a/src/wh_server_dma.c +++ b/src/wh_server_dma.c @@ -33,80 +33,6 @@ #include "wolfhsm/wh_server.h" -/* TODO: if the Address allowlist ever gets large, we should consider a more - * efficient representation (requiring sorted array and binary search, or - * building a binary tree, etc.) */ - -static int _checkOperValid(whServerDmaOper oper) -{ - if (oper < WH_DMA_OPER_CLIENT_READ_PRE || - oper > WH_DMA_OPER_CLIENT_WRITE_POST) { - return WH_ERROR_BADARGS; - } - - return WH_ERROR_OK; -} - -static int _checkAddrAgainstAllowList(const whServerDmaAddrList allowList, void* addr, - size_t size) -{ - uintptr_t startAddr = (uintptr_t)addr; - uintptr_t endAddr = startAddr + size; - int i = 0; - - if (0 == size) { - return WH_ERROR_BADARGS; - } - - /* Check if the address range is fully within a allowlist entry */ - for (i = 0; i < WOLFHSM_CFG_SERVER_DMAADDR_COUNT; i++) { - uintptr_t allowListStartAddr = (uintptr_t)allowList[i].addr; - uintptr_t allowListEndAddr = allowListStartAddr + allowList[i].size; - - if (0 == allowList[i].size) { - continue; - } - - if (startAddr >= allowListStartAddr && endAddr <= allowListEndAddr) { - return WH_ERROR_OK; - } - } - - return WH_ERROR_ACCESS; -} - -static int _checkMemOperAgainstAllowList(const whServerContext* server, - whServerDmaOper oper, void* addr, - size_t size) -{ - int rc = WH_ERROR_OK; - - rc = _checkOperValid(oper); - if (rc != WH_ERROR_OK) { - return rc; - } - - /* If no allowlist is registered, anything goes */ - if (server->dma.dmaAddrAllowList == NULL) { - return WH_ERROR_OK; - } - - /* If a read/write operation is requested, check the transformed address - * against the appropriate allowlist - * - * TODO: do we need to allowlist check on POST in case there are subsequent - * memory operations for some reason? - */ - if (oper == WH_DMA_OPER_CLIENT_READ_PRE) { - rc = _checkAddrAgainstAllowList(server->dma.dmaAddrAllowList->readList, addr, size); - } - else if (oper == WH_DMA_OPER_CLIENT_WRITE_PRE) { - rc = _checkAddrAgainstAllowList(server->dma.dmaAddrAllowList->writeList, addr, size); - } - - return rc; -} - int wh_Server_DmaCheckMemOperAllowed(const whServerContext* server, whServerDmaOper oper, void* addr, size_t size) { @@ -115,7 +41,8 @@ int wh_Server_DmaCheckMemOperAllowed(const whServerContext* server, return WH_ERROR_BADARGS; } - return _checkMemOperAgainstAllowList(server, oper, addr, size); + return wh_Dma_CheckMemOperAgainstAllowList(server->dma.dmaAddrAllowList, + oper, addr, size); } int wh_Server_DmaRegisterCb(whServerContext* server, whServerDmaClientMemCb cb) @@ -184,7 +111,11 @@ int wh_Server_DmaProcessClientAddress(whServerContext* server, } /* if the server has a allowlist registered, check address against it */ - return _checkMemOperAgainstAllowList(server, oper, *xformedCliAddr, len); + if (rc == WH_ERROR_OK && len > 0) { + rc = wh_Dma_CheckMemOperAgainstAllowList(server->dma.dmaAddrAllowList, + oper, *xformedCliAddr, len); + } + return rc; } int whServerDma_CopyFromClient(struct whServerContext_t* server, @@ -200,8 +131,9 @@ int whServerDma_CopyFromClient(struct whServerContext_t* server, } /* Check the server address against the allow list */ - rc = _checkMemOperAgainstAllowList(server, WH_DMA_OPER_CLIENT_READ_PRE, - serverPtr, len); + rc = wh_Dma_CheckMemOperAgainstAllowList(server->dma.dmaAddrAllowList, + WH_DMA_OPER_CLIENT_READ_PRE, + serverPtr, len); if (rc != WH_ERROR_OK) { return rc; } @@ -253,8 +185,9 @@ int whServerDma_CopyToClient(struct whServerContext_t* server, } /* Check the server address against the allow list */ - rc = _checkMemOperAgainstAllowList(server, WH_DMA_OPER_CLIENT_WRITE_PRE, - serverPtr, len); + rc = wh_Dma_CheckMemOperAgainstAllowList(server->dma.dmaAddrAllowList, + WH_DMA_OPER_CLIENT_WRITE_PRE, + serverPtr, len); if (rc != WH_ERROR_OK) { return rc; } diff --git a/src/wh_transport_mem.c b/src/wh_transport_mem.c index 2ec2d767..92e74d4c 100644 --- a/src/wh_transport_mem.c +++ b/src/wh_transport_mem.c @@ -142,7 +142,7 @@ int wh_TransportMem_SendRequest(void* c, uint16_t len, const void* data) return 0; } -int wh_TransportMem_RecvResponse(void* c, uint16_t *out_len, void* data) +int wh_TransportMem_RecvResponse(void* c, uint16_t* out_len, void* data) { whTransportMemContext* context = c; volatile whTransportMemCsr* ctx_req; @@ -165,7 +165,7 @@ int wh_TransportMem_RecvResponse(void* c, uint16_t *out_len, void* data) resp.u64 = ctx_resp->u64; /* Check to see if the current response is the different than the request */ - if(resp.s.notify != req.s.notify) { + if (resp.s.notify != req.s.notify) { return WH_ERROR_NOTREADY; } @@ -226,7 +226,7 @@ int wh_TransportMem_SendResponse(void* c, uint16_t len, const void* data) return 0; } -int wh_TransportMem_RecvRequest(void* c, uint16_t *out_len, void* data) +int wh_TransportMem_RecvRequest(void* c, uint16_t* out_len, void* data) { whTransportMemContext* context = c; volatile whTransportMemCsr* ctx_req; @@ -249,7 +249,7 @@ int wh_TransportMem_RecvRequest(void* c, uint16_t *out_len, void* data) resp.u64 = ctx_resp->u64; /* Check to see if a new request has arrived */ - if(req.s.notify == resp.s.notify) { + if (req.s.notify == resp.s.notify) { return WH_ERROR_NOTREADY; } diff --git a/test/config/user_settings.h b/test/config/user_settings.h index fa136ecd..838d050f 100644 --- a/test/config/user_settings.h +++ b/test/config/user_settings.h @@ -45,7 +45,6 @@ #define WOLFSSL_IGNORE_FILE_WARN - /* For cert manager */ #define NO_TLS /* Eliminates need for IO layer since we only use CM */ diff --git a/test/config/wolfhsm_cfg.h b/test/config/wolfhsm_cfg.h index 36d3ce8b..759a70e7 100644 --- a/test/config/wolfhsm_cfg.h +++ b/test/config/wolfhsm_cfg.h @@ -37,7 +37,7 @@ #define WOLFHSM_CFG_SERVER_KEYCACHE_BUFSIZE 300 #define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_COUNT 2 #define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_BUFSIZE WOLFHSM_CFG_COMM_DATA_LEN -#define WOLFHSM_CFG_SERVER_DMAADDR_COUNT 8 +#define WOLFHSM_CFG_DMAADDR_COUNT 8 #define WOLFHSM_CFG_SERVER_CUSTOMCB_COUNT 6 #define WOLFHSM_CFG_CERTIFICATE_MANAGER diff --git a/test/wh_test.c b/test/wh_test.c index c3fabd41..6c33f5bd 100644 --- a/test/wh_test.c +++ b/test/wh_test.c @@ -138,7 +138,7 @@ int whTest_ClientTcp(void) { /* Client configuration/contexts */ whTransportClientCb pttccb[1] = {PTT_CLIENT_CB}; - posixTransportTcpClientContext tcc[1] = {}; + posixTransportTcpClientContext tcc[1] = {0}; posixTransportTcpConfig mytcpconfig[1] = {{ .server_ip_string = "127.0.0.1", .server_port = 23456, diff --git a/test/wh_test_cert.c b/test/wh_test_cert.c index ed7060c6..8c2e0d4f 100644 --- a/test/wh_test_cert.c +++ b/test/wh_test_cert.c @@ -644,7 +644,7 @@ int whTest_CertRamSim(void) }}; printf("Testing Server Certificate with RAM sim...\n"); - + /* Initialize NVM */ WH_TEST_RETURN_ON_FAIL(wh_Nvm_Init(nvm, n_conf)); #ifndef WOLFHSM_CFG_NO_CRYPTO diff --git a/test/wh_test_clientserver.c b/test/wh_test_clientserver.c index 8e953f61..582c8fc1 100644 --- a/test/wh_test_clientserver.c +++ b/test/wh_test_clientserver.c @@ -742,11 +742,11 @@ int whTest_ClientServerSequential(void) }}; #endif - whServerConfig s_conf[1] = {{ - .comm_config = cs_conf, - .nvm = nvm, + whServerConfig s_conf[1] = {{ + .comm_config = cs_conf, + .nvm = nvm, #ifndef WOLFHSM_CFG_NO_CRYPTO - .crypto = crypto, + .crypto = crypto, #endif }}; whServerContext server[1] = {0}; @@ -1772,12 +1772,13 @@ static int wh_ClientServer_MemThreadTest(void) }}; #endif + whServerConfig s_conf[1] = {{ .comm_config = cs_conf, .nvm = nvm, #ifndef WOLFHSM_CFG_NO_CRYPTO .crypto = crypto, - .devId = INVALID_DEVID, + .devId = INVALID_DEVID, #endif }}; @@ -1865,11 +1866,11 @@ static int wh_ClientServer_PosixMemMapThreadTest(void) }}; #endif - whServerConfig s_conf[1] = {{ - .comm_config = cs_conf, - .nvm = nvm, + whServerConfig s_conf[1] = {{ + .comm_config = cs_conf, + .nvm = nvm, #ifndef WOLFHSM_CFG_NO_CRYPTO - .crypto = crypto, + .crypto = crypto, #endif }}; diff --git a/test/wh_test_comm.c b/test/wh_test_comm.c index 3c292b36..f3f3ebf2 100644 --- a/test/wh_test_comm.c +++ b/test/wh_test_comm.c @@ -44,11 +44,11 @@ #if defined(WOLFHSM_CFG_TEST_POSIX) #include /* For pthread_create/cancel/join/_t */ #include -#include /* For nanosleep */ +#include /* For nanosleep */ #include "port/posix/posix_transport_tcp.h" #include "port/posix/posix_transport_shm.h" -const struct timespec ONE_MS = { .tv_sec = 0, .tv_nsec = 1000000 }; +const struct timespec ONE_MS = {.tv_sec = 0, .tv_nsec = 1000000}; #endif #include "wh_test_comm.h" @@ -400,7 +400,7 @@ void wh_CommClientServer_MemThreadTest(void) /* Client configuration/contexts */ whTransportClientCb tmccb[1] = {WH_TRANSPORT_MEM_CLIENT_CB}; - whTransportMemClientContext csc[1] = {}; + whTransportMemClientContext csc[1] = {0}; whCommClientConfig c_conf[1] = {{ .transport_cb = tmccb, .transport_context = (void*)csc, @@ -410,7 +410,7 @@ void wh_CommClientServer_MemThreadTest(void) /* Server configuration/contexts */ whTransportServerCb tmscb[1] = {WH_TRANSPORT_MEM_SERVER_CB}; - whTransportMemServerContext css[1] = {}; + whTransportMemServerContext css[1] = {0}; whCommServerConfig s_conf[1] = {{ .transport_cb = tmscb, .transport_context = (void*)css, @@ -439,7 +439,7 @@ void wh_CommClientServer_ShMemThreadTest(void) /* Client configuration/contexts */ whTransportClientCb tmccb[1] = {POSIX_TRANSPORT_SHM_CLIENT_CB}; - posixTransportShmClientContext csc[1] = {}; + posixTransportShmClientContext csc[1] = {0}; whCommClientConfig c_conf[1] = {{ .transport_cb = tmccb, .transport_context = (void*)csc, @@ -449,7 +449,7 @@ void wh_CommClientServer_ShMemThreadTest(void) /* Server configuration/contexts */ whTransportServerCb tmscb[1] = {POSIX_TRANSPORT_SHM_SERVER_CB}; - posixTransportShmServerContext css[1] = {}; + posixTransportShmServerContext css[1] = {0}; whCommServerConfig s_conf[1] = {{ .transport_cb = tmscb, .transport_context = (void*)css, @@ -470,7 +470,7 @@ void wh_CommClientServer_TcpThreadTest(void) /* Client configuration/contexts */ whTransportClientCb pttccb[1] = {PTT_CLIENT_CB}; - posixTransportTcpClientContext tcc[1] = {}; + posixTransportTcpClientContext tcc[1] = {0}; whCommClientConfig c_conf[1] = {{ .transport_cb = pttccb, .transport_context = (void*)tcc, @@ -481,7 +481,7 @@ void wh_CommClientServer_TcpThreadTest(void) /* Server configuration/contexts */ whTransportServerCb pttscb[1] = {PTT_SERVER_CB}; - posixTransportTcpServerContext tss[1] = {}; + posixTransportTcpServerContext tss[1] = {0}; whCommServerConfig s_conf[1] = {{ .transport_cb = pttscb, .transport_context = (void*)tss, diff --git a/test/wh_test_common.h b/test/wh_test_common.h index 5d640355..a6ba3ff2 100644 --- a/test/wh_test_common.h +++ b/test/wh_test_common.h @@ -41,7 +41,9 @@ printf("[%s:%d]: " fmt, __func__, __LINE__, ##__VA_ARGS__) #endif #else -#define WH_DEBUG_PRINT(...) do{} while(0) +#define WH_DEBUG_PRINT(...) \ + do { \ + } while (0) #endif /* Helper macro to print a message, prefixed by ERROR, along with caller source diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index c096347c..54fb1daf 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -3631,9 +3631,16 @@ static int wh_ClientServer_MemThreadTest(void) .transport_config = (void*)tmcf, .client_id = 1, }}; + +#ifdef WOLFHSM_CFG_DMA + whClientDmaConfig clientDmaConfig = {0}; +#endif whClientConfig c_conf[1] = {{ - .comm = cc_conf, - .cancelCb = _cancelCb, + .comm = cc_conf, + .cancelCb = _cancelCb, +#ifdef WOLFHSM_CFG_DMA + .dmaConfig = &clientDmaConfig, +#endif }}; /* Server configuration/contexts */ whTransportServerCb tscb[1] = {WH_TRANSPORT_MEM_SERVER_CB}; @@ -3678,11 +3685,12 @@ static int wh_ClientServer_MemThreadTest(void) .devId = INVALID_DEVID, }}; - whServerConfig s_conf[1] = {{ - .comm_config = cs_conf, - .nvm = nvm, - .crypto = crypto, - .devId = INVALID_DEVID, + + whServerConfig s_conf[1] = {{ + .comm_config = cs_conf, + .nvm = nvm, + .crypto = crypto, + .devId = INVALID_DEVID, }}; WH_TEST_RETURN_ON_FAIL(wh_Nvm_Init(nvm, n_conf)); diff --git a/tools/whnvmtool/whnvmtool.c b/tools/whnvmtool/whnvmtool.c index deb8e62b..319b69ec 100644 --- a/tools/whnvmtool/whnvmtool.c +++ b/tools/whnvmtool/whnvmtool.c @@ -565,7 +565,9 @@ int main(int argc, char* argv[]) .she = NULL, #endif /* WOLFHSM_CFG_SHE_EXTENSION */ #endif /* WOLFHSM_CFG_NO_CRYPTO */ +#ifdef WOLFHSM_CFG_DMA .dmaConfig = NULL, +#endif /* WOLFHSM_CFG_DMA */ }; whServerContext gServerContext = {0}; diff --git a/wolfhsm/wh_client.h b/wolfhsm/wh_client.h index 33498349..f73e23fc 100644 --- a/wolfhsm/wh_client.h +++ b/wolfhsm/wh_client.h @@ -49,10 +49,17 @@ /* Component includes */ #include "wolfhsm/wh_comm.h" #include "wolfhsm/wh_message_customcb.h" +#ifdef WOLFHSM_CFG_DMA +#include "wolfhsm/wh_dma.h" +#endif /* WOLFHSM_CFG_DMA */ /* WolfCrypt types and defines */ #include "wolfssl/wolfcrypt/types.h" +/* Forward declaration of the client structure so its elements can reference + * itself (e.g. server argument to custom callback) */ +typedef struct whClientContext_t whClientContext; + #ifndef WOLFHSM_CFG_NO_CRYPTO /* Device Id to be registered and passed to wolfCrypt functions */ @@ -68,6 +75,26 @@ enum WH_CLIENT_DEVID_ENUM { extern const int WH_DEV_IDS_ARRAY[WH_NUM_DEVIDS]; #endif +/** Client DMA address translation and validation */ +#ifdef WOLFHSM_CFG_DMA +typedef int (*whClientDmaClientMemCb)(struct whClientContext_t* client, + uintptr_t clientAddr, void** ptr, + size_t len, whDmaOper oper, + whDmaFlags flags); + +/* Common DMA callback types and structures */ +typedef struct { + whClientDmaClientMemCb cb; + const whDmaAddrAllowList* dmaAddrAllowList; /* allowed addresses */ +} whClientDmaConfig; + +typedef struct { + whClientDmaClientMemCb cb; + const whDmaAddrAllowList* dmaAddrAllowList; /* allowed addresses */ + void* heap; /* heap hint for using static memory (or other allocator) */ +} whClientDmaContext; +#endif /* WOLFHSM_CFG_DMA */ + /** * Out of band callback function to inform the server to cancel a request, * internal logic is provided by the port code. @@ -84,12 +111,17 @@ struct whClientContext_t { uint8_t cancelable; whCommClient comm[1]; whClientCancelCb cancelCb; +#ifdef WOLFHSM_CFG_DMA + whClientDmaContext dma; +#endif /* WOLFHSM_CFG_DMA */ }; -typedef struct whClientContext_t whClientContext; struct whClientConfig_t { whCommClientConfig* comm; whClientCancelCb cancelCb; +#ifdef WOLFHSM_CFG_DMA + whClientDmaConfig* dmaConfig; +#endif /* WOLFHSM_CFG_DMA */ }; typedef struct whClientConfig_t whClientConfig; @@ -118,7 +150,6 @@ int wh_Client_Init(whClientContext* c, const whClientConfig* config); */ int wh_Client_Cleanup(whClientContext* c); - /** Generic request/response functions */ /** @@ -2387,6 +2418,45 @@ int wh_Client_CertVerifyAcertDmaRequest(whClientContext* c, const void* cert, int wh_Client_CertVerifyAcertDmaResponse(whClientContext* c, int32_t* out_rc); #if defined(WOLFHSM_CFG_DMA) +/** + * @brief Registers a custom client DMA callback + * + * This function allows the client to register a custom callback handler + * for processing memory operations. The callback will be invoked during + * DMA operations to transform client addresses, manipulate caches, etc. + * + * @param[in] client Pointer to the client context. + * @param[in] cb The custom DMA callback handler to register. + * @return int Returns WH_ERROR_OK on success, or WH_ERROR_BADARGS if the + * arguments are invalid. + */ +int wh_Client_DmaRegisterCb(struct whClientContext_t* client, + whClientDmaClientMemCb cb); + + +/** + * @brief Processes a client address for DMA operations, using the native + * pointer size of the system + * + * This function transforms a client address for DMA operations. It performs + * user-supplied address transformations, cache manipulations, and checks the + * transformed address against the client's allowlist if registered. + * + * @param[in] client Pointer to the client context. + * @param[in] clientAddr The client address to be processed. + * @param[out] serverPtr Pointer to store the transformed server address. + * @param[in] len The length of the memory operation. + * @param[in] oper The DMA operation type (e.g., read or write). + * @param[in] flags Flags for the DMA operation. + * @return int Returns WH_ERROR_OK on success, WH_ERROR_BADARGS if the arguments + * are invalid, or a negative error code on failure. + */ +int wh_Client_DmaProcessClientAddress(struct whClientContext_t* client, + uintptr_t clientAddr, void** serverPtr, + size_t len, whDmaOper oper, + whDmaFlags flags); + + /** * @brief Sends a DMA request and receives a response to verify an attribute * certificate. diff --git a/wolfhsm/wh_dma.h b/wolfhsm/wh_dma.h new file mode 100644 index 00000000..32d0fa68 --- /dev/null +++ b/wolfhsm/wh_dma.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 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 . + */ +/* + * wolfhsm/wh_dma.h + * + * Common DMA API for client and server + */ + +#include +#include + +#ifndef WOLFHSM_WH_COMMON_DMA_H_ +#define WOLFHSM_WH_COMMON_DMA_H_ + +/* Pick up compile-time configuration */ +#include "wolfhsm/wh_settings.h" + +/* This is the same for both client and server, the client cares about when the + * server is about to access its memory and the server cares about when it is + * about to access the clients memory. */ +typedef enum { + /* Indicates server is about to read from client memory */ + WH_DMA_OPER_CLIENT_READ_PRE = 0, + /* Indicates server has just read from client memory */ + WH_DMA_OPER_CLIENT_READ_POST = 1, + /* Indicates server is about to write to client memory */ + WH_DMA_OPER_CLIENT_WRITE_PRE = 2, + /* Indicates server has just written to client memory */ + WH_DMA_OPER_CLIENT_WRITE_POST = 3, +} whDmaOper; + +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY +typedef enum { + WH_DMA_COPY_OPER_CLIENT_READ = 0, + WH_DMA_COPY_OPER_CLIENT_WRITE = 1, +} whDmaCopyOper; +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ + +/* Flags embedded in request/response structs provided by client */ +typedef struct { + uint8_t cacheForceInvalidate : 1; + uint8_t : 7; +} whDmaFlags; + +/* Common DMA address entry within the allowed tables */ +typedef struct { + void* addr; + size_t size; +} whDmaAddr; +typedef whDmaAddr whDmaAddrList[WOLFHSM_CFG_DMAADDR_COUNT]; + +/* Holds allowable client read/write addresses */ +typedef struct { + whDmaAddrList readList; /* Allowed client read addresses */ + whDmaAddrList writeList; /* Allowed client write addresses */ +} whDmaAddrAllowList; + +int wh_Dma_CheckMemOperAgainstAllowList(const whDmaAddrAllowList* allowlist, + whDmaOper oper, void* addr, size_t len); + +#endif /* WOLFHSM_WH_COMMON_DMA_H_ */ diff --git a/wolfhsm/wh_server.h b/wolfhsm/wh_server.h index 9ccec52d..546f6145 100644 --- a/wolfhsm/wh_server.h +++ b/wolfhsm/wh_server.h @@ -40,6 +40,9 @@ typedef struct whServerContext_t whServerContext; #include "wolfhsm/wh_comm.h" #include "wolfhsm/wh_nvm.h" #include "wolfhsm/wh_message_customcb.h" +#ifdef WOLFHSM_CFG_DMA +#include "wolfhsm/wh_dma.h" +#endif /* WOLFHSM_CFG_DMA */ #ifndef WOLFHSM_CFG_NO_CRYPTO #include "wolfssl/wolfcrypt/settings.h" @@ -109,22 +112,14 @@ typedef int (*whServerCustomCb)( /** Server DMA address translation and validation */ +#ifdef WOLFHSM_CFG_DMA -/* Indicates to a DMA callback the type of memory operation the callback must - * act on. Common use cases are remapping client addresses into server address - * space (map in READ_PRE/WRITE_PRE, unmap in READ_POST/WRITE_POST), or - * invalidating a cache block before reading from or after writing to client - * memory */ -typedef enum { - /* Indicates server is about to read from client memory */ - WH_DMA_OPER_CLIENT_READ_PRE = 0, - /* Indicates server has just read from client memory */ - WH_DMA_OPER_CLIENT_READ_POST = 1, - /* Indicates server is about to write to client memory */ - WH_DMA_OPER_CLIENT_WRITE_PRE = 2, - /* Indicates server has just written from client memory */ - WH_DMA_OPER_CLIENT_WRITE_POST = 3, -} whServerDmaOper; +/* Maintain existing naming for common DMA types */ +typedef whDmaAddrAllowList whServerDmaAddrAllowList; +typedef whDmaOper whServerDmaOper; +typedef whDmaFlags whServerDmaFlags; +typedef whDmaAddr whServerDmaAddr; +typedef whDmaAddrList whServerDmaAddrList; #ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY typedef enum { @@ -133,12 +128,6 @@ typedef enum { } whServerDmaCopyOper; #endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ -/* Flags embedded in request/response structs provided by client */ -typedef struct { - uint8_t cacheForceInvalidate : 1; - uint8_t : 7; -} whServerDmaFlags; - /* DMA callbacks invoked internally by wolfHSM before and after every client * memory operation. */ typedef int (*whServerDmaClientMemCb)(struct whServerContext_t* server, @@ -154,21 +143,6 @@ typedef int (*whServerDmaMemCopyCb)(struct whServerContext_t* server, whServerDmaFlags flags); #endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ -/* DMA address entry within the allowed tables. */ -/* Note: These are translated addresses from the Server's perspective*/ -typedef struct { - void* addr; - size_t size; -} whServerDmaAddr; - -typedef whServerDmaAddr whServerDmaAddrList[WOLFHSM_CFG_SERVER_DMAADDR_COUNT]; - -/* Holds allowable client read/write addresses */ -typedef struct { - whServerDmaAddrList readList; /* Allowed client read addresses */ - whServerDmaAddrList writeList; /* Allowed client write addresses */ -} whServerDmaAddrAllowList; - /* Server DMA configuration struct for initializing a server */ typedef struct { whServerDmaClientMemCb cb; /* DMA callback */ @@ -185,7 +159,7 @@ typedef struct { #endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ const whServerDmaAddrAllowList* dmaAddrAllowList; /* allowed addresses */ } whServerDmaContext; - +#endif /* WOLFHSM_CFG_DMA */ /** Server config and context */ @@ -202,7 +176,9 @@ typedef struct whServerConfig_t { int devId; #endif /* WOLF_CRYPTO_CB */ #endif /* !WOLFHSM_CFG_NO_CRYPTO */ +#ifdef WOLFHSM_CFG_DMA whServerDmaConfig* dmaConfig; +#endif /* WOLFHSM_CFG_DMA */ } whServerConfig; @@ -219,7 +195,9 @@ struct whServerContext_t { #endif #endif /* !WOLFHSM_CFG_NO_CRYPTO */ whServerCustomCb customHandlerTable[WOLFHSM_CFG_SERVER_CUSTOMCB_COUNT]; +#ifdef WOLFHSM_CFG_DMA whServerDmaContext dma; +#endif /* WOLFHSM_CFG_DMA */ int connected; uint16_t cancelSeq; }; diff --git a/wolfhsm/wh_settings.h b/wolfhsm/wh_settings.h index 1c6f9c5a..8cc9eb38 100644 --- a/wolfhsm/wh_settings.h +++ b/wolfhsm/wh_settings.h @@ -65,7 +65,7 @@ * WOLFHSM_CFG_SERVER_CUSTOMCB_COUNT - Number of additional callbacks * Default: 8 * - * WOLFHSM_CFG_SERVER_DMAADDR_COUNT - Number of DMA address regions + * WOLFHSM_CFG_DMAADDR_COUNT - Number of DMA address regions * Default: 10 * * WOLFHSM_CFG_SERVER_IMG_MGR_MAX_IMG_COUNT - Maximum number of images that can @@ -179,8 +179,8 @@ #endif /* DMA translation allow entries */ -#ifndef WOLFHSM_CFG_SERVER_DMAADDR_COUNT -#define WOLFHSM_CFG_SERVER_DMAADDR_COUNT 10 +#ifndef WOLFHSM_CFG_DMAADDR_COUNT +#define WOLFHSM_CFG_DMAADDR_COUNT 10 #endif /* Image manager maximum number of images */