diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index c3af7ed608..8215e2fe31 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -50,6 +50,15 @@ Crypto Callback Build Options: * Algorithm-specific callback options: * NO_SHA2_CRYPTO_CB: Disable crypto callbacks for SHA-384 default: off * and SHA-512 operations. + * WOLF_CRYPTO_CB_NO_SHA512_FALLBACK: default: off + * Do not fall back to the generic SHA-512 + * callback for SHA-384, SHA-512/224 and + * SHA-512/256 when no variant-specific + * callback is registered. Required for + * backends whose hash context has no + * digest[] state field or that keep the + * hash state on the device (auto-enabled + * for Renesas FSPSM). * WOLF_CRYPTO_CB_ONLY_ECC: Use only callbacks for ECC default: off * WOLF_CRYPTO_CB_ONLY_RSA: Use only callbacks for RSA default: off * WOLF_CRYPTO_CB_ONLY_SHA256: Use only callbacks for SHA-256 default: off @@ -2061,7 +2070,9 @@ int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, } if (dev && dev->cb) { + #ifndef WOLF_CRYPTO_CB_NO_SHA512_FALLBACK byte localHash[WC_SHA512_DIGEST_SIZE]; + #endif wc_CryptoInfo cryptoInfo; XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); cryptoInfo.algo_type = WC_ALGO_TYPE_HASH; @@ -2078,6 +2089,9 @@ int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, ret = wc_CryptoCb_TranslateErrorCode(ret); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; + #ifdef WOLF_CRYPTO_CB_NO_SHA512_FALLBACK + return ret; + #endif } #endif #if !defined(WOLFSSL_NOSHA512_256) @@ -2087,16 +2101,48 @@ int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, ret = wc_CryptoCb_TranslateErrorCode(ret); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; + #ifdef WOLF_CRYPTO_CB_NO_SHA512_FALLBACK + return ret; + #endif } #endif cryptoInfo.hash.type = WC_HASH_TYPE_SHA512; + #ifndef WOLF_CRYPTO_CB_NO_SHA512_FALLBACK /* use local buffer if not full size */ if (digest != NULL && digestSz != WC_SHA512_DIGEST_SIZE) cryptoInfo.hash.digest = localHash; + #endif ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); ret = wc_CryptoCb_TranslateErrorCode(ret); - if (ret == 0 && digest != NULL && digestSz != WC_SHA512_DIGEST_SIZE) + #ifndef WOLF_CRYPTO_CB_NO_SHA512_FALLBACK + if (ret == 0 && digest != NULL && digestSz != WC_SHA512_DIGEST_SIZE) { XMEMCPY(digest, localHash, digestSz); +#if !defined(WOLFSSL_NOSHA512_224) + if (digestSz == WC_SHA512_224_DIGEST_SIZE) { + sha512->digest[0] = W64LIT(0x8c3d37c819544da2); + sha512->digest[1] = W64LIT(0x73e1996689dcd4d6); + sha512->digest[2] = W64LIT(0x1dfab7ae32ff9c82); + sha512->digest[3] = W64LIT(0x679dd514582f9fcf); + sha512->digest[4] = W64LIT(0x0f6d2b697bd44da8); + sha512->digest[5] = W64LIT(0x77e36f7304c48942); + sha512->digest[6] = W64LIT(0x3f9d85a86a1d36c8); + sha512->digest[7] = W64LIT(0x1112e6ad91d692a1); + } +#endif +#if !defined(WOLFSSL_NOSHA512_256) + if (digestSz == WC_SHA512_256_DIGEST_SIZE) { + sha512->digest[0] = W64LIT(0x22312194fc2bf72c); + sha512->digest[1] = W64LIT(0x9f555fa3c84c64c2); + sha512->digest[2] = W64LIT(0x2393b86b6f53b151); + sha512->digest[3] = W64LIT(0x963877195940eabd); + sha512->digest[4] = W64LIT(0x96283ee2a88effe3); + sha512->digest[5] = W64LIT(0xbe5e1e2553863992); + sha512->digest[6] = W64LIT(0x2b0199fc2c85b8aa); + sha512->digest[7] = W64LIT(0x0eb72ddc81c52ca2); + } +#endif + } + #endif /* !WOLF_CRYPTO_CB_NO_SHA512_FALLBACK */ return ret; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index f3fc88c8a1..45ec4c4b15 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -74443,6 +74443,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) #ifdef WOLFSSL_SHA512 if (ret == 0) ret = sha512_test(); +#if !defined(WOLFSSL_NOSHA512_224) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) + /* exercises the SHA-512/224 fallback to the generic SHA-512 callback, + * including object reuse after Final */ + if (ret == 0) + ret = sha512_224_test(); +#endif +#if !defined(WOLFSSL_NOSHA512_256) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) + if (ret == 0) + ret = sha512_256_test(); +#endif #ifdef WOLFSSL_SHA3 if (ret == 0) ret = sha3_test(); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 0fb49e9351..3247bb9298 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1189,6 +1189,19 @@ /* settings in user_settings.h */ #endif +#if defined(WOLFSSL_RENESAS_RSIP) && !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) + /* The Renesas FSPSM hash context has no software digest[] state field and + * the device computes each SHA-512 variant (SHA-384, SHA-512/224, + * SHA-512/256) natively. Disable the cryptocb fallback that reuses the + * generic SHA-512 callback for the variants: it relies on a digest[] IV in + * the context (absent here, so it would not compile) and assumes the + * backend exposes its hash state, which a device that keeps state + * internally does not. */ + #ifndef WOLF_CRYPTO_CB_NO_SHA512_FALLBACK + #define WOLF_CRYPTO_CB_NO_SHA512_FALLBACK + #endif +#endif + #if defined(WOLFSSL_LWIP_NATIVE) || \ defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */ #undef WOLFSSL_USER_IO