From 8c1cd0f80df9dfe3b112d8f60b27687284b5fb05 Mon Sep 17 00:00:00 2001 From: Bill Phipps Date: Tue, 20 Aug 2024 13:47:07 -0400 Subject: [PATCH] Fix memtransport, move debug prints to utils --- src/wh_client_cryptocb.c | 32 +++++------------ src/wh_server_crypto.c | 15 ++++---- src/wh_transport_mem.c | 78 ++++++++++++++++++++++++++++------------ src/wh_utils.c | 70 ++++++++++++++++++++++++++++++++++++ wolfhsm/wh_utils.h | 47 ++++++++++++++++++++++++ 5 files changed, 191 insertions(+), 51 deletions(-) diff --git a/src/wh_client_cryptocb.c b/src/wh_client_cryptocb.c index 65bd2d1f..913b940e 100644 --- a/src/wh_client_cryptocb.c +++ b/src/wh_client_cryptocb.c @@ -21,18 +21,21 @@ * */ -#include - /* Pick up compile-time configuration */ #include "wolfhsm/wh_settings.h" -#include "wolfhsm/wh_client.h" + +#ifndef WOLFHSM_CFG_NO_CRYPTO + +#include + +#include "wolfhsm/wh_common.h" +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_utils.h" #include "wolfhsm/wh_comm.h" #include "wolfhsm/wh_packet.h" -#include "wolfhsm/wh_error.h" #include "wolfhsm/wh_message.h" - -#ifndef WOLFHSM_CFG_NO_CRYPTO +#include "wolfhsm/wh_client.h" #include "wolfssl/wolfcrypt/settings.h" #include "wolfssl/wolfcrypt/types.h" @@ -45,23 +48,6 @@ #include "wolfhsm/wh_client_cryptocb.h" -#if defined(DEBUG_CRYPTOCB) || defined(DEBUG_CRYPTOCB_VERBOSE) -#include -#endif - -#ifdef DEBUG_CRYPTOCB_VERBOSE -static void _hexdump(const char* initial,uint8_t* ptr, size_t size) -{ - if(initial != NULL) - printf("%s",initial); - while(size > 0) { - printf ("%02X ", *ptr); - ptr++; - size --; - } - printf("\n"); -} -#endif #ifndef NO_SHA256 static int _handleSha256(int devId, wc_CryptoInfo* info, void* inCtx, diff --git a/src/wh_server_crypto.c b/src/wh_server_crypto.c index 33f3c7dc..7291ab47 100644 --- a/src/wh_server_crypto.c +++ b/src/wh_server_crypto.c @@ -24,28 +24,31 @@ /* Pick up compile-time configuration */ #include "wolfhsm/wh_settings.h" +#ifndef WOLFHSM_CFG_NO_CRYPTO + /* System libraries */ #include #include /* For NULL */ #include /* For memset, memcpy */ -#ifndef WOLFHSM_CFG_NO_CRYPTO - #include "wolfssl/wolfcrypt/settings.h" #include "wolfssl/wolfcrypt/types.h" #include "wolfssl/wolfcrypt/error-crypt.h" +#include "wolfssl/wolfcrypt/rsa.h" +#include "wolfssl/wolfcrypt/curve25519.h" +#include "wolfssl/wolfcrypt/ecc.h" +#include "wolfssl/wolfcrypt/aes.h" +#include "wolfssl/wolfcrypt/sha256.h" +#include "wolfssl/wolfcrypt/cmac.h" #include "wolfhsm/wh_error.h" #include "wolfhsm/wh_packet.h" +#include "wolfhsm/wh_utils.h" #include "wolfhsm/wh_server_keystore.h" #include "wolfhsm/wh_server_crypto.h" #include "wolfhsm/wh_server.h" -#if defined(DEBUG_CRYPTOCB) || defined(DEBUG_CRYPTOCB_VERBOSE) -#include -#endif - #ifndef NO_RSA static int hsmCacheKeyRsa(whServerContext* server, RsaKey* key, whKeyId* outId) { diff --git a/src/wh_transport_mem.c b/src/wh_transport_mem.c index 5bdb62ae..86ba4b45 100644 --- a/src/wh_transport_mem.c +++ b/src/wh_transport_mem.c @@ -30,6 +30,7 @@ #include #include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_utils.h" #include "wolfhsm/wh_comm.h" #include "wolfhsm/wh_transport_mem.h" @@ -51,7 +52,7 @@ int wh_TransportMem_Init(void* c, const void* cf, return WH_ERROR_BADARGS; } - memset(context, 0, sizeof(*context)); + wh_Utils_memset_flush(context, 0, sizeof(*context)); context->req = (whTransportMemCsr*)config->req; context->req_size = config->req_size; context->req_data = (void*)(context->req + 1); @@ -61,6 +62,8 @@ int wh_TransportMem_Init(void* c, const void* cf, context->resp_data = (void*)(context->resp + 1); context->initialized = 1; + XMEMFENCE(); + return WH_ERROR_OK; } @@ -72,8 +75,8 @@ int wh_TransportMem_InitClear(void* c, const void* cf, int rc = wh_TransportMem_Init(c, cf, connectcb, connectcb_arg); if (rc == WH_ERROR_OK) { /* Zero the buffers */ - memset((void*)context->req, 0, context->req_size); - memset((void*)context->resp, 0, context->resp_size); + wh_Utils_memset_flush((void*)context->req, 0, context->req_size); + wh_Utils_memset_flush((void*)context->resp, 0, context->resp_size); } return rc; } @@ -93,6 +96,8 @@ int wh_TransportMem_Cleanup(void* c) int wh_TransportMem_SendRequest(void* c, uint16_t len, const void* data) { whTransportMemContext* context = c; + volatile whTransportMemCsr* ctx_req = context->req; + volatile whTransportMemCsr* ctx_resp = context->resp; whTransportMemCsr resp; whTransportMemCsr req; @@ -101,9 +106,13 @@ int wh_TransportMem_SendRequest(void* c, uint16_t len, const void* data) return WH_ERROR_BADARGS; } - /* Read current CSR's */ - resp.u64 = context->resp->u64; - req.u64 = context->req->u64; + /* Read current CSR's. ctx_req does not need to be invalidated */ + XMEMFENCE(); + XCACHEINVLD(ctx_resp); + XCACHEINVLD(ctx_req); + + resp.u64 = ctx_resp->u64; + req.u64 = ctx_req->u64; /* Has server completed with previous request */ if (req.s.notify != resp.s.notify) { @@ -111,13 +120,20 @@ int wh_TransportMem_SendRequest(void* c, uint16_t len, const void* data) } if ((data != NULL) && (len != 0)) { - memcpy((void*)context->req_data, data, len); + wh_Utils_memcpy_flush((void*)context->req_data, data, len); } + + /* Ensure the memcpy is complete */ + XMEMFENCE(); + req.s.len = len; req.s.notify++; /* Write the new CSR's */ - context->req->u64 = req.u64; + ctx_req->u64 = req.u64; + /*Ensure the update to the CSR is complete */ + XMEMFENCE(); + XCACHEFLUSH(ctx_req); return 0; } @@ -125,6 +141,8 @@ int wh_TransportMem_SendRequest(void* c, uint16_t len, const void* data) int wh_TransportMem_RecvRequest(void* c, uint16_t *out_len, void* data) { whTransportMemContext* context = c; + volatile whTransportMemCsr* ctx_req = context->req; + volatile whTransportMemCsr* ctx_resp = context->resp; whTransportMemCsr req; whTransportMemCsr resp; @@ -133,9 +151,11 @@ int wh_TransportMem_RecvRequest(void* c, uint16_t *out_len, void* data) return WH_ERROR_BADARGS; } - /* Read current request CSR's */ - req.u64 = context->req->u64; - resp.u64 = context->resp->u64; + /* Read current request CSR's. ctx_resp does not need to be invalidated */ + XMEMFENCE(); + XCACHEINVLD(ctx_req); + req.u64 = ctx_req->u64; + resp.u64 = ctx_resp->u64; /* Check to see if a new request has arrived */ if(req.s.notify == resp.s.notify) { @@ -143,7 +163,7 @@ int wh_TransportMem_RecvRequest(void* c, uint16_t *out_len, void* data) } if ((data != NULL) && (req.s.len != 0)) { - memcpy(data, context->req_data, req.s.len); + wh_Utils_memcpy_invalidate(data, context->req_data, req.s.len); } if (out_len != NULL) { *out_len = req.s.len; @@ -155,6 +175,8 @@ int wh_TransportMem_RecvRequest(void* c, uint16_t *out_len, void* data) int wh_TransportMem_SendResponse(void* c, uint16_t len, const void* data) { whTransportMemContext* context = c; + volatile whTransportMemCsr* ctx_req = context->req; + volatile whTransportMemCsr* ctx_resp = context->resp; whTransportMemCsr req; whTransportMemCsr resp; @@ -163,18 +185,26 @@ int wh_TransportMem_SendResponse(void* c, uint16_t len, const void* data) return WH_ERROR_BADARGS; } - /* Read both CSR's */ - req.u64 = context->req->u64; - resp.u64 = context->resp->u64; + /* Read both CSR's. ctx_resp does not need to be invalidated */ + XMEMFENCE(); + XCACHEINVLD(ctx_req); + req.u64 = ctx_req->u64; + resp.u64 = ctx_resp->u64; if ((data != NULL) && (len != 0)) { - memcpy(context->resp_data, data, len); + wh_Utils_memcpy_flush(context->resp_data, data, len); } + /* Ensure the memcpy is complete */ + XMEMFENCE(); + resp.s.len = len; resp.s.notify = req.s.notify; - /* Write the new CSR's */ - context->resp->u64 = resp.u64; + /* Write the new CSR's */ + ctx_resp->u64 = resp.u64; + /*Ensure the update to the CSR is complete */ + XMEMFENCE(); + XCACHEFLUSH(ctx_resp); return 0; } @@ -182,6 +212,8 @@ int wh_TransportMem_SendResponse(void* c, uint16_t len, const void* data) int wh_TransportMem_RecvResponse(void* c, uint16_t *out_len, void* data) { whTransportMemContext* context = c; + volatile whTransportMemCsr* ctx_req = context->req; + volatile whTransportMemCsr* ctx_resp = context->resp; whTransportMemCsr req; whTransportMemCsr resp; @@ -190,9 +222,11 @@ int wh_TransportMem_RecvResponse(void* c, uint16_t *out_len, void* data) return WH_ERROR_BADARGS; } - /* Read both CSR's */ - req.u64 = context->req->u64; - resp.u64 = context->resp->u64; + /* Read both CSR's. ctx_req does not need to be invalidated */ + XMEMFENCE(); + XCACHEINVLD(ctx_resp); + req.u64 = ctx_req->u64; + 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) { @@ -200,7 +234,7 @@ int wh_TransportMem_RecvResponse(void* c, uint16_t *out_len, void* data) } if ((data != NULL) && (resp.s.len != 0)) { - memcpy(data, context->resp_data, resp.s.len); + wh_Utils_memcpy_invalidate(data, context->resp_data, resp.s.len); } if (out_len != NULL) { diff --git a/src/wh_utils.c b/src/wh_utils.c index 86fd30ab..50ed24e5 100644 --- a/src/wh_utils.c +++ b/src/wh_utils.c @@ -25,6 +25,8 @@ #include "wolfhsm/wh_settings.h" #include +#include /* For size_t */ +#include /* For memset/cpy */ #include "wolfhsm/wh_utils.h" @@ -84,3 +86,71 @@ int wh_Utils_memeqzero(uint8_t* buffer, uint32_t size) } return 1; } + +/** Cache helper functions */ +const void* wh_Utils_CacheInvalidate(const void* p, size_t n) +{ + int len = (int)n; + const uint8_t* ptr = (const uint8_t*)p; + do { + XCACHEINVLD(ptr); + ptr += XCACHELINE; + len -= XCACHELINE; + } while (len > 0); + return p; +} + +void* wh_Utils_CacheFlush(void* p, size_t n) +{ + int len = (int)n; + uint8_t* ptr = (uint8_t*)p; + do { + XCACHEFLUSH(ptr); + ptr += XCACHELINE; + len -= XCACHELINE; + } while (len > 0); + return p; +} + +void* wh_Utils_memset_flush(void* p, int c, size_t n) +{ + return wh_Utils_CacheFlush(memset(p, c, n), n); +} + +void* wh_Utils_memcpy_invalidate(void* dst, const void* src, size_t n) +{ + return memcpy(dst,wh_Utils_CacheInvalidate(src,n),n); +} + +void* wh_Utils_memcpy_flush(void* dst, const void* src , size_t n) +{ + return wh_Utils_CacheFlush(memcpy(dst,src,n),n); +} + + +#if defined(DEBUG_CRYPTOCB) || defined(DEBUG_CRYPTOCB_VERBOSE) +#include +#endif + +#ifdef DEBUG_CRYPTOCB_VERBOSE +void _hexdump(const char* initial, uint8_t* ptr, size_t size) +{ +#define HEXDUMP_BYTES_PER_LINE 16 + int count = 0; + if(initial != NULL) + printf("%s",initial); + while(size > 0) { + printf ("%02X ", *ptr); + ptr++; + size --; + count++; + if (count % HEXDUMP_BYTES_PER_LINE == 0) { + printf("\n"); + } + } + if((count % HEXDUMP_BYTES_PER_LINE) != 0) { + printf("\n"); + } +} +#endif + diff --git a/wolfhsm/wh_utils.h b/wolfhsm/wh_utils.h index 5185f4ce..2df950e1 100644 --- a/wolfhsm/wh_utils.h +++ b/wolfhsm/wh_utils.h @@ -28,6 +28,7 @@ #include "wolfhsm/wh_settings.h" #include +#include /* For size_t */ /** Byteswap functions */ uint16_t wh_Utils_Swap16(uint16_t val); @@ -39,4 +40,50 @@ uint32_t wh_Utils_ntohl(uint32_t networklong); int wh_Utils_memeqzero(uint8_t* buffer, uint32_t size); +/** Cache flushing and memory fencing synchronization primitives */ +/* Create a full sequential memory fence to ensure compiler memory ordering */ +#ifndef XMEMFENCE +#define XMEMFENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST) +#endif + +/* Return cacheline size */ +#ifndef XCACHELINE +#define XCACHELINE (32) +#endif + +/* Flush the cache line at _p. Used after writing to ensure the memory is + * consistent. */ +#ifndef XCACHEFLUSH +#define XCACHEFLUSH(_p) (void)(_p) +/* PPC32: __asm__ volatile ("dcbf 0, %0" : : "r" (_p): "memory") */ +#endif + +/* Invalidate the cache line at _p. Used prior to reading to ensure + * freshness. */ +#ifndef XCACHEINVLD +#define XCACHEINVLD(_p) (void)(_p) +/* PPC32: __asm__ volatile ("dcbi 0, %0" : : "r" (_p): "memory") */ +#endif + +/** Cache helper functions */ +/* Flush the cache lines starting at p for at least n bytes */ +void* wh_Utils_CacheFlush(void* p, size_t n); + +/* Invalidate the cache lines starting at p for at least n bytes */ +const void* wh_Utils_CacheInvalidate(const void* p, size_t n); + +/* Perform memset followed by a cache flush */ +void* wh_Utils_memset_flush(void* p, int c, size_t n); + +/* Cache invalidate the src followed by memcpy */ +void* wh_Utils_memcpy_invalidate(void* dst, const void* src, size_t n); + +/* Perform memcpy followed by a cache flush of dst */ +void* wh_Utils_memcpy_flush(void* dst, const void* src , size_t n); + + +#if defined(DEBUG_CRYPTOCB) || defined(DEBUG_CRYPTOCB_VERBOSE) +void _hexdump(const char* initial, uint8_t* ptr, size_t size); +#endif + #endif /* !WOLFHSM_WH_UTILS_H_ */