From 9a70643f9c7677978ea057912cfbb731398c214b Mon Sep 17 00:00:00 2001 From: Brett Nicholas <7547222+bigbrett@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:54:03 -0700 Subject: [PATCH 1/4] Unify server handler return code processing - handlers should return errors to HandleRequestMessage, which should never fail based on these codes --- src/wh_server.c | 48 +++++++++------ src/wh_server_counter.c | 11 ---- src/wh_server_crypto.c | 21 +------ src/wh_server_keystore.c | 124 +++++++++++++++------------------------ src/wh_server_she.c | 5 +- wolfhsm/wh_error.h | 2 +- 6 files changed, 81 insertions(+), 130 deletions(-) diff --git a/src/wh_server.c b/src/wh_server.c index cf450db7..88279899 100644 --- a/src/wh_server.c +++ b/src/wh_server.c @@ -325,6 +325,7 @@ int wh_Server_HandleRequestMessage(whServerContext* server) uint16_t seq = 0; uint16_t size = 0; uint8_t* data = NULL; + int handlerRc = 0; if (server == NULL) { return WH_ERROR_BADARGS; @@ -342,7 +343,7 @@ int wh_Server_HandleRequestMessage(whServerContext* server) int rc = wh_CommServer_RecvRequest(server->comm, &magic, &kind, &seq, &size, data); /* Got a packet? */ - if (rc == 0) { + if (rc == WH_ERROR_OK) { group = WH_MESSAGE_GROUP(kind); action = WH_MESSAGE_ACTION(kind); switch (group) { @@ -407,33 +408,44 @@ int wh_Server_HandleRequestMessage(whServerContext* server) #endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER && !WOLFHSM_CFG_NO_CRYPTO */ default: - /* Unknown group. Return empty packet*/ - /* TODO: Respond with aux error flag */ + /* Unknown group. Return empty packet */ + rc = WH_ERROR_NOTIMPL; size = 0; } - /* Send a response */ - /* TODO: Respond with ErrorResponse if handler returns an error */ + /* Capture handler result for logging. The response packet already + * contains the error code for the client in the resp.rc field. */ + handlerRc = rc; + + /* Handle cancellation by modifying response kind */ #ifdef WOLFHSM_CFG_CANCEL_API - if (rc == WH_ERROR_CANCEL) { + if (handlerRc == WH_ERROR_CANCEL) { /* notify the client that their request was canceled */ kind = WH_MESSAGE_KIND(WH_MESSAGE_GROUP_CANCEL, 0); size = 0; data = NULL; - /* reset RC so the cancellation response is sent */ - rc = 0; } #endif - if (rc == 0) { - do { - rc = wh_CommServer_SendResponse(server->comm, magic, kind, seq, - size, data); - } while (rc == WH_ERROR_NOTREADY); - } - WH_LOG_ON_ERROR_F( - &server->log, WH_LOG_LEVEL_ERROR, rc, - "Request Handler for (group=%d, action=%d) Returned Error: %d", - group, action, rc); + + /* Always send the response to the client, regardless of handler error. + * The response packet contains the operational error code for the + * client in the resp.rc field. */ + do { + rc = wh_CommServer_SendResponse(server->comm, magic, kind, seq, + size, data); + } while (rc == WH_ERROR_NOTREADY); + + /* Log any communication errors */ + WH_LOG_ON_ERROR_F(&server->log, WH_LOG_LEVEL_ERROR, rc, + "SendResponse failed for (group=%d, action=%d): %d", + group, action, rc); + + (void)handlerRc; /* Suppress unused variable warning until logging is + * implemented */ + + /* Always return success when we processed a request, so no handler + * error can terminate the server's request processing loop. */ + rc = WH_ERROR_OK; } return rc; diff --git a/src/wh_server_counter.c b/src/wh_server_counter.c index b2e33ffb..10c672ce 100644 --- a/src/wh_server_counter.c +++ b/src/wh_server_counter.c @@ -80,8 +80,6 @@ int wh_Server_HandleCounter(whServerContext* server, uint16_t magic, resp.counter = *counter; } resp.rc = ret; - /* TODO: are there any fatal server errors? */ - ret = WH_ERROR_OK; (void)wh_MessageCounter_TranslateInitResponse( magic, &resp, (whMessageCounter_InitResponse*)resp_packet); @@ -139,9 +137,6 @@ int wh_Server_HandleCounter(whServerContext* server, uint16_t magic, magic, &resp, (whMessageCounter_IncrementResponse*)resp_packet); *out_resp_size = sizeof(resp); - - /* TODO: are there any fatal server errors? */ - ret = WH_ERROR_OK; } break; case WH_COUNTER_READ: { @@ -178,9 +173,6 @@ int wh_Server_HandleCounter(whServerContext* server, uint16_t magic, magic, &resp, (whMessageCounter_ReadResponse*)resp_packet); *out_resp_size = sizeof(resp); - - /* TODO: are there any fatal server errors? */ - ret = WH_ERROR_OK; } break; case WH_COUNTER_DESTROY: { @@ -211,9 +203,6 @@ int wh_Server_HandleCounter(whServerContext* server, uint16_t magic, magic, &resp, (whMessageCounter_DestroyResponse*)resp_packet); *out_resp_size = sizeof(resp); - - /* TODO: are there any fatal server errors? */ - ret = WH_ERROR_OK; } break; default: diff --git a/src/wh_server_crypto.c b/src/wh_server_crypto.c index 0719c79b..deeabcee 100644 --- a/src/wh_server_crypto.c +++ b/src/wh_server_crypto.c @@ -4231,16 +4231,6 @@ int wh_Server_HandleCryptoRequest(whServerContext* ctx, uint16_t magic, WH_DEBUG_SERVER_VERBOSE("End ret:%d\n", ret); - /* Since crypto error codes are propagated to the client in the response - * packet, return success to the caller unless a cancellation has occurred - */ -#ifdef WOLFHSM_CFG_CANCEL_API - if (ret != WH_ERROR_CANCEL) { - ret = WH_ERROR_OK; - } -#else - ret = WH_ERROR_OK; -#endif return ret; } @@ -5724,16 +5714,7 @@ int wh_Server_HandleCryptoDmaRequest(whServerContext* ctx, uint16_t magic, WH_DEBUG_SERVER_VERBOSE("Crypto DMA request. Action:%u\n", action); - /* Since crypto error codes are propagated to the client in the response - * packet, return success to the caller unless a cancellation has occurred - */ -#ifdef WOLFHSM_CFG_CANCEL_API - if (ret != WH_ERROR_CANCEL) { - ret = WH_ERROR_OK; - } -#else - ret = WH_ERROR_OK; -#endif + return ret; } #endif /* WOLFHSM_CFG_DMA */ diff --git a/src/wh_server_keystore.c b/src/wh_server_keystore.c index d8960cfa..a2a1857c 100644 --- a/src/wh_server_keystore.c +++ b/src/wh_server_keystore.c @@ -1360,7 +1360,6 @@ static int _HandleDataUnwrapRequest(whServerContext* server, whMessageKeystore_DataUnwrapResponse* resp, uint8_t* respData, uint32_t respDataSz) { - int ret; uint8_t* wrappedData; uint8_t* data; @@ -1380,9 +1379,8 @@ static int _HandleDataUnwrapRequest(whServerContext* server, wrappedData = reqData; /* Translate the server key id passed in from the client */ - serverKeyId = wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, - server->comm->client_id, - req->serverKeyId); + serverKeyId = wh_KeyId_TranslateFromClient( + WH_KEYTYPE_CRYPTO, server->comm->client_id, req->serverKeyId); /* Ensure the cipher type in the response matches the request */ resp->cipherType = req->cipherType; @@ -1474,26 +1472,21 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, if (WH_KEYID_ISERASED(meta->id)) { ret = wh_Server_KeystoreGetUniqueId(server, &meta->id); resp.rc = ret; - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; } /* write the key */ if (ret == WH_ERROR_OK) { ret = wh_Server_KeystoreCacheKey(server, meta, in); resp.rc = ret; - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; } if (ret == WH_ERROR_OK) { /* Translate server keyId back to client format with flags */ resp.id = wh_KeyId_TranslateToClient(meta->id); + } - (void)wh_MessageKeystore_TranslateCacheResponse( - magic, &resp, - (whMessageKeystore_CacheResponse*)resp_packet); + (void)wh_MessageKeystore_TranslateCacheResponse( + magic, &resp, (whMessageKeystore_CacheResponse*)resp_packet); - *out_resp_size = sizeof(resp); - } + *out_resp_size = sizeof(resp); } break; #ifdef WOLFHSM_CFG_DMA @@ -1533,8 +1526,6 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, resp.dmaAddrStatus.badAddr.addr = req.key.addr; resp.dmaAddrStatus.badAddr.sz = req.key.sz; } - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; } /* Translate server keyId back to client format with flags */ @@ -1560,13 +1551,12 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, server->comm->client_id, req.id), req.key.addr, req.key.sz, meta); resp.rc = ret; + /* propagate bad address to client if DMA operation failed */ if (ret != WH_ERROR_OK) { resp.dmaAddrStatus.badAddr.addr = req.key.addr; resp.dmaAddrStatus.badAddr.sz = req.key.sz; } - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; if (ret == WH_ERROR_OK) { resp.len = req.key.sz; @@ -1593,17 +1583,11 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, req.id)); resp.rc = ret; - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; + resp.ok = 0; /* unused */ - if (ret == WH_ERROR_OK) { - resp.ok = 0; - - (void)wh_MessageKeystore_TranslateEvictResponse( - magic, &resp, - (whMessageKeystore_EvictResponse*)resp_packet); - *out_resp_size = sizeof(resp); - } + (void)wh_MessageKeystore_TranslateEvictResponse( + magic, &resp, (whMessageKeystore_EvictResponse*)resp_packet); + *out_resp_size = sizeof(resp); } break; case WH_KEY_EXPORT: { @@ -1638,25 +1622,20 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, } resp.rc = ret; - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; + /* Only provide key output if no error */ if (ret == WH_ERROR_OK) { - /* Only provide key output if no error */ - if (resp.rc == WH_ERROR_OK) { - resp.len = keySz; - } - else { - resp.len = 0; - } - memcpy(resp.label, meta->label, sizeof(meta->label)); + resp.len = keySz; + } + else { + resp.len = 0; + } + memcpy(resp.label, meta->label, sizeof(meta->label)); - (void)wh_MessageKeystore_TranslateExportResponse( - magic, &resp, - (whMessageKeystore_ExportResponse*)resp_packet); + (void)wh_MessageKeystore_TranslateExportResponse( + magic, &resp, (whMessageKeystore_ExportResponse*)resp_packet); - *out_resp_size = sizeof(resp) + resp.len; - } + *out_resp_size = sizeof(resp) + resp.len; } break; case WH_KEY_COMMIT: { @@ -1672,18 +1651,12 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, req.id)); resp.rc = ret; - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; + resp.ok = 0; /* unused */ - if (ret == WH_ERROR_OK) { - resp.ok = 0; - - (void)wh_MessageKeystore_TranslateCommitResponse( - magic, &resp, - (whMessageKeystore_CommitResponse*)resp_packet); + (void)wh_MessageKeystore_TranslateCommitResponse( + magic, &resp, (whMessageKeystore_CommitResponse*)resp_packet); - *out_resp_size = sizeof(resp); - } + *out_resp_size = sizeof(resp); } break; case WH_KEY_ERASE: { @@ -1699,18 +1672,12 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, wh_KeyId_TranslateFromClient(WH_KEYTYPE_CRYPTO, server->comm->client_id, req.id)); resp.rc = ret; - /* TODO: Are there any fatal server errors? */ - ret = WH_ERROR_OK; - - if (ret == WH_ERROR_OK) { - resp.ok = 0; + resp.ok = 0; /* unused */ - (void)wh_MessageKeystore_TranslateEraseResponse( - magic, &resp, - (whMessageKeystore_EraseResponse*)resp_packet); + (void)wh_MessageKeystore_TranslateEraseResponse( + magic, &resp, (whMessageKeystore_EraseResponse*)resp_packet); - *out_resp_size = sizeof(resp); - } + *out_resp_size = sizeof(resp); } break; #ifdef WOLFHSM_CFG_KEYWRAP @@ -1740,9 +1707,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_KeyWrapResponse); - wrapResp.rc = - _HandleKeyWrapRequest(server, &wrapReq, reqData, reqDataSz, - &wrapResp, respData, respDataSz); + ret = _HandleKeyWrapRequest(server, &wrapReq, reqData, reqDataSz, + &wrapResp, respData, respDataSz); + wrapResp.rc = ret; (void)wh_MessageKeystore_TranslateKeyWrapResponse(magic, &wrapResp, resp_packet); @@ -1776,12 +1743,14 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_KeyUnwrapAndExportResponse); - unwrapResp.rc = _HandleKeyUnwrapAndExportRequest( - server, &unwrapReq, reqData, reqDataSz, &unwrapResp, respData, - respDataSz); + ret = _HandleKeyUnwrapAndExportRequest(server, &unwrapReq, reqData, + reqDataSz, &unwrapResp, + respData, respDataSz); + unwrapResp.rc = ret; (void)wh_MessageKeystore_TranslateKeyUnwrapAndExportResponse( magic, &unwrapResp, resp_packet); + *out_resp_size = sizeof(unwrapResp) + sizeof(whNvmMetadata) + unwrapResp.keySz; @@ -1812,12 +1781,14 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_KeyUnwrapAndCacheResponse); - cacheResp.rc = _HandleKeyUnwrapAndCacheRequest( - server, &cacheReq, reqData, reqDataSz, &cacheResp, respData, - respDataSz); + ret = _HandleKeyUnwrapAndCacheRequest(server, &cacheReq, reqData, + reqDataSz, &cacheResp, + respData, respDataSz); + cacheResp.rc = ret; (void)wh_MessageKeystore_TranslateKeyUnwrapAndCacheResponse( magic, &cacheResp, resp_packet); + *out_resp_size = sizeof(cacheResp); } break; @@ -1848,9 +1819,9 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_DataWrapResponse); - wrapResp.rc = - _HandleDataWrapRequest(server, &wrapReq, reqData, reqDataSz, - &wrapResp, respData, respDataSz); + ret = _HandleDataWrapRequest(server, &wrapReq, reqData, reqDataSz, + &wrapResp, respData, respDataSz); + wrapResp.rc = ret; (void)wh_MessageKeystore_TranslateDataWrapResponse(magic, &wrapResp, resp_packet); @@ -1885,9 +1856,10 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, respData = (uint8_t*)resp_packet + sizeof(whMessageKeystore_DataUnwrapResponse); - unwrapResp.rc = + ret = _HandleDataUnwrapRequest(server, &unwrapReq, reqData, reqDataSz, &unwrapResp, respData, respDataSz); + unwrapResp.rc = ret; (void)wh_MessageKeystore_TranslateDataUnwrapResponse( magic, &unwrapResp, resp_packet); @@ -1898,7 +1870,7 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic, #endif /* WOLFHSM_CFG_KEYWRAP */ default: - ret = WH_ERROR_BADARGS; + ret = WH_ERROR_NOHANDLER; break; } diff --git a/src/wh_server_she.c b/src/wh_server_she.c index b1295376..eba75acc 100644 --- a/src/wh_server_she.c +++ b/src/wh_server_she.c @@ -1689,10 +1689,7 @@ int wh_Server_HandleSheRequest(whServerContext* server, uint16_t magic, server->she->cmacKeyFound = 0; } - /* Unconditionally return success so response message is sent, propagating - * the error code to the client */ - /* TODO: Are there any fatal server errors that should be handled here? */ - return 0; + return ret; } #endif /* WOLFHSM_CFG_SHE_EXTENSION */ diff --git a/wolfhsm/wh_error.h b/wolfhsm/wh_error.h index 9eb1f07c..d918fe61 100644 --- a/wolfhsm/wh_error.h +++ b/wolfhsm/wh_error.h @@ -40,7 +40,7 @@ enum WH_ERROR_ENUM { WH_ERROR_CERT_VERIFY = -2005, /* Certificate verification failed */ WH_ERROR_BUFFER_SIZE = -2006, /* Generic buffer size mismatch. Buffer * length is not what was expected */ - WH_ERROR_NOHANDLER = -2007, /* No customcb handler registered */ + WH_ERROR_NOHANDLER = -2007, /* No handler for requested action */ WH_ERROR_NOTIMPL = -2008, /* Functionality not implemented given the compile-time configuration */ WH_ERROR_USAGE = From ed9143f011d55d764bd6cc6fdfb82fd45dd3fbec Mon Sep 17 00:00:00 2001 From: Brett Nicholas <7547222+bigbrett@users.noreply.github.com> Date: Fri, 12 Dec 2025 13:30:32 -0700 Subject: [PATCH 2/4] Log server handler errors --- src/wh_server.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/wh_server.c b/src/wh_server.c index 88279899..bb9fb5da 100644 --- a/src/wh_server.c +++ b/src/wh_server.c @@ -435,18 +435,29 @@ int wh_Server_HandleRequestMessage(whServerContext* server) size, data); } while (rc == WH_ERROR_NOTREADY); - /* Log any communication errors */ - WH_LOG_ON_ERROR_F(&server->log, WH_LOG_LEVEL_ERROR, rc, - "SendResponse failed for (group=%d, action=%d): %d", - group, action, rc); - - (void)handlerRc; /* Suppress unused variable warning until logging is - * implemented */ + /* Log error code from request handler, if present */ + WH_LOG_ON_ERROR_F(&server->log, WH_LOG_LEVEL_ERROR, handlerRc, + "Handler (group=%d, action=%d, seq=%d) returned %d", + group, action, seq, handlerRc); + (void)handlerRc; /* suppress unused var warning */ + + /* Log error code from sending response, if present */ + WH_LOG_ON_ERROR_F( + &server->log, WH_LOG_LEVEL_ERROR, rc, + "SendResponse failed for (group=%d, action=%d, seq=%d): %d", group, + action, seq, rc); /* Always return success when we processed a request, so no handler * error can terminate the server's request processing loop. */ rc = WH_ERROR_OK; } + else if (rc != WH_ERROR_NOTREADY) { + /* Log error code from processing request, if present */ + WH_LOG_ON_ERROR_F( + &server->log, WH_LOG_LEVEL_ERROR, rc, + "RecvRequest failed for (group=%d, action=%d, seq=%d): %d", group, + action, seq, rc); + } return rc; } From 3fba0764f571fee67089df105612f13ce53b0ea6 Mon Sep 17 00:00:00 2001 From: Brett Nicholas <7547222+bigbrett@users.noreply.github.com> Date: Fri, 12 Dec 2025 14:54:03 -0700 Subject: [PATCH 3/4] implement printf logging backend --- port/posix/posix_log_file.c | 17 +------ src/wh_log.c | 14 ++++++ src/wh_log_printf.c | 94 +++++++++++++++++++++++++++++++++++++ wolfhsm/wh_log.h | 11 +++++ wolfhsm/wh_log_printf.h | 64 +++++++++++++++++++++++++ 5 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 src/wh_log_printf.c create mode 100644 wolfhsm/wh_log_printf.h diff --git a/port/posix/posix_log_file.c b/port/posix/posix_log_file.c index 0c086d67..764fede4 100644 --- a/port/posix/posix_log_file.c +++ b/port/posix/posix_log_file.c @@ -39,21 +39,6 @@ #ifdef WOLFHSM_CFG_LOGGING -/* Helper function to convert log level to string */ -static const char* posixLogFile_LevelToString(whLogLevel level) -{ - switch (level) { - case WH_LOG_LEVEL_INFO: - return "INFO"; - case WH_LOG_LEVEL_ERROR: - return "ERROR"; - case WH_LOG_LEVEL_SECEVENT: - return "SECEVENT"; - default: - return "UNKNOWN"; - } -} - /* Helper function to convert string to log level */ static whLogLevel posixLogFile_StringToLevel(const char* str) { @@ -146,7 +131,7 @@ int posixLogFile_AddEntry(void* c, const whLogEntry* entry) /* Format log entry: TIMESTAMP|LEVEL|FILE:LINE|FUNCTION|MESSAGE\n */ len = snprintf(buffer, sizeof(buffer), "%llu|%s|%s:%u|%s|%.*s\n", (unsigned long long)entry->timestamp, - posixLogFile_LevelToString(entry->level), + wh_Log_LevelToString(entry->level), entry->file ? entry->file : "", entry->line, entry->function ? entry->function : "", (int)entry->msg_len, entry->msg); diff --git a/src/wh_log.c b/src/wh_log.c index cb059009..1023df0c 100644 --- a/src/wh_log.c +++ b/src/wh_log.c @@ -36,6 +36,20 @@ #ifdef WOLFHSM_CFG_LOGGING +const char* wh_Log_LevelToString(whLogLevel level) +{ + switch (level) { + case WH_LOG_LEVEL_INFO: + return "INFO"; + case WH_LOG_LEVEL_ERROR: + return "ERROR"; + case WH_LOG_LEVEL_SECEVENT: + return "SECEVENT"; + default: + return "UNKNOWN"; + } +} + void wh_Log_AddMsg(whLogContext* ctx, whLogLevel level, const char* file, const char* function, uint32_t line, const char* src, size_t src_len) diff --git a/src/wh_log_printf.c b/src/wh_log_printf.c new file mode 100644 index 00000000..f4f72814 --- /dev/null +++ b/src/wh_log_printf.c @@ -0,0 +1,94 @@ +/* + * 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_log_printf.c + * + * Printf-style logging backend implementation + */ + +#include /* For NULL */ +#include /* For memset, memcpy */ + +#include "wolfhsm/wh_settings.h" + +#include "wolfhsm/wh_log_printf.h" +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_log.h" + +#ifdef WOLFHSM_CFG_LOGGING + +int whLogPrintf_Init(void* c, const void* cf) +{ + whLogPrintfContext* context = (whLogPrintfContext*)c; + const whLogPrintfConfig* config = (const whLogPrintfConfig*)cf; + + if (context == NULL) { + return WH_ERROR_BADARGS; + } + + /* Initialize context */ + memset(context, 0, sizeof(*context)); + + /* Copy config if provided, otherwise use defaults */ + if (config != NULL) { + context->logIfNotDebug = config->logIfNotDebug; + } + else { + context->logIfNotDebug = 0; + } + + context->initialized = 1; + + return WH_ERROR_OK; +} + + +int whLogPrintf_AddEntry(void* c, const whLogEntry* entry) +{ + whLogPrintfContext* context = (whLogPrintfContext*)c; + + if ((context == NULL) || (entry == NULL)) { + return WH_ERROR_BADARGS; + } + + if (!context->initialized) { + return WH_ERROR_ABORTED; + } + + /* Conditional logging: + * - If logIfNotDebug is true: always log + * - If logIfNotDebug is false: only log if WOLFHSM_CFG_DEBUG is defined + */ +#ifndef WOLFHSM_CFG_DEBUG + if (!context->logIfNotDebug) { + return WH_ERROR_OK; + } +#endif + + /* Format: [TIMESTAMP] [LEVEL] [FILE:LINE FUNC] MESSAGE */ + WOLFHSM_CFG_PRINTF( + "[%llu] [%s] [%s:%u %s] %.*s\n", (unsigned long long)entry->timestamp, + wh_Log_LevelToString(entry->level), entry->file ? entry->file : "", + entry->line, entry->function ? entry->function : "", + (int)entry->msg_len, entry->msg); + + return WH_ERROR_OK; +} + +#endif /* WOLFHSM_CFG_LOGGING */ diff --git a/wolfhsm/wh_log.h b/wolfhsm/wh_log.h index 85d61072..2011a3e8 100644 --- a/wolfhsm/wh_log.h +++ b/wolfhsm/wh_log.h @@ -82,6 +82,17 @@ typedef struct { void* config; /* Backend-specific config */ } whLogConfig; +/* Utility functions */ + +/** + * @brief Convert a log level to its string representation. + * + * @param level The log level to convert. + * @return Pointer to a static string representing the log level: + * "INFO", "ERROR", "SECEVENT", or "UNKNOWN". + */ +const char* wh_Log_LevelToString(whLogLevel level); + /* Frontend API */ /** diff --git a/wolfhsm/wh_log_printf.h b/wolfhsm/wh_log_printf.h new file mode 100644 index 00000000..35accb9e --- /dev/null +++ b/wolfhsm/wh_log_printf.h @@ -0,0 +1,64 @@ +/* + * 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_log_printf.h + * + * Printf logging backend that simply prints out log entries as they are added, + * with no backing store. + */ + +#ifndef WOLFHSM_WH_LOG_PRINTF_H_ +#define WOLFHSM_WH_LOG_PRINTF_H_ + +#include "wolfhsm/wh_settings.h" +#include "wolfhsm/wh_log.h" + +#include + +/* Printf configuration structure */ +typedef struct whLogPrintfConfig_t { + int logIfNotDebug; /* When true, always log regardless of WOLFHSM_CFG_DEBUG + */ +} whLogPrintfConfig; + +/* Printf context structure */ +typedef struct whLogPrintfContext_t { + int initialized; /* Initialization flag */ + int logIfNotDebug; /* Copied from config */ +} whLogPrintfContext; + +/* Callback functions */ +int whLogPrintf_Init(void* context, const void* config); +int whLogPrintf_AddEntry(void* context, const whLogEntry* entry); + +/* Convenience macro for callback table initialization. + */ +/* clang-format off */ +#define WH_LOG_PRINTF_CB \ + { \ + .Init = whLogPrintf_Init, \ + .Cleanup = NULL, \ + .AddEntry = whLogPrintf_AddEntry, \ + .Export = NULL, \ + .Iterate = NULL, \ + .Clear = NULL, \ + } +/* clang-format on */ + +#endif /* !WOLFHSM_WH_LOG_PRINTF_H_ */ From c47bb19ca30f4fa4d2fa5d7f77c326caf1796983 Mon Sep 17 00:00:00 2001 From: Brett Nicholas <7547222+bigbrett@users.noreply.github.com> Date: Wed, 17 Dec 2025 16:54:38 -0700 Subject: [PATCH 4/4] address review feedback --- src/wh_log_printf.c | 12 ++++++++---- src/wh_server.c | 7 ++++--- wolfhsm/wh_log_printf.h | 6 ++++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/wh_log_printf.c b/src/wh_log_printf.c index f4f72814..73dc835c 100644 --- a/src/wh_log_printf.c +++ b/src/wh_log_printf.c @@ -82,11 +82,15 @@ int whLogPrintf_AddEntry(void* c, const whLogEntry* entry) #endif /* Format: [TIMESTAMP] [LEVEL] [FILE:LINE FUNC] MESSAGE */ - WOLFHSM_CFG_PRINTF( + (void)WOLFHSM_CFG_PRINTF( "[%llu] [%s] [%s:%u %s] %.*s\n", (unsigned long long)entry->timestamp, - wh_Log_LevelToString(entry->level), entry->file ? entry->file : "", - entry->line, entry->function ? entry->function : "", - (int)entry->msg_len, entry->msg); + wh_Log_LevelToString(entry->level), + (entry->file != NULL) ? entry->file : "", entry->line, + (entry->function != NULL) ? entry->function : "", + (entry->msg_len <= WOLFHSM_CFG_LOG_MSG_MAX) + ? (int)(entry->msg_len) + : (int)WOLFHSM_CFG_LOG_MSG_MAX, + entry->msg); return WH_ERROR_OK; } diff --git a/src/wh_server.c b/src/wh_server.c index bb9fb5da..83df8acb 100644 --- a/src/wh_server.c +++ b/src/wh_server.c @@ -410,6 +410,7 @@ int wh_Server_HandleRequestMessage(whServerContext* server) default: /* Unknown group. Return empty packet */ rc = WH_ERROR_NOTIMPL; + data = NULL; size = 0; } @@ -447,9 +448,9 @@ int wh_Server_HandleRequestMessage(whServerContext* server) "SendResponse failed for (group=%d, action=%d, seq=%d): %d", group, action, seq, rc); - /* Always return success when we processed a request, so no handler - * error can terminate the server's request processing loop. */ - rc = WH_ERROR_OK; + /* Handler errors are logged above via handlerRc but don't affect + * return code. Errors from SendResponse are propagated back to the + * caller in rc */ } else if (rc != WH_ERROR_NOTREADY) { /* Log error code from processing request, if present */ diff --git a/wolfhsm/wh_log_printf.h b/wolfhsm/wh_log_printf.h index 35accb9e..dc5e7ada 100644 --- a/wolfhsm/wh_log_printf.h +++ b/wolfhsm/wh_log_printf.h @@ -33,8 +33,10 @@ /* Printf configuration structure */ typedef struct whLogPrintfConfig_t { - int logIfNotDebug; /* When true, always log regardless of WOLFHSM_CFG_DEBUG - */ + int logIfNotDebug; /* When non-zero, log entries are printed even if + * WOLFHSM_CFG_DEBUG is not defined. When zero, entries + * are only printed if WOLFHSM_CFG_DEBUG is defined. This + * flag applies to all log levels */ } whLogPrintfConfig; /* Printf context structure */