diff --git a/src/wh_server_crypto.c b/src/wh_server_crypto.c index 95d43a7f..cc387ecb 100644 --- a/src/wh_server_crypto.c +++ b/src/wh_server_crypto.c @@ -3222,10 +3222,12 @@ int wh_Server_HandleCryptoDmaRequest(whServerContext* ctx, uint16_t magic, } break; /* WC_ALGO_TYPE_PK */ +#ifdef WOLFSSL_CMAC case WC_ALGO_TYPE_CMAC: ret = _HandleCmacDma(ctx, magic, seq, cryptoDataIn, cryptoInSize, cryptoDataOut, &cryptoOutSize); break; +#endif /* WOLFSSL_CMAC */ case WC_ALGO_TYPE_NONE: default: diff --git a/src/wh_server_dma.c b/src/wh_server_dma.c index 2ed1d8a8..718841fb 100644 --- a/src/wh_server_dma.c +++ b/src/wh_server_dma.c @@ -131,6 +131,22 @@ int wh_Server_DmaRegisterCb(whServerContext* server, whServerDmaClientMemCb cb) return WH_ERROR_OK; } +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY +int wh_Server_DmaRegisterMemCopyCb(whServerContext* server, + whServerDmaMemCopyCb cb) +{ + /* No NULL check for cb, since it is optional and always NULL checked before + * it is called */ + if (NULL == server) { + return WH_ERROR_BADARGS; + } + + server->dma.memCopyCb = cb; + + return WH_ERROR_OK; +} +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ + int wh_Server_DmaRegisterAllowList(whServerContext* server, const whServerDmaAddrAllowList* allowlist) { @@ -199,8 +215,22 @@ int whServerDma_CopyFromClient(struct whServerContext_t* server, } /* Perform the actual copy */ - /* TODO: should we add a flag to force client word-sized reads? */ - memcpy(serverPtr, transformedAddr, len); +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY + if (server->dma.memCopyCb != NULL) { + rc = server->dma.memCopyCb(server, (uintptr_t)transformedAddr, + (uintptr_t)serverPtr, len, + WH_DMA_COPY_OPER_CLIENT_READ, flags); + if (rc != WH_ERROR_OK) { + return rc; + } + } + else +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ + { + + /* TODO: should we add a flag to force client word-sized reads? */ + memcpy(serverPtr, transformedAddr, len); + } /* process the client address post-read */ rc = wh_Server_DmaProcessClientAddress( @@ -238,8 +268,21 @@ int whServerDma_CopyToClient(struct whServerContext_t* server, } /* Perform the actual copy */ - /* TODO: should we add a flag to force client word-sized reads? */ - memcpy(transformedAddr, serverPtr, len); +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY + if (server->dma.memCopyCb != NULL) { + rc = server->dma.memCopyCb(server, clientAddr, (uintptr_t)serverPtr, + len, WH_DMA_COPY_OPER_CLIENT_WRITE, flags); + if (rc != WH_ERROR_OK) { + return rc; + } + } + else +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ + { + + /* TODO: should we add a flag to force client word-sized reads? */ + memcpy(transformedAddr, serverPtr, len); + } /* Process the client address post-write */ rc = wh_Server_DmaProcessClientAddress(server, clientAddr, &transformedAddr, diff --git a/wolfhsm/wh_server.h b/wolfhsm/wh_server.h index b82e7b00..5e86f2a0 100644 --- a/wolfhsm/wh_server.h +++ b/wolfhsm/wh_server.h @@ -129,6 +129,13 @@ typedef enum { WH_DMA_OPER_CLIENT_WRITE_POST = 3, } whServerDmaOper; +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY +typedef enum { + WH_DMA_COPY_OPER_CLIENT_READ = 0, + WH_DMA_COPY_OPER_CLIENT_WRITE = 1, +} whServerDmaCopyOper; +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ + /* Flags embedded in request/response structs provided by client */ typedef struct { uint8_t cacheForceInvalidate : 1; @@ -142,6 +149,14 @@ typedef int (*whServerDmaClientMemCb)(struct whServerContext_t* server, size_t len, whServerDmaOper oper, whServerDmaFlags flags); +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY +/* DMA callback invoked to copy from the client */ +typedef int (*whServerDmaMemCopyCb)(struct whServerContext_t* server, + uintptr_t clientAddr, uintptr_t serverPtr, + size_t len, whServerDmaCopyOper oper, + 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 { @@ -160,11 +175,17 @@ typedef struct { /* Server DMA configuration struct for initializing a server */ typedef struct { whServerDmaClientMemCb cb; /* DMA callback */ +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY + whServerDmaMemCopyCb memCopyCb; /* DMA memory copy callback */ +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ const whServerDmaAddrAllowList* dmaAddrAllowList; /* allowed addresses */ } whServerDmaConfig; typedef struct { whServerDmaClientMemCb cb; /* DMA callback */ +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY + whServerDmaMemCopyCb memCopyCb; /* DMA memory copy callback */ +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ const whServerDmaAddrAllowList* dmaAddrAllowList; /* allowed addresses */ } whServerDmaContext; @@ -384,6 +405,26 @@ int wh_Server_HandleCustomCbRequest(whServerContext* server, uint16_t magic, int wh_Server_DmaRegisterCb(struct whServerContext_t* server, whServerDmaClientMemCb cb); + +#ifdef WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY +/** + * @brief Registers a custom memory copy callback for DMA operations. + * This function allows the server to register a callback that will be invoked + * during DMA memory copy operations. The callback overrides the use of + * memcpy when copying to and from client memory. This is useful if standard + * memcpy cannot be used to copy data back and forth between the client, even + * after client addresses are transformed through the standard DMA callbacks + * (e.g. if client memory can only be accessed though a hardware FIFO or register + * interface) + * @param[in] server Pointer to the server context. + * @param[in] cb The custom memory copy callback handler to register. + * @return int Returns WH_ERROR_OK on success, or WH_ERROR_BADARGS if the + * arguments are invalid. + */ +int wh_Server_DmaRegisterMemCopyCb(whServerContext* server, + whServerDmaMemCopyCb cb); +#endif /* WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY */ + /** * @brief Registers the allowable client read/write addresses for DMA. * diff --git a/wolfhsm/wh_settings.h b/wolfhsm/wh_settings.h index 96eb657b..f84674bb 100644 --- a/wolfhsm/wh_settings.h +++ b/wolfhsm/wh_settings.h @@ -67,6 +67,10 @@ * WOLFHSM_CFG_SERVER_IMG_MGR_MAX_SIG_SIZE - Maximum signature size for image * verification Default: 512 bytes (RSA4096) * + * WOLFHSM_CFG_DMA_CUSTOM_CLIENT_COPY - if defined, allows to setup a custom + * callback to handle client to server and/or server to client memory copy + * operation in DMA requests. + * Default: Not defined * * Overridable porting functions: *