cryptocb: sha512_family: try specific digest length hashtype first

If the cryptocb provider supports specific SHA512/224 and SHA512/256
hashtype, this commit allows to:

1. avoid a copy
2. do not touch the output buffer outside of the cryptocb handler

2 might be important for cryptocb provider that needs special handling
of memory buffer (DMA, memory mapping).
This commit is contained in:
Marco Oliverio
2025-10-06 11:06:02 +02:00
parent 99c983d44f
commit 9cbc3f97e5
4 changed files with 34 additions and 11 deletions

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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