From 0dca3bc24d224e5edcb827e79d1a69e0bf73447d Mon Sep 17 00:00:00 2001 From: night1rider Date: Thu, 16 Oct 2025 13:43:24 -0600 Subject: [PATCH] Setup to be opt-in for copy callback, and also added a outline for a free callback --- .wolfssl_known_macro_extras | 1 + tests/api.c | 71 ++++++++++++++++++++++++++++ wolfcrypt/src/cryptocb.c | 74 +++++++++++++++++++---------- wolfcrypt/src/sha256.c | 33 +++++++++++-- wolfcrypt/test/test.c | 90 +++++++++++++++++++++++++----------- wolfssl/wolfcrypt/cryptocb.h | 27 ++++++----- wolfssl/wolfcrypt/types.h | 4 +- 7 files changed, 228 insertions(+), 72 deletions(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index ca514a928..bbc74ade9 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -731,6 +731,7 @@ WOLFSSL_HARDEN_TLS_ALLOW_OLD_TLS WOLFSSL_HARDEN_TLS_ALLOW_TRUNCATED_HMAC WOLFSSL_HARDEN_TLS_NO_PKEY_CHECK WOLFSSL_HARDEN_TLS_NO_SCR_CHECK +WOLFSSL_HAVE_COPY_FREE_CB WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY WOLFSSL_I2D_ECDSA_SIG_ALLOC WOLFSSL_IAR_ARM_TIME diff --git a/tests/api.c b/tests/api.c index fe32649b1..d92c5e022 100644 --- a/tests/api.c +++ b/tests/api.c @@ -44807,6 +44807,77 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx) } #endif /* HAVE_ED25519 */ } +#ifdef WOLFSSL_HAVE_COPY_FREE_CB + else if (info->algo_type == WC_ALGO_TYPE_COPY) { + #ifdef DEBUG_WOLFSSL + fprintf(stderr, "test_CryptoCb_Func: Copy Algo=%d Type=%d\n", + info->copy.algo, info->copy.type); + #endif + if (info->copy.algo == WC_ALGO_TYPE_HASH) { + switch (info->copy.type) { + #ifndef NO_SHA256 + case WC_HASH_TYPE_SHA256: + { + wc_Sha256* src = (wc_Sha256*)info->copy.src; + wc_Sha256* dst = (wc_Sha256*)info->copy.dst; + /* set devId to invalid, so software is used */ + src->devId = INVALID_DEVID; + ret = wc_Sha256Copy(src, dst); + + /* reset devId */ + src->devId = thisDevId; + if (ret == 0) { + /* Set the devId of the destination to the same */ + /* since we used the software implementation of copy */ + /* so dst would have been set to INVALID_DEVID */ + dst->devId = thisDevId; + } + break; + } + #endif /* !NO_SHA256 */ + default: + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); + break; + } + } + else { + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); + } + } + else if (info->algo_type == WC_ALGO_TYPE_FREE) { + #ifdef DEBUG_WOLFSSL + fprintf(stderr, "test_CryptoCb_Func: Free Algo=%d Type=%d\n", + info->free.algo, info->free.type); + #endif + + if (info->free.algo == WC_ALGO_TYPE_HASH) { + switch (info->free.type) { + #ifndef NO_SHA256 + case WC_HASH_TYPE_SHA256: + { + wc_Sha256* sha = (wc_Sha256*)info->free.obj; + + /* set devId to invalid, so software is used */ + sha->devId = INVALID_DEVID; + + /* Call the actual free function */ + wc_Sha256Free(sha); + + /* Note: devId doesn't need to be restored as object is freed */ + ret = 0; + break; + } + #endif + default: + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); + break; + } + } + else { + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); + } + } +#endif /* WOLFSSL_HAVE_COPY_FREE_CB */ (void)thisDevId; (void)keyFormat; diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 7be31cab9..38c6bb898 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -81,7 +81,10 @@ static const char* GetAlgoTypeStr(int algo) case WC_ALGO_TYPE_CMAC: return "CMAC"; case WC_ALGO_TYPE_CERT: return "Cert"; case WC_ALGO_TYPE_KDF: return "KDF"; +#ifdef WOLFSSL_HAVE_COPY_FREE_CB case WC_ALGO_TYPE_COPY: return "Copy"; + case WC_ALGO_TYPE_FREE: return "Free"; +#endif /* WOLFSSL_HAVE_COPY_FREE_CB */ } return NULL; } @@ -174,15 +177,6 @@ static const char* GetCryptoCbCmdTypeStr(int type) } #endif -#ifndef NO_COPY_CB -static const char* GetCryptoCbCopyTypeStr(int type) -{ - switch (type) { - case WC_CRYPTOCB_COPY_TYPE_SHA256: return "SHA256-Copy"; - } - return NULL; -} -#endif /* !NO_COPY_CB */ #if (defined(HAVE_HKDF) && !defined(NO_HMAC)) || defined(HAVE_CMAC_KDF) static const char* GetKdfTypeStr(int type) @@ -263,13 +257,18 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info) GetCryptoCbCmdTypeStr(info->cmd.type), info->cmd.type); } #endif -#ifndef NO_COPY_CB +#ifdef WOLFSSL_HAVE_COPY_FREE_CB else if (info->algo_type == WC_ALGO_TYPE_COPY) { - printf("Crypto CB: %s %s (%d)\n", + printf("Crypto CB: %s %s Type=%d\n", GetAlgoTypeStr(info->algo_type), - GetCryptoCbCopyTypeStr(info->copy.type), info->copy.type); + GetAlgoTypeStr(info->copy.algo), info->copy.type); } -#endif + else if (info->algo_type == WC_ALGO_TYPE_FREE) { + printf("Crypto CB: %s %s Type=%d\n", + GetAlgoTypeStr(info->algo_type), + GetAlgoTypeStr(info->free.algo), info->free.type); + } +#endif /* WOLFSSL_HAVE_COPY_FREE_CB */ #if (defined(HAVE_HKDF) && !defined(NO_HMAC)) || \ defined(HAVE_CMAC_KDF) else if (info->algo_type == WC_ALGO_TYPE_KDF) { @@ -2045,40 +2044,65 @@ int wc_CryptoCb_Hkdf(int hashType, const byte* inKey, word32 inKeySz, } #endif /* HAVE_HKDF && !NO_HMAC */ -#ifndef NO_COPY_CB +#ifdef WOLFSSL_HAVE_COPY_FREE_CB /* General copy callback function for algorithm structures * devId: The device ID to use for the callback - * copyType: The type of structure being copied (enum wc_CryptoCbCopyType) + * algo: Algorithm type (enum wc_AlgoType) - WC_ALGO_TYPE_HASH, WC_ALGO_TYPE_CIPHER, etc + * type: Specific type - for HASH: enum wc_HashType, for CIPHER: enum wc_CipherType * src: Pointer to source structure * dst: Pointer to destination structure * Returns: 0 on success, negative on error, CRYPTOCB_UNAVAILABLE if not handled */ -int wc_CryptoCb_Copy(int devId, int copyType, void* src, void* dst) +int wc_CryptoCb_Copy(int devId, int algo, int type, void* src, void* dst) { int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); CryptoCb* dev; - /* Validate inputs */ - if (src == NULL || dst == NULL) { - return BAD_FUNC_ARG; - } - /* Find registered callback device */ dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_COPY); if (dev && dev->cb) { wc_CryptoInfo cryptoInfo; XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); cryptoInfo.algo_type = WC_ALGO_TYPE_COPY; - cryptoInfo.copy.type = copyType; + cryptoInfo.copy.algo = algo; + cryptoInfo.copy.type = type; cryptoInfo.copy.src = src; cryptoInfo.copy.dst = dst; - + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); } - + return wc_CryptoCb_TranslateErrorCode(ret); } -#endif /* !NO_COPY_CB */ + +/* General free callback function for algorithm structures + * devId: The device ID to use for the callback + * algo: Algorithm type (enum wc_AlgoType) - WC_ALGO_TYPE_HASH, WC_ALGO_TYPE_CIPHER, etc + * type: Specific type - for HASH: enum wc_HashType, for CIPHER: enum wc_CipherType + * obj: Pointer to object structure to free + * Returns: 0 on success, negative on error, CRYPTOCB_UNAVAILABLE if not handled + */ +int wc_CryptoCb_Free(int devId, int algo, int type, void* obj) +{ + int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + CryptoCb* dev; + + /* Find registered callback device */ + dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_FREE); + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_FREE; + cryptoInfo.free.algo = algo; + cryptoInfo.free.type = type; + cryptoInfo.free.obj = obj; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} +#endif /* WOLFSSL_HAVE_COPY_FREE_CB */ #if defined(HAVE_CMAC_KDF) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 8817c7ef4..de9480c97 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -2276,9 +2276,34 @@ int wc_InitSha256(wc_Sha256* sha256) void wc_Sha256Free(wc_Sha256* sha256) { + +#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_HAVE_COPY_FREE_CB) + int ret = 0; +#endif + if (sha256 == NULL) return; +#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_HAVE_COPY_FREE_CB) + #ifndef WOLF_CRYPTO_CB_FIND + if (sha256->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Free(sha256->devId, WC_ALGO_TYPE_HASH, + WC_HASH_TYPE_SHA256, (void*)sha256); + /* If they want the standard free, they can call it themselves */ + /* via their callback setting devId to INVALID_DEVID */ + /* otherwise assume the callback handled it */ + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return; + /* fall-through when unavailable */ + } + + /* silence compiler warning */ + (void)ret; + +#endif /* WOLF_CRYPTO_CB && WOLFSSL_HAVE_COPY_FREE_CB */ + #if defined(WOLFSSL_ESP32) && \ !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \ !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) @@ -2576,19 +2601,19 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) return BAD_FUNC_ARG; } -#if defined(WOLF_CRYPTO_CB) && !defined(NO_COPY_CB) +#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_HAVE_COPY_FREE_CB) #ifndef WOLF_CRYPTO_CB_FIND if (src->devId != INVALID_DEVID) #endif { /* Cast the source and destination to be void to keep the abstraction */ - ret = wc_CryptoCb_Copy(src->devId, WC_CRYPTOCB_COPY_TYPE_SHA256, - (void*)src, (void*)dst); + ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH, + WC_HASH_TYPE_SHA256, (void*)src, (void*)dst); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ } -#endif +#endif /* WOLF_CRYPTO_CB && WOLFSSL_HAVE_COPY_FREE_CB */ XMEMCPY(dst, src, sizeof(wc_Sha256)); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 633506aa1..1a19b5b17 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -61295,43 +61295,79 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) } } #endif /* !NO_SHA || !NO_SHA256 */ -#ifndef NO_COPY_CB +#ifdef WOLFSSL_HAVE_COPY_FREE_CB else if (info->algo_type == WC_ALGO_TYPE_COPY) { #ifdef DEBUG_WOLFSSL - WOLFSSL_MSG_EX("CryptoDevCb: Copy Type %d\n", info->copy.type); + WOLFSSL_MSG_EX("CryptoDevCb: Copy Algo=%d Type=%d\n", + info->copy.algo, info->copy.type); #endif - switch (info->copy.type) { + if (info->copy.algo == WC_ALGO_TYPE_HASH) { + switch (info->copy.type) { #ifndef NO_SHA256 - case WC_CRYPTOCB_COPY_TYPE_SHA256: - { - /* Cast the source and destination to the correct type */ - /* Given as a void pointer initally for abstraction */ - wc_Sha256* src = (wc_Sha256*)info->copy.src; - wc_Sha256* dst = (wc_Sha256*)info->copy.dst; - - /* set devId to invalid, so software is used */ - src->devId = INVALID_DEVID; + case WC_HASH_TYPE_SHA256: + { + /* Cast the source and destination to the correct type */ + /* Given as a void pointer initially for abstraction */ + wc_Sha256* src = (wc_Sha256*)info->copy.src; + wc_Sha256* dst = (wc_Sha256*)info->copy.dst; + /* set devId to invalid, so software is used */ + src->devId = INVALID_DEVID; + ret = wc_Sha256Copy(src, dst); - ret = wc_Sha256Copy(src, dst); + /* reset devId */ + src->devId = devIdArg; + if (ret == 0) { + /* Set the devId of the destination to the same as the */ + /* since we used the software implementation of copy */ + /* so dst would have been set to INVALID_DEVID */ + dst->devId = devIdArg; + } - /* reset devId */ - src->devId = devIdArg; - if (ret == 0) { - /* Set the devId of the destination to the same as the */ - /* since we used the software implementation of copy */ - /* so dst would have been set to INVALID_DEVID */ - dst->devId = devIdArg; + break; } - - break; - } #endif /* !NO_SHA256 */ - default: - ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); - break; + default: + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); + break; + } + } + else { + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); } } -#endif /* !NO_COPY_CB */ + else if (info->algo_type == WC_ALGO_TYPE_FREE) { +#ifdef DEBUG_WOLFSSL + WOLFSSL_MSG_EX("CryptoDevCb: Free Algo=%d Type=%d\n", + info->free.algo, info->free.type); +#endif + + if (info->free.algo == WC_ALGO_TYPE_HASH) { + switch (info->free.type) { +#ifndef NO_SHA256 + case WC_HASH_TYPE_SHA256: + { + wc_Sha256* sha = (wc_Sha256*)info->free.obj; + /* set devId to invalid, so software is used */ + sha->devId = INVALID_DEVID; + + /* Call the actual free function */ + wc_Sha256Free(sha); + + /* Note: devId doesn't need to be restored as object is freed */ + ret = 0; + break; + } +#endif + default: + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); + break; + } + } + else { + ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); + } + } +#endif /* WOLFSSL_HAVE_COPY_FREE_CB */ #ifndef NO_HMAC else if (info->algo_type == WC_ALGO_TYPE_HMAC) { if (info->hmac.hmac == NULL) diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 6052bd567..8e52c152e 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -101,14 +101,6 @@ enum wc_CryptoCbCmdType { }; #endif -#ifndef NO_COPY_CB -/* CryptoCb Copy Types - for copy operations on algorithm structures */ -enum wc_CryptoCbCopyType { - WC_CRYPTOCB_COPY_TYPE_NONE = 0, - WC_CRYPTOCB_COPY_TYPE_SHA256, - WC_CRYPTOCB_COPY_TYPE_MAX = WC_CRYPTOCB_COPY_TYPE_SHA256 -}; -#endif /* !NO_COPY_CB */ #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) @@ -477,13 +469,19 @@ typedef struct wc_CryptoInfo { void *ctx; } cmd; #endif -#ifndef NO_COPY_CB +#ifdef WOLFSSL_HAVE_COPY_FREE_CB struct { /* uses wc_AlgoType=WC_ALGO_TYPE_COPY */ - int type; /* enum wc_CryptoCbCopyType */ + int algo; /* enum wc_AlgoType - WC_ALGO_TYPE_HASH, WC_ALGO_TYPE_CIPHER, etc */ + int type; /* For HASH: enum wc_HashType, For CIPHER: enum wc_CipherType */ void *src; /* Source structure to copy from */ void *dst; /* Destination structure to copy to */ } copy; -#endif + struct { /* uses wc_AlgoType=WC_ALGO_TYPE_FREE */ + int algo; /* enum wc_AlgoType - WC_ALGO_TYPE_HASH, WC_ALGO_TYPE_CIPHER, etc */ + int type; /* For HASH: enum wc_HashType, For CIPHER: enum wc_CipherType */ + void *obj; /* Object structure to free */ + } free; +#endif /* WOLFSSL_HAVE_COPY_FREE_CB */ #if defined(HAVE_HKDF) || defined(HAVE_CMAC_KDF) struct { int type; /* enum wc_KdfType */ @@ -753,10 +751,11 @@ WOLFSSL_LOCAL int wc_CryptoCb_GetCert(int devId, const char *label, word32* outSz, int *format, void *heap); #endif -#ifndef NO_COPY_CB -WOLFSSL_LOCAL int wc_CryptoCb_Copy(int devId, int copyType, void* src, +#ifdef WOLFSSL_HAVE_COPY_FREE_CB +WOLFSSL_LOCAL int wc_CryptoCb_Copy(int devId, int algo, int type, void* src, void* dst); -#endif +WOLFSSL_LOCAL int wc_CryptoCb_Free(int devId, int algo, int type, void* obj); +#endif /* WOLFSSL_HAVE_COPY_FREE_CB */ #endif /* WOLF_CRYPTO_CB */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index e44d60244..f423be296 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1310,8 +1310,8 @@ enum wc_AlgoType { WC_ALGO_TYPE_CERT = 8, WC_ALGO_TYPE_KDF = 9, WC_ALGO_TYPE_COPY = 10, - - WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_COPY + WC_ALGO_TYPE_FREE = 11, + WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_FREE }; /* KDF types */