diff --git a/wolfcrypt/src/port/maxim/max3266x.c b/wolfcrypt/src/port/maxim/max3266x.c index 494999f100..06c6b8c7e9 100644 --- a/wolfcrypt/src/port/maxim/max3266x.c +++ b/wolfcrypt/src/port/maxim/max3266x.c @@ -136,6 +136,77 @@ int wc_MxcAesCryptoCb(wc_CryptoInfo* info) #ifdef MAX3266X_SHA_CB +#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT + +/* Shared callback handler: Update grows buffer, Final computes hash. */ +static int wc_MxcShaCbDispatch(byte** msg, word32* used, word32* len, + void* heap, const byte* in, word32 inSz, + byte* digest, MXC_TPU_HASH_TYPE algo) +{ + if (in != NULL && digest == NULL) { + MAX3266X_MSG("Update CB"); + return _wc_Hash_Grow(msg, used, len, in, (int)inSz, heap); + } + if (in == NULL && digest != NULL) { + MAX3266X_MSG("Final CB"); + return wc_MXC_TPU_SHA_Final(msg, used, len, heap, digest, algo); + } + if (inSz == 0) { + return 0; /* Don't need to Update when Size is Zero */ + } + return BAD_FUNC_ARG; +} + +int wc_MxcShaCryptoCb(wc_CryptoInfo* info) +{ + switch (info->hash.type) { + #ifndef NO_SHA + case WC_HASH_TYPE_SHA: + return wc_MxcShaCbDispatch(&info->hash.sha1->msg, + &info->hash.sha1->used, &info->hash.sha1->len, + info->hash.sha1->heap, info->hash.in, + info->hash.inSz, info->hash.digest, + MXC_TPU_HASH_SHA1); + #endif + #ifdef WOLFSSL_SHA224 + case WC_HASH_TYPE_SHA224: + return wc_MxcShaCbDispatch(&info->hash.sha224->msg, + &info->hash.sha224->used, &info->hash.sha224->len, + info->hash.sha224->heap, info->hash.in, + info->hash.inSz, info->hash.digest, + MXC_TPU_HASH_SHA224); + #endif + #ifndef NO_SHA256 + case WC_HASH_TYPE_SHA256: + return wc_MxcShaCbDispatch(&info->hash.sha256->msg, + &info->hash.sha256->used, &info->hash.sha256->len, + info->hash.sha256->heap, info->hash.in, + info->hash.inSz, info->hash.digest, + MXC_TPU_HASH_SHA256); + #endif + #ifdef WOLFSSL_SHA384 + case WC_HASH_TYPE_SHA384: + return wc_MxcShaCbDispatch(&info->hash.sha384->msg, + &info->hash.sha384->used, &info->hash.sha384->len, + info->hash.sha384->heap, info->hash.in, + info->hash.inSz, info->hash.digest, + MXC_TPU_HASH_SHA384); + #endif + #ifdef WOLFSSL_SHA512 + case WC_HASH_TYPE_SHA512: + return wc_MxcShaCbDispatch(&info->hash.sha512->msg, + &info->hash.sha512->used, &info->hash.sha512->len, + info->hash.sha512->heap, info->hash.in, + info->hash.inSz, info->hash.digest, + MXC_TPU_HASH_SHA512); + #endif + default: + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } +} + +#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */ + int wc_MXC_TPU_SHA_Update(unsigned int* digest, unsigned int* buffer, unsigned int* buffLen, unsigned int* loLen, unsigned int* hiLen, int stateWords, @@ -271,9 +342,76 @@ int wc_MxcShaCryptoCb(wc_CryptoInfo* info) return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); } } + +#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */ #endif /* MAX3266X_SHA_CB */ #ifdef WOLF_CRYPTO_CB_COPY +#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT +static int wc_MxcCopyCb(wc_CryptoInfo* info) +{ + if (info == NULL || info->copy.src == NULL || info->copy.dst == NULL) { + return BAD_FUNC_ARG; + } + + switch (info->copy.type) { +#ifdef MAX3266X_SHA_CB + #ifndef NO_SHA + case WC_HASH_TYPE_SHA: + return wc_MXC_TPU_SHA_Copy(info->copy.src, info->copy.dst, + sizeof(wc_Sha), + &((wc_Sha*)info->copy.dst)->msg, + &((wc_Sha*)info->copy.dst)->used, + &((wc_Sha*)info->copy.dst)->len, + ((wc_Sha*)info->copy.dst)->heap, + ((wc_Sha*)info->copy.src)->heap); + #endif + #ifdef WOLFSSL_SHA224 + case WC_HASH_TYPE_SHA224: + return wc_MXC_TPU_SHA_Copy(info->copy.src, info->copy.dst, + sizeof(wc_Sha224), + &((wc_Sha224*)info->copy.dst)->msg, + &((wc_Sha224*)info->copy.dst)->used, + &((wc_Sha224*)info->copy.dst)->len, + ((wc_Sha224*)info->copy.dst)->heap, + ((wc_Sha224*)info->copy.src)->heap); + #endif + #ifndef NO_SHA256 + case WC_HASH_TYPE_SHA256: + return wc_MXC_TPU_SHA_Copy(info->copy.src, info->copy.dst, + sizeof(wc_Sha256), + &((wc_Sha256*)info->copy.dst)->msg, + &((wc_Sha256*)info->copy.dst)->used, + &((wc_Sha256*)info->copy.dst)->len, + ((wc_Sha256*)info->copy.dst)->heap, + ((wc_Sha256*)info->copy.src)->heap); + #endif + #ifdef WOLFSSL_SHA384 + case WC_HASH_TYPE_SHA384: + return wc_MXC_TPU_SHA_Copy(info->copy.src, info->copy.dst, + sizeof(wc_Sha384), + &((wc_Sha384*)info->copy.dst)->msg, + &((wc_Sha384*)info->copy.dst)->used, + &((wc_Sha384*)info->copy.dst)->len, + ((wc_Sha384*)info->copy.dst)->heap, + ((wc_Sha384*)info->copy.src)->heap); + #endif + #ifdef WOLFSSL_SHA512 + case WC_HASH_TYPE_SHA512: + return wc_MXC_TPU_SHA_Copy(info->copy.src, info->copy.dst, + sizeof(wc_Sha512), + &((wc_Sha512*)info->copy.dst)->msg, + &((wc_Sha512*)info->copy.dst)->used, + &((wc_Sha512*)info->copy.dst)->len, + ((wc_Sha512*)info->copy.dst)->heap, + ((wc_Sha512*)info->copy.src)->heap); + #endif +#endif /* MAX3266X_SHA_CB */ + default: + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } +} +#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */ static int wc_MxcCopyCb(wc_CryptoInfo* info) { word32 sz; @@ -321,8 +459,70 @@ static int wc_MxcCopyCb(wc_CryptoInfo* info) XMEMCPY(info->copy.dst, info->copy.src, sz); return 0; } +#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */ #endif /* WOLF_CRYPTO_CB_COPY */ +#ifdef WOLF_CRYPTO_CB_FREE +static int wc_MxcFreeCb(wc_CryptoInfo* info) +{ + if (info == NULL || info->free.obj == NULL) { + return BAD_FUNC_ARG; + } + + switch (info->free.type) { +#ifdef MAX3266X_SHA_CB + #ifndef NO_SHA + case WC_HASH_TYPE_SHA: + wc_MXC_TPU_SHA_FreeCtx(info->free.obj, sizeof(wc_Sha), + &((wc_Sha*)info->free.obj)->msg, + &((wc_Sha*)info->free.obj)->used, + &((wc_Sha*)info->free.obj)->len, + ((wc_Sha*)info->free.obj)->heap); + return 0; + #endif + #ifdef WOLFSSL_SHA224 + case WC_HASH_TYPE_SHA224: + wc_MXC_TPU_SHA_FreeCtx(info->free.obj, sizeof(wc_Sha224), + &((wc_Sha224*)info->free.obj)->msg, + &((wc_Sha224*)info->free.obj)->used, + &((wc_Sha224*)info->free.obj)->len, + ((wc_Sha224*)info->free.obj)->heap); + return 0; + #endif + #ifndef NO_SHA256 + case WC_HASH_TYPE_SHA256: + wc_MXC_TPU_SHA_FreeCtx(info->free.obj, sizeof(wc_Sha256), + &((wc_Sha256*)info->free.obj)->msg, + &((wc_Sha256*)info->free.obj)->used, + &((wc_Sha256*)info->free.obj)->len, + ((wc_Sha256*)info->free.obj)->heap); + return 0; + #endif + #ifdef WOLFSSL_SHA384 + case WC_HASH_TYPE_SHA384: + wc_MXC_TPU_SHA_FreeCtx(info->free.obj, sizeof(wc_Sha384), + &((wc_Sha384*)info->free.obj)->msg, + &((wc_Sha384*)info->free.obj)->used, + &((wc_Sha384*)info->free.obj)->len, + ((wc_Sha384*)info->free.obj)->heap); + return 0; + #endif + #ifdef WOLFSSL_SHA512 + case WC_HASH_TYPE_SHA512: + wc_MXC_TPU_SHA_FreeCtx(info->free.obj, sizeof(wc_Sha512), + &((wc_Sha512*)info->free.obj)->msg, + &((wc_Sha512*)info->free.obj)->used, + &((wc_Sha512*)info->free.obj)->len, + ((wc_Sha512*)info->free.obj)->heap); + return 0; + #endif +#endif /* MAX3266X_SHA_CB */ + default: + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + } +} +#endif /* WOLF_CRYPTO_CB_FREE */ + /* General Callback Function to determine ALGO Type */ int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) { @@ -355,8 +555,12 @@ int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) ret = wc_MxcCopyCb(info); break; #endif /* WOLF_CRYPTO_CB_COPY */ - /* No WC_ALGO_TYPE_FREE needed: SHA contexts have no heap - * allocations to clean up. */ +#ifdef WOLF_CRYPTO_CB_FREE + case WC_ALGO_TYPE_FREE: + MAX3266X_MSG("Using MXC Free Callback:"); + ret = wc_MxcFreeCb(info); + break; +#endif /* WOLF_CRYPTO_CB_FREE */ default: MAX3266X_MSG("Callback not supported with MXC, using SW"); /* return this to bypass HW and use SW */ @@ -679,6 +883,172 @@ int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) +#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT + +/* Check for empty message and provide pre-computed digest if so */ +/* Returns 1 if empty (digest filled), 0 if needs hardware processing */ +int wc_MXC_TPU_SHA_GetDigest(const unsigned char* msg, unsigned int msgSz, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo) +{ + if (digest == NULL) { + return BAD_FUNC_ARG; + } + if (msg == NULL && msgSz == 0) { + switch (algo) { + #ifndef NO_SHA + case MXC_TPU_HASH_SHA1: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA1, WC_SHA_DIGEST_SIZE); + break; + #endif /* NO_SHA */ + #ifdef WOLFSSL_SHA224 + case MXC_TPU_HASH_SHA224: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA224, WC_SHA224_DIGEST_SIZE); + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case MXC_TPU_HASH_SHA256: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA256, WC_SHA256_DIGEST_SIZE); + break; + #endif /* NO_SHA256 */ + #ifdef WOLFSSL_SHA384 + case MXC_TPU_HASH_SHA384: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA384, WC_SHA384_DIGEST_SIZE); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case MXC_TPU_HASH_SHA512: + XMEMCPY(digest, MXC_EMPTY_DIGEST_SHA512, WC_SHA512_DIGEST_SIZE); + break; + #endif /* WOLFSSL_SHA512 */ + default: + return BAD_FUNC_ARG; + } + return 1; /* True: empty digest provided */ + } + return 0; /* False: needs hardware processing */ +} + +/* Compute hash from accumulated message using TPU hardware */ +int wc_MXC_TPU_SHA_GetHash(const unsigned char* msg, unsigned int msgSz, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo) +{ + int status; + if (digest == NULL || (msg == NULL && msgSz != 0)) { + return BAD_FUNC_ARG; + } + status = wc_MXC_TPU_SHA_GetDigest(msg, msgSz, digest, algo); + /* True Case that msg is an empty string */ + if (status == 1) { + /* Hardware cannot handle the case of an empty string */ + /* so in the case of this we will provide the hash via software */ + return 0; + } + /* False Case where msg needs to be processed */ + else if (status == 0) { + status = wolfSSL_HwHashMutexLock(); /* Set Mutex */ + if (status != 0) { /* Mutex Call Check */ + return status; + } + MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TPU); + MXC_TPU_Hash_Config(algo); + status = MXC_TPU_Hash_SHA((const char *)msg, algo, msgSz, + (char *)digest); + MAX3266X_MSG("SHA HW Acceleration Used"); + wolfSSL_HwHashMutexUnLock(); /* Release Mutex */ + if (wc_MXC_error(&status) != 0) { + MAX3266X_MSG("SHA HW Error Occurred"); + return status; + } + } + /* Error Occurred */ + return status; +} + +/* Free HASH_KEEP message buffer and reset fields */ +void wc_MXC_TPU_SHA_Free(byte** msg, word32* used, word32* len, void* heap) +{ + if (msg == NULL) { + return; + } + if (*msg != NULL) { + XFREE(*msg, heap, DYNAMIC_TYPE_TMP_BUFFER); + *msg = NULL; + } + if (used != NULL) { + *used = 0; + } + if (len != NULL) { + *len = 0; + } +} + +/* Free HASH_KEEP message buffer and zero the full SHA context struct */ +void wc_MXC_TPU_SHA_FreeCtx(void* ctx, word32 ctxSz, byte** msg, word32* used, + word32* len, void* heap) +{ + if (ctx == NULL) { + return; + } + wc_MXC_TPU_SHA_Free(msg, used, len, heap); + XMEMSET(ctx, 0, ctxSz); +} + +/* Copy SHA context struct and deep copy the HASH_KEEP message buffer. + * Frees any existing dst msg buffer to prevent memory leaks when copying + * into an already-used context. */ +int wc_MXC_TPU_SHA_Copy(void* src, void* dst, word32 ctxSz, + byte** dstMsg, word32* dstUsed, word32* dstLen, + void* dstHeap, void* srcHeap) +{ + byte* srcBuf = NULL; + + if (src == NULL || dst == NULL || dstMsg == NULL || + dstUsed == NULL || dstLen == NULL || ctxSz == 0) { + return BAD_FUNC_ARG; + } + + /* Free existing dst msg buffer using dst's original heap */ + wc_MXC_TPU_SHA_Free(dstMsg, dstUsed, dstLen, dstHeap); + + /* Shallow copy the full context struct */ + XMEMCPY(dst, src, ctxSz); + + /* Deep copy src msg buffer if present. Since dstMsg points into the dst + * struct, the XMEMCPY above overwrites it with the src's msg pointer. + * Save that pointer, allocate a new buffer for dst, and copy the data. + * Do NOT move srcBuf assignment before XMEMCPY - it must capture the + * src msg pointer that lands in *dstMsg after the shallow copy. */ + if (*dstMsg != NULL) { + srcBuf = *dstMsg; + *dstMsg = (byte*)XMALLOC(*dstLen, srcHeap, DYNAMIC_TYPE_TMP_BUFFER); + if (*dstMsg == NULL) { + return MEMORY_E; + } + XMEMCPY(*dstMsg, srcBuf, *dstUsed); + } + + return 0; +} + +/* Compute hash, free message buffer, and reset HASH_KEEP fields */ +int wc_MXC_TPU_SHA_Final(unsigned char** msg, unsigned int* used, + unsigned int* len, void* heap, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo) +{ + int status; + if (msg == NULL || used == NULL || len == NULL || digest == NULL) { + return BAD_FUNC_ARG; + } + status = wc_MXC_TPU_SHA_GetHash(*msg, *used, digest, algo); + wc_MXC_TPU_SHA_Free(msg, used, len, heap); + return status; +} + +#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */ + /* TPU hash helpers (bare-metal SHA accelerator) */ /* Reset TPU, select hash function, and restore intermediate state into @@ -948,9 +1318,360 @@ static int wc_MXC_TPU_SHA_Init(unsigned int* digest, int stateWords, return 0; } +#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */ + /* Per-algorithm Init / Update / Final / GetHash / Copy / Free */ #ifndef MAX3266X_SHA_CB + +#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT + +#if !defined(NO_SHA) + +WOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + XMEMSET(sha, 0, sizeof(*sha)); + sha->heap = heap; + return 0; +} + +WOLFSSL_API int wc_ShaUpdate(wc_Sha* sha, const unsigned char* data, + unsigned int len) +{ + if (sha == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + return _wc_Hash_Grow(&sha->msg, &sha->used, &sha->len, + data, (int)len, sha->heap); +} + +WOLFSSL_API int wc_ShaFinal(wc_Sha* sha, unsigned char* hash) +{ + if (sha == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Final(&sha->msg, &sha->used, &sha->len, + sha->heap, hash, MXC_TPU_HASH_SHA1); +} + +WOLFSSL_API int wc_ShaGetHash(wc_Sha* sha, unsigned char* hash) +{ + if (sha == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_GetHash((const unsigned char*)sha->msg, + sha->used, hash, MXC_TPU_HASH_SHA1); +} + +WOLFSSL_API int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Copy(src, dst, sizeof(wc_Sha), + &dst->msg, &dst->used, &dst->len, + dst->heap, src->heap); +} + +WOLFSSL_API void wc_ShaFree(wc_Sha* sha) +{ + if (sha == NULL) { + return; + } + wc_MXC_TPU_SHA_FreeCtx(sha, sizeof(wc_Sha), &sha->msg, &sha->used, + &sha->len, sha->heap); +} + +#endif /* NO_SHA */ + +#if defined(WOLFSSL_SHA224) + +WOLFSSL_API int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId) +{ + if (sha224 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + XMEMSET(sha224, 0, sizeof(*sha224)); + sha224->heap = heap; + return 0; +} + +WOLFSSL_API int wc_InitSha224(wc_Sha224* sha224) +{ + return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha224Update(wc_Sha224* sha224, const unsigned char* data, + unsigned int len) +{ + if (sha224 == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + return _wc_Hash_Grow(&sha224->msg, &sha224->used, &sha224->len, + data, (int)len, sha224->heap); +} + +WOLFSSL_API int wc_Sha224Final(wc_Sha224* sha224, unsigned char* hash) +{ + if (sha224 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Final(&sha224->msg, &sha224->used, &sha224->len, + sha224->heap, hash, + MXC_TPU_HASH_SHA224); +} + +WOLFSSL_API int wc_Sha224GetHash(wc_Sha224* sha224, unsigned char* hash) +{ + if (sha224 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_GetHash((const unsigned char*)sha224->msg, + sha224->used, hash, + MXC_TPU_HASH_SHA224); +} + +WOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Copy(src, dst, sizeof(wc_Sha224), + &dst->msg, &dst->used, &dst->len, + dst->heap, src->heap); +} + +WOLFSSL_API void wc_Sha224Free(wc_Sha224* sha224) +{ + if (sha224 == NULL) { + return; + } + wc_MXC_TPU_SHA_FreeCtx(sha224, sizeof(wc_Sha224), &sha224->msg, + &sha224->used, &sha224->len, + sha224->heap); +} + +#endif /* WOLFSSL_SHA224 */ + +#if !defined(NO_SHA256) + +WOLFSSL_API int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) +{ + if (sha256 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + XMEMSET(sha256, 0, sizeof(*sha256)); + sha256->heap = heap; + return 0; +} + +WOLFSSL_API int wc_InitSha256(wc_Sha256* sha256) +{ + return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha256Update(wc_Sha256* sha256, const unsigned char* data, + unsigned int len) +{ + if (sha256 == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + return _wc_Hash_Grow(&sha256->msg, &sha256->used, &sha256->len, + data, (int)len, sha256->heap); +} + +WOLFSSL_API int wc_Sha256Final(wc_Sha256* sha256, unsigned char* hash) +{ + if (sha256 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Final(&sha256->msg, &sha256->used, &sha256->len, + sha256->heap, hash, + MXC_TPU_HASH_SHA256); +} + +WOLFSSL_API int wc_Sha256GetHash(wc_Sha256* sha256, unsigned char* hash) +{ + if (sha256 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_GetHash((const unsigned char*)sha256->msg, + sha256->used, hash, + MXC_TPU_HASH_SHA256); +} + +WOLFSSL_API int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Copy(src, dst, sizeof(wc_Sha256), + &dst->msg, &dst->used, &dst->len, + dst->heap, src->heap); +} + +WOLFSSL_API void wc_Sha256Free(wc_Sha256* sha256) +{ + if (sha256 == NULL) { + return; + } + wc_MXC_TPU_SHA_FreeCtx(sha256, sizeof(wc_Sha256), &sha256->msg, + &sha256->used, &sha256->len, + sha256->heap); +} + +#endif /* NO_SHA256 */ + +#if defined(WOLFSSL_SHA384) + +WOLFSSL_API int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) +{ + if (sha384 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + XMEMSET(sha384, 0, sizeof(*sha384)); + sha384->heap = heap; + return 0; +} + +WOLFSSL_API int wc_InitSha384(wc_Sha384* sha384) +{ + return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha384Update(wc_Sha384* sha384, const unsigned char* data, + unsigned int len) +{ + if (sha384 == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + return _wc_Hash_Grow(&sha384->msg, &sha384->used, &sha384->len, + data, (int)len, sha384->heap); +} + +WOLFSSL_API int wc_Sha384Final(wc_Sha384* sha384, unsigned char* hash) +{ + if (sha384 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Final(&sha384->msg, &sha384->used, &sha384->len, + sha384->heap, hash, + MXC_TPU_HASH_SHA384); +} + +WOLFSSL_API int wc_Sha384GetHash(wc_Sha384* sha384, unsigned char* hash) +{ + if (sha384 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_GetHash((const unsigned char*)sha384->msg, + sha384->used, hash, + MXC_TPU_HASH_SHA384); +} + +WOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Copy(src, dst, sizeof(wc_Sha384), + &dst->msg, &dst->used, &dst->len, + dst->heap, src->heap); +} + +WOLFSSL_API void wc_Sha384Free(wc_Sha384* sha384) +{ + if (sha384 == NULL) { + return; + } + wc_MXC_TPU_SHA_FreeCtx(sha384, sizeof(wc_Sha384), &sha384->msg, + &sha384->used, &sha384->len, + sha384->heap); +} + +#endif /* WOLFSSL_SHA384 */ + +#if defined(WOLFSSL_SHA512) + +WOLFSSL_API int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) +{ + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + XMEMSET(sha512, 0, sizeof(*sha512)); + sha512->heap = heap; +#if defined(WOLFSSL_SHA512_HASHTYPE) + sha512->hashType = WC_HASH_TYPE_SHA512; +#endif + return 0; +} + +WOLFSSL_API int wc_InitSha512(wc_Sha512* sha512) +{ + return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID); +} + +WOLFSSL_API int wc_Sha512Update(wc_Sha512* sha512, const unsigned char* data, + unsigned int len) +{ + if (sha512 == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + return _wc_Hash_Grow(&sha512->msg, &sha512->used, &sha512->len, + data, (int)len, sha512->heap); +} + +WOLFSSL_API int wc_Sha512Final(wc_Sha512* sha512, unsigned char* hash) +{ + if (sha512 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Final(&sha512->msg, &sha512->used, &sha512->len, + sha512->heap, hash, + MXC_TPU_HASH_SHA512); +} + +WOLFSSL_API int wc_Sha512GetHash(wc_Sha512* sha512, unsigned char* hash) +{ + if (sha512 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_GetHash((const unsigned char*)sha512->msg, + sha512->used, hash, + MXC_TPU_HASH_SHA512); +} + +WOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + return wc_MXC_TPU_SHA_Copy(src, dst, sizeof(wc_Sha512), + &dst->msg, &dst->used, &dst->len, + dst->heap, src->heap); +} + +WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha512) +{ + if (sha512 == NULL) { + return; + } + wc_MXC_TPU_SHA_FreeCtx(sha512, sizeof(wc_Sha512), &sha512->msg, + &sha512->used, &sha512->len, + sha512->heap); +} + +#endif /* WOLFSSL_SHA512 */ + +#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */ /* Non-callback path: provide the wc_Sha* API functions directly */ #if !defined(NO_SHA) @@ -1368,6 +2089,8 @@ WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha512) } #endif /* WOLFSSL_SHA512 */ + +#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */ #endif /* !MAX3266X_SHA_CB */ #endif /* MAX3266X_SHA || MAX3266X_SHA_CB */ diff --git a/wolfssl/wolfcrypt/port/maxim/max3266x.h b/wolfssl/wolfcrypt/port/maxim/max3266x.h index 7f357d6b95..67c5c2fe39 100644 --- a/wolfssl/wolfcrypt/port/maxim/max3266x.h +++ b/wolfssl/wolfcrypt/port/maxim/max3266x.h @@ -62,6 +62,12 @@ #ifndef WOLF_CRYPTO_CB_COPY #define WOLF_CRYPTO_CB_COPY #endif + /* One-shot mode buffers the whole message, so Free is needed too */ + #ifdef WOLFSSL_MAX3266X_SHA_ONESHOT + #ifndef WOLF_CRYPTO_CB_FREE + #define WOLF_CRYPTO_CB_FREE + #endif + #endif #endif /* Crypto HW can be used in parallel on this device */ @@ -255,6 +261,108 @@ #endif #endif /* WOLFSSL_SHA512 */ +#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT + + /* Use HASH_KEEP to accumulate message data for one-shot TPU hardware */ + #ifndef WOLFSSL_HASH_KEEP + #define WOLFSSL_HASH_KEEP + #endif + + #if !defined(NO_SHA) + /* Define the SHA digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA1[20] = { + 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, + 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, + 0xaf, 0xd8, 0x07, 0x09}; + #endif /* NO_SHA */ + + #if defined(WOLFSSL_SHA224) + /* Define the SHA-224 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA224[28] = { + 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, + 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4, + 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a, + 0xc5, 0xb3, 0xe4, 0x2f}; + #endif /* WOLFSSL_SHA224 */ + + #if !defined(NO_SHA256) + /* Define the SHA-256 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA256[32] = { + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, + 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, + 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, + 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; + #endif /* NO_SHA256 */ + + #if defined(WOLFSSL_SHA384) + /* Define the SHA-384 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA384[48] = { + 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, + 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, + 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, + 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, + 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, + 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b}; + #endif /* WOLFSSL_SHA384 */ + + #if defined(WOLFSSL_SHA512) + /* Define the SHA-512 digest for an empty string */ + /* as a constant byte array */ + static const unsigned char MXC_EMPTY_DIGEST_SHA512[64] = { + 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, + 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, + 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, + 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, + 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, + 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, + 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, + 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e}; + #endif /* WOLFSSL_SHA512 */ + + + /* Check for empty message and provide pre-computed digest if so */ + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_GetDigest(const unsigned char* msg, + unsigned int msgSz, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo); + /* Compute hash from accumulated message using TPU hardware */ + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_GetHash(const unsigned char* msg, + unsigned int msgSz, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo); + /* Free HASH_KEEP message buffer and reset fields */ + WOLFSSL_LOCAL void wc_MXC_TPU_SHA_Free(unsigned char** msg, + unsigned int* used, + unsigned int* len, + void* heap); + /* Free HASH_KEEP message buffer and zero the full SHA context */ + WOLFSSL_LOCAL void wc_MXC_TPU_SHA_FreeCtx(void* ctx, + unsigned int ctxSz, + unsigned char** msg, + unsigned int* used, + unsigned int* len, + void* heap); + /* Copy SHA context and deep copy HASH_KEEP message buffer */ + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Copy(void* src, void* dst, + unsigned int ctxSz, + unsigned char** dstMsg, + unsigned int* dstUsed, + unsigned int* dstLen, + void* dstHeap, void* srcHeap); + /* Compute hash, free message buffer, and reset fields */ + WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Final(unsigned char** msg, + unsigned int* used, + unsigned int* len, + void* heap, + unsigned char* digest, + MXC_TPU_HASH_TYPE algo); + +#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */ + /* Number of HASH_DIGEST register words for each algorithm's state */ #define MXC_SHA1_STATE_WORDS 5 /* 160-bit state */ #define MXC_SHA224_STATE_WORDS 8 /* 256-bit internal state */ @@ -300,6 +408,8 @@ MXC_TPU_HASH_TYPE algo, unsigned char* hash); +#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */ + #endif /* defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) */ #if defined(MAX3266X_MATH)