diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 781af62a3..533380954 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -1720,7 +1720,7 @@ int wc_CryptoCb_Sha384Hash(wc_Sha384* sha384, const byte* in, #ifdef WOLFSSL_SHA512 int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, - word32 inSz, byte* digest) + word32 inSz, byte* digest, size_t digestSz) { int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); CryptoCb* dev; @@ -1738,16 +1738,43 @@ int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, } if (dev && dev->cb) { + byte localHash[WC_SHA512_DIGEST_SIZE]; wc_CryptoInfo cryptoInfo; XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); cryptoInfo.algo_type = WC_ALGO_TYPE_HASH; - cryptoInfo.hash.type = WC_HASH_TYPE_SHA512; cryptoInfo.hash.sha512 = sha512; cryptoInfo.hash.in = in; cryptoInfo.hash.inSz = inSz; cryptoInfo.hash.digest = digest; + /* try the specific family callbacks first */ +#if !defined(WOLFSSL_NOSHA512_224) + if (digest != NULL && digestSz == WC_SHA512_224_DIGEST_SIZE) { + cryptoInfo.hash.type = WC_HASH_TYPE_SHA512_224; + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + ret = wc_CryptoCb_TranslateErrorCode(ret); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + } +#endif +#if !defined(WOLFSSL_NOSHA512_256) + if (digest != NULL && digestSz == WC_SHA512_256_DIGEST_SIZE) { + cryptoInfo.hash.type = WC_HASH_TYPE_SHA512_256; + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + ret = wc_CryptoCb_TranslateErrorCode(ret); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + } +#endif + cryptoInfo.hash.type = WC_HASH_TYPE_SHA512; + /* use local buffer if not full size */ + if (digest != NULL && digestSz != WC_SHA512_DIGEST_SIZE) + cryptoInfo.hash.digest = localHash; ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + ret = wc_CryptoCb_TranslateErrorCode(ret); + if (ret == 0 && digest != NULL && digestSz != WC_SHA512_DIGEST_SIZE) + XMEMCPY(digest, localHash, digestSz); + return ret; } return wc_CryptoCb_TranslateErrorCode(ret); diff --git a/wolfcrypt/src/port/arm/armv8-sha512.c b/wolfcrypt/src/port/arm/armv8-sha512.c index 57020f01c..1e88016da 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512.c +++ b/wolfcrypt/src/port/arm/armv8-sha512.c @@ -543,7 +543,7 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) if (sha512->devId != INVALID_DEVID) #endif { - int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL); + int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL, 0); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ @@ -675,10 +675,8 @@ static int Sha512_Family_Final(wc_Sha512* sha512, byte* hash, if (sha512->devId != INVALID_DEVID) #endif { - byte localHash[WC_SHA512_DIGEST_SIZE]; - ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, localHash); + ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, hash, digestSz); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { - XMEMCPY(hash, localHash, digestSz); return ret; } /* fall-through when unavailable */ diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 0454ab62f..9cdb2ae70 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -1192,7 +1192,7 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) if (sha512->devId != INVALID_DEVID) #endif { - int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL); + int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL, 0); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ @@ -1429,10 +1429,8 @@ static int Sha512_Family_Final(wc_Sha512* sha512, byte* hash, size_t digestSz, if (sha512->devId != INVALID_DEVID) #endif { - byte localHash[WC_SHA512_DIGEST_SIZE]; - ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, localHash); + ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, hash, digestSz); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { - XMEMCPY(hash, localHash, digestSz); return ret; } /* fall-through when unavailable */ diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 35b6f715c..05543eadc 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -676,7 +676,7 @@ WOLFSSL_LOCAL int wc_CryptoCb_Sha384Hash(wc_Sha384* sha384, const byte* in, #endif #ifdef WOLFSSL_SHA512 WOLFSSL_LOCAL int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, - word32 inSz, byte* digest); + word32 inSz, byte* digest, size_t digestSz); #endif #ifdef WOLFSSL_SHA3