From 1ef9a8fe7c1cd91e36f5541a806793bacffe1a30 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Thu, 20 Jun 2024 14:15:28 -0700 Subject: [PATCH] Added crypto callback for SHA3 and extended the test.c tests for it in cryptocb_test. --- wolfcrypt/src/cryptocb.c | 34 +++++++++++++ wolfcrypt/src/sha3.c | 43 +++++++++++++--- wolfcrypt/test/test.c | 99 ++++++++++++++++++++++++++++++++++++ wolfssl/wolfcrypt/cryptocb.h | 8 +++ wolfssl/wolfcrypt/sha3.h | 5 ++ 5 files changed, 182 insertions(+), 7 deletions(-) diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index e4943abca1..b3a4949098 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -1606,6 +1606,40 @@ int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, } #endif /* WOLFSSL_SHA512 */ +#ifdef WOLFSSL_SHA3 +int wc_CryptoCb_Sha3Hash(wc_Sha3* sha3, int type, const byte* in, + word32 inSz, byte* digest) +{ + int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + CryptoCb* dev; + + /* locate registered callback */ + if (sha3) { + dev = wc_CryptoCb_FindDevice(sha3->devId, WC_ALGO_TYPE_HASH); + } + else + { + /* locate first callback and try using it */ + dev = wc_CryptoCb_FindDeviceByIndex(0); + } + + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_HASH; + cryptoInfo.hash.type = type; + cryptoInfo.hash.sha3 = sha3; + cryptoInfo.hash.in = in; + cryptoInfo.hash.inSz = inSz; + cryptoInfo.hash.digest = digest; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return wc_CryptoCb_TranslateErrorCode(ret); +} +#endif /* WOLFSSL_SHA3 */ + #ifndef NO_HMAC int wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in, word32 inSz, byte* digest) diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index 57b8d2eb4f..afc8bd5af7 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -43,6 +43,9 @@ #include #include +#ifdef WOLF_CRYPTO_CB + #include +#endif #ifdef NO_INLINE #include #else @@ -802,7 +805,7 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l) * devId Device identifier for asynchronous operation. * returns 0 on success. */ -static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId) +static int wc_InitSha3(wc_Sha3* sha3, int type, void* heap, int devId) { int ret = 0; @@ -817,8 +820,12 @@ static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) ret = wolfAsync_DevCtxInit(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3, sha3->heap, devId); +#elif defined(WOLF_CRYPTO_CB) + sha3->devId = devId; + sha3->type = type; #else (void)devId; + (void)type; #endif /* WOLFSSL_ASYNC_CRYPT */ return ret; @@ -845,6 +852,17 @@ static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) return 0; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (sha3->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Sha3Hash(sha3, sha3->type, data, len, NULL); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + } +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) { #if defined(HAVE_INTEL_QA) && defined(QAT_V2) @@ -880,6 +898,17 @@ static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (sha3->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Sha3Hash(sha3, sha3->type, NULL, 0, hash); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + } +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) { #if defined(HAVE_INTEL_QA) && defined(QAT_V2) @@ -981,7 +1010,7 @@ static int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len) */ int wc_InitSha3_224(wc_Sha3* sha3, void* heap, int devId) { - return wc_InitSha3(sha3, heap, devId); + return wc_InitSha3(sha3, WC_HASH_TYPE_SHA3_224, heap, devId); } /* Update the SHA3-224 hash state with message data. @@ -1053,7 +1082,7 @@ int wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst) */ int wc_InitSha3_256(wc_Sha3* sha3, void* heap, int devId) { - return wc_InitSha3(sha3, heap, devId); + return wc_InitSha3(sha3, WC_HASH_TYPE_SHA3_256, heap, devId); } /* Update the SHA3-256 hash state with message data. @@ -1125,7 +1154,7 @@ int wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst) */ int wc_InitSha3_384(wc_Sha3* sha3, void* heap, int devId) { - return wc_InitSha3(sha3, heap, devId); + return wc_InitSha3(sha3, WC_HASH_TYPE_SHA3_384, heap, devId); } /* Update the SHA3-384 hash state with message data. @@ -1197,7 +1226,7 @@ int wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst) */ int wc_InitSha3_512(wc_Sha3* sha3, void* heap, int devId) { - return wc_InitSha3(sha3, heap, devId); + return wc_InitSha3(sha3, WC_HASH_TYPE_SHA3_512, heap, devId); } /* Update the SHA3-512 hash state with message data. @@ -1286,7 +1315,7 @@ int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags) */ int wc_InitShake128(wc_Shake* shake, void* heap, int devId) { - return wc_InitSha3(shake, heap, devId); + return wc_InitSha3(shake, WC_HASH_TYPE_SHAKE128, heap, devId); } /* Update the SHAKE128 hash state with message data. @@ -1430,7 +1459,7 @@ int wc_Shake128_Copy(wc_Shake* src, wc_Shake* dst) */ int wc_InitShake256(wc_Shake* shake, void* heap, int devId) { - return wc_InitSha3(shake, heap, devId); + return wc_InitSha3(shake, WC_HASH_TYPE_SHAKE256, heap, devId); } /* Update the SHAKE256 hash state with message data. diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c1bafcd643..1191cd06b3 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -54801,6 +54801,97 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) #endif } else + #endif + #ifdef WOLFSSL_SHA3 + if (info->hash.type == WC_HASH_TYPE_SHA3_224) { + if (info->hash.sha3 == NULL) + return NOT_COMPILED_IN; + + /* set devId to invalid, so software is used */ + info->hash.sha3->devId = INVALID_DEVID; + + if (info->hash.in != NULL) { + ret = wc_Sha3_224_Update( + info->hash.sha3, + info->hash.in, + info->hash.inSz); + } + if (info->hash.digest != NULL) { + ret = wc_Sha3_224_Final( + info->hash.sha3, + info->hash.digest); + } + + /* reset devId */ + info->hash.sha3->devId = devIdArg; + } + else if (info->hash.type == WC_HASH_TYPE_SHA3_256) { + if (info->hash.sha3 == NULL) + return NOT_COMPILED_IN; + + /* set devId to invalid, so software is used */ + info->hash.sha3->devId = INVALID_DEVID; + + if (info->hash.in != NULL) { + ret = wc_Sha3_256_Update( + info->hash.sha3, + info->hash.in, + info->hash.inSz); + } + if (info->hash.digest != NULL) { + ret = wc_Sha3_256_Final( + info->hash.sha3, + info->hash.digest); + } + + /* reset devId */ + info->hash.sha3->devId = devIdArg; + } + else if (info->hash.type == WC_HASH_TYPE_SHA3_384) { + if (info->hash.sha3 == NULL) + return NOT_COMPILED_IN; + + /* set devId to invalid, so software is used */ + info->hash.sha3->devId = INVALID_DEVID; + + if (info->hash.in != NULL) { + ret = wc_Sha3_384_Update( + info->hash.sha3, + info->hash.in, + info->hash.inSz); + } + if (info->hash.digest != NULL) { + ret = wc_Sha3_384_Final( + info->hash.sha3, + info->hash.digest); + } + + /* reset devId */ + info->hash.sha3->devId = devIdArg; + } + else if (info->hash.type == WC_HASH_TYPE_SHA3_512) { + if (info->hash.sha3 == NULL) + return NOT_COMPILED_IN; + + /* set devId to invalid, so software is used */ + info->hash.sha3->devId = INVALID_DEVID; + + if (info->hash.in != NULL) { + ret = wc_Sha3_512_Update( + info->hash.sha3, + info->hash.in, + info->hash.inSz); + } + if (info->hash.digest != NULL) { + ret = wc_Sha3_512_Final( + info->hash.sha3, + info->hash.digest); + } + + /* reset devId */ + info->hash.sha3->devId = devIdArg; + } + else #endif { } @@ -54998,6 +55089,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) #ifdef WOLFSSL_SHA512 if (ret == 0) ret = sha512_test(); +#ifdef WOLFSSL_SHA3 + if (ret == 0) + ret = sha3_test(); +#endif #endif #ifndef NO_HMAC #ifndef NO_SHA @@ -55008,6 +55103,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) if (ret == 0) ret = hmac_sha256_test(); #endif + #ifdef WOLFSSL_SHA3 + if (ret == 0) + ret = hmac_sha3_test(); + #endif #endif #ifndef NO_PWDBASED #if defined(HAVE_PBKDF2) && !defined(NO_SHA256) && !defined(NO_HMAC) diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 549dbbe724..29580eaa6a 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -398,6 +398,9 @@ typedef struct wc_CryptoInfo { #endif #ifdef WOLFSSL_SHA512 wc_Sha512* sha512; + #endif + #ifdef WOLFSSL_SHA3 + wc_Sha3* sha3; #endif void* ctx; #if HAVE_ANONYMOUS_INLINE_AGGREGATES @@ -622,6 +625,11 @@ WOLFSSL_LOCAL int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, word32 inSz, byte* digest); #endif +#ifdef WOLFSSL_SHA3 +WOLFSSL_LOCAL int wc_CryptoCb_Sha3Hash(wc_Sha3* sha3, int type, const byte* in, + word32 inSz, byte* digest); +#endif + #ifndef NO_HMAC WOLFSSL_LOCAL int wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in, word32 inSz, byte* digest); diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index 149c714c49..955704d11c 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -124,6 +124,11 @@ struct wc_Sha3 { void* heap; +#ifdef WOLF_CRYPTO_CB + int devId; + int type; /* enum wc_HashType */ +#endif + #ifdef WC_C_DYNAMIC_FALLBACK void (*sha3_block)(word64 *s); void (*sha3_block_n)(word64 *s, const byte* data, word32 n,