From 40a6a04d231791bc2ee3c5121ae6babe4bfa3760 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 2 Jun 2026 09:05:04 +0200 Subject: [PATCH 1/4] fix: restore SHA-512 variant IV after generic fallback After the SHA-512/224 and /256 fallback to the generic SHA-512 callback, restore the variant initial state so the object is reset for reuse, and exercise the path in cryptocb_test. --- wolfcrypt/src/cryptocb.c | 48 +++++++++++++++++++++++++++++++++++- wolfcrypt/test/test.c | 12 +++++++++ wolfssl/wolfcrypt/settings.h | 13 ++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) 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 From 76962339c4f3f1e6af608d2d0b9612a431106083 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 2 Jun 2026 15:28:32 +0200 Subject: [PATCH 2/4] cryptocb: fallback to sha512 if no sha384 cryptocb handler --- wolfcrypt/src/cryptocb.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 8215e2fe31..c2cb707f3f 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -2024,16 +2024,52 @@ int wc_CryptoCb_Sha384Hash(wc_Sha384* sha384, const byte* in, } if (dev && dev->cb) { + #if defined(WOLFSSL_SHA512) && !defined(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; - cryptoInfo.hash.type = WC_HASH_TYPE_SHA384; - cryptoInfo.hash.sha384 = sha384; cryptoInfo.hash.in = in; cryptoInfo.hash.inSz = inSz; + + /* try the SHA-384 callback first */ + cryptoInfo.hash.type = WC_HASH_TYPE_SHA384; + cryptoInfo.hash.sha384 = sha384; cryptoInfo.hash.digest = digest; + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + ret = wc_CryptoCb_TranslateErrorCode(ret); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + #if defined(WOLFSSL_SHA512) && !defined(WOLF_CRYPTO_CB_NO_SHA512_FALLBACK) + /* fall back to the SHA-512 core: SHA-384 is the SHA-512 core with a + * different IV (in the caller-supplied state) and a 48-byte + * truncation done here */ + cryptoInfo.hash.type = WC_HASH_TYPE_SHA512; + cryptoInfo.hash.sha512 = (wc_Sha512*)sha384; + /* use local buffer for the final digest so we can truncate */ + if (digest != NULL) + cryptoInfo.hash.digest = localHash; ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + ret = wc_CryptoCb_TranslateErrorCode(ret); + if (ret == 0 && digest != NULL) { + XMEMCPY(digest, localHash, WC_SHA384_DIGEST_SIZE); + /* the SHA-512 callback left the SHA-512 IV in the state; write + * the SHA-384 IV back so the struct is ready for reuse */ + if (sha384 != NULL) { + sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8); + sha384->digest[1] = W64LIT(0x629a292a367cd507); + sha384->digest[2] = W64LIT(0x9159015a3070dd17); + sha384->digest[3] = W64LIT(0x152fecd8f70e5939); + sha384->digest[4] = W64LIT(0x67332667ffc00b31); + sha384->digest[5] = W64LIT(0x8eb44a8768581511); + sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7); + sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4); + } + } + return ret; + #endif /* WOLFSSL_SHA512 && !WOLF_CRYPTO_CB_NO_SHA512_FALLBACK */ } return wc_CryptoCb_TranslateErrorCode(ret); From 5744df1c77bdfda62a81c63236e2d20d75d2e643 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Wed, 3 Jun 2026 15:57:23 +0200 Subject: [PATCH 3/4] test: add sha512 variants by sha512 general fallback test --- tests/api/test_sha512.c | 184 ++++++++++++++++++++++++++++++++++++++++ tests/api/test_sha512.h | 4 +- 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/tests/api/test_sha512.c b/tests/api/test_sha512.c index 419fb60b31..85ed2ab328 100644 --- a/tests/api/test_sha512.c +++ b/tests/api/test_sha512.c @@ -874,3 +874,187 @@ int test_wc_Sha384_Flags(void) return EXPECT_RESULT(); } +/* The SHA-512/224 and SHA-512/256 variants are only available under these + * build conditions. */ +#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) + #define TEST_WC_SHA512_224_FALLBACK +#endif +#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) + #define TEST_WC_SHA512_256_FALLBACK +#endif + +#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_SHA512) && \ + !defined(NO_SHA2_CRYPTO_CB) && \ + ((!defined(WOLF_CRYPTO_CB_NO_SHA512_FALLBACK) && \ + (defined(WOLFSSL_SHA384) || defined(TEST_WC_SHA512_224_FALLBACK) || \ + defined(TEST_WC_SHA512_256_FALLBACK))) || \ + defined(WOLF_CRYPTO_CB_ONLY_SHA512)) + +#include + +#define TEST_CRYPTOCB_SHA512_DEVID 2 + +typedef struct { + int variantSeen; /* SHA-384 / SHA-512-224 / SHA-512-256 callback declined */ + int sha512Seen; /* generic SHA-512 callback the fallback lands on */ +#ifdef WOLF_CRYPTO_CB_FREE + int freeSeen; /* SHA-512-family free callbacks the CB-only free routes to */ +#endif +} Sha512DevCbCtx; + +/* Shared SHA-512 crypto-callback test device. For HASH ops it declines every + * SHA-512 variant callback so the cryptocb dispatcher falls back to the generic + * SHA-512 callback; that callback fills a recognisable digest and deliberately + * leaves the SHA-512 IV in the caller's state, forcing the dispatcher to reset + * the state back to the variant IV. */ +static int sha512_dev_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + Sha512DevCbCtx* cbCtx = (Sha512DevCbCtx*)ctx; + int i; + + (void)devIdArg; + + if (info == NULL || cbCtx == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLF_CRYPTO_CB_FREE + if (info->algo_type == WC_ALGO_TYPE_FREE) { + /* Count SHA-512-family frees so the test can confirm the + * CB-only free path reaches the callback instead of only zeroing the + * struct. Decline so the caller still performs its standard cleanup. */ + if (info->free.algo == WC_ALGO_TYPE_HASH && + (info->free.type == WC_HASH_TYPE_SHA512 || + info->free.type == WC_HASH_TYPE_SHA384)) + cbCtx->freeSeen++; + return CRYPTOCB_UNAVAILABLE; + } +#endif + + if (info->algo_type != WC_ALGO_TYPE_HASH) + return CRYPTOCB_UNAVAILABLE; + + switch (info->hash.type) { + case WC_HASH_TYPE_SHA384: + case WC_HASH_TYPE_SHA512_224: + case WC_HASH_TYPE_SHA512_256: + cbCtx->variantSeen++; + return CRYPTOCB_UNAVAILABLE; + + case WC_HASH_TYPE_SHA512: + cbCtx->sha512Seen++; + if (info->hash.digest != NULL) { + for (i = 0; i < WC_SHA512_DIGEST_SIZE; i++) + info->hash.digest[i] = (byte)(0x80 + i); + } + #ifndef WOLF_CRYPTO_CB_NO_SHA512_FALLBACK + /* leave the SHA-512 IV in the caller's state to force the + * dispatcher's variant IV reset; backends that drop the digest[] + * field disable the fallback, so this only runs when it exists */ + if (info->hash.sha512 != NULL) { + for (i = 0; i < (int)(sizeof(info->hash.sha512->digest) / + sizeof(info->hash.sha512->digest[0])); i++) { + info->hash.sha512->digest[i] = W64LIT(0xdeadbeefcafebabe); + } + } + #endif + return 0; + + default: + return CRYPTOCB_UNAVAILABLE; + } +} + +#endif + +int test_wc_sha512_cryptocb_fallback(void) +{ + EXPECT_DECLS; +#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_SHA512) && \ + !defined(NO_SHA2_CRYPTO_CB) && \ + !defined(WOLF_CRYPTO_CB_NO_SHA512_FALLBACK) && \ + (defined(WOLFSSL_SHA384) || defined(TEST_WC_SHA512_224_FALLBACK) || \ + defined(TEST_WC_SHA512_256_FALLBACK)) + typedef struct { + const char* name; + int (*initFn)(wc_Sha512* sha, void* heap, int devId); + int (*finalFn)(wc_Sha512* sha, byte* hash); + word32 digestSz; + } Sha512FallbackCase; + static const Sha512FallbackCase sha512FallbackCases[] = { +#ifdef WOLFSSL_SHA384 + { "SHA-384", wc_InitSha384_ex, wc_Sha384Final, WC_SHA384_DIGEST_SIZE }, +#endif +#ifdef TEST_WC_SHA512_224_FALLBACK + { "SHA-512/224", wc_InitSha512_224_ex, wc_Sha512_224Final, + WC_SHA512_224_DIGEST_SIZE }, +#endif +#ifdef TEST_WC_SHA512_256_FALLBACK + { "SHA-512/256", wc_InitSha512_256_ex, wc_Sha512_256Final, + WC_SHA512_256_DIGEST_SIZE }, +#endif + }; + wc_Sha512 sha; + wc_Sha512 refSha; + Sha512DevCbCtx cbCtx; + byte hash[WC_SHA512_DIGEST_SIZE]; + byte devCtxMarker; + const Sha512FallbackCase* tc; + size_t c; + word32 i; + + for (c = 0; + c < sizeof(sha512FallbackCases) / sizeof(sha512FallbackCases[0]); + c++) { + tc = &sha512FallbackCases[c]; + devCtxMarker = 0; + + XMEMSET(&sha, 0, sizeof(sha)); + sha.devId = INVALID_DEVID; + sha.devCtx = NULL; + XMEMSET(&refSha, 0, sizeof(refSha)); + XMEMSET(&cbCtx, 0, sizeof(cbCtx)); + XMEMSET(hash, 0, sizeof(hash)); + + /* Reference struct capturing the freshly-initialised variant IV state, + * against which we verify the test struct after Final. */ + ExpectIntEQ(tc->initFn(&refSha, HEAP_HINT, INVALID_DEVID), 0); + + ExpectIntEQ(wc_CryptoCb_RegisterDevice( + TEST_CRYPTOCB_SHA512_DEVID, sha512_dev_cb, + &cbCtx), 0); + + ExpectIntEQ(tc->initFn(&sha, HEAP_HINT, + TEST_CRYPTOCB_SHA512_DEVID), 0); + sha.devCtx = &devCtxMarker; + + ExpectIntEQ(tc->finalFn(&sha, hash), 0); + + /* the variant callback is declined, forcing the generic SHA-512 + * fallback */ + ExpectIntEQ(cbCtx.variantSeen, 1); + ExpectIntEQ(cbCtx.sha512Seen, 1); + + /* devId and devCtx must be preserved across the SHA-512 fallback. */ + ExpectIntEQ(sha.devId, TEST_CRYPTOCB_SHA512_DEVID); + ExpectPtrEq(sha.devCtx, &devCtxMarker); + + /* the digest is the generic SHA-512 output truncated to the variant + * digest size */ + for (i = 0; i < tc->digestSz; i++) + ExpectIntEQ(hash[i], (byte)(0x80 + i)); + + /* the SHA-512 fallback leaves the SHA-512 IV in the state buffer; the + * fallback must reset it back to the variant IV so the struct is ready + * to hash a new message */ + ExpectIntEQ(XMEMCMP(sha.digest, refSha.digest, sizeof(sha.digest)), 0); + + wc_Sha512Free(&sha); + wc_Sha512Free(&refSha); + wc_CryptoCb_UnRegisterDevice(TEST_CRYPTOCB_SHA512_DEVID); + } +#endif + return EXPECT_RESULT(); +} + diff --git a/tests/api/test_sha512.h b/tests/api/test_sha512.h index 48882c4daa..4d584b824a 100644 --- a/tests/api/test_sha512.h +++ b/tests/api/test_sha512.h @@ -66,6 +66,7 @@ int test_wc_Sha384_other(void); int test_wc_Sha384Copy(void); int test_wc_Sha384GetHash(void); int test_wc_Sha384_Flags(void); +int test_wc_sha512_cryptocb_fallback(void); #define TEST_SHA512_DECLS \ TEST_DECL_GROUP("sha512", test_wc_InitSha512), \ @@ -77,7 +78,8 @@ int test_wc_Sha384_Flags(void); TEST_DECL_GROUP("sha512", test_wc_Sha512Copy), \ TEST_DECL_GROUP("sha512", test_wc_Sha512GetHash), \ TEST_DECL_GROUP("sha512", test_wc_Sha512Transform), \ - TEST_DECL_GROUP("sha512", test_wc_Sha512_Flags) + TEST_DECL_GROUP("sha512", test_wc_Sha512_Flags), \ + TEST_DECL_GROUP("sha512", test_wc_sha512_cryptocb_fallback) #define TEST_SHA512_224_DECLS \ TEST_DECL_GROUP("sha512_224", test_wc_InitSha512_224), \ From 0314b3fed2dd0a4ce1324ddd985017605a2fd1de Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Wed, 20 May 2026 22:01:34 +0200 Subject: [PATCH 4/4] cryptocb: support WOLF_CRYPTO_CB_ONLY_SHA512 --- .github/workflows/cryptocb-only.yml | 16 +- .wolfssl_known_macro_extras | 2 + src/ssl_crypto.c | 9 +- tests/api.c | 6 +- tests/api/test_sha512.c | 97 +++++ tests/api/test_sha512.h | 6 +- tests/swdev/swdev.c | 194 ++++++++- tests/swdev/user_settings.h | 1 + wolfcrypt/src/cryptocb.c | 5 +- wolfcrypt/src/sha512.c | 586 ++++++++++++++++++++++++++++ wolfcrypt/test/test.c | 18 + wolfssl/openssl/sha.h | 12 + wolfssl/wolfcrypt/settings.h | 6 + wolfssl/wolfcrypt/sha512.h | 23 +- 14 files changed, 968 insertions(+), 13 deletions(-) diff --git a/.github/workflows/cryptocb-only.yml b/.github/workflows/cryptocb-only.yml index 63400f2f9a..5aedf4c873 100644 --- a/.github/workflows/cryptocb-only.yml +++ b/.github/workflows/cryptocb-only.yml @@ -33,6 +33,19 @@ jobs: # the software path via cryptocb. - name: SHA256 cppflags: -DWOLF_CRYPTO_CB_ONLY_SHA256 + # WOLF_CRYPTO_CB_ONLY_SHA512: strips software SHA-512 family (SHA-384, + # SHA-512/224, SHA-512/256, SHA-512); swdev handles every variant + # explicitly via cryptocb. + - name: SHA512 + cppflags: -DWOLF_CRYPTO_CB_ONLY_SHA512 + # Same as SHA512 but tells swdev to refuse the SHA-384 / SHA-512/224 / + # SHA-512/256 variant callbacks (WOLFSSL_SWDEV_SHA512_GENERAL_ONLY). That + # forces the cryptocb dispatcher's fallback-to-plain-SHA-512-with- + # truncation path. The SHA512 entry above instead has swdev handle + # every variant end-to-end, so the dispatcher fallback is otherwise + # uncovered. + - name: SHA512_via_general + cppflags: -DWOLF_CRYPTO_CB_ONLY_SHA512 -DWOLFSSL_SWDEV_SHA512_GENERAL_ONLY # WOLF_CRYPTO_CB_ONLY_AES: strips software AES; swdev provides the # software path via cryptocb. - name: AES @@ -51,7 +64,8 @@ jobs: - name: ALL cppflags: >- -DWOLF_CRYPTO_CB_ONLY_ECC -DWOLF_CRYPTO_CB_ONLY_RSA - -DWOLF_CRYPTO_CB_ONLY_SHA256 -DWOLF_CRYPTO_CB_ONLY_AES + -DWOLF_CRYPTO_CB_ONLY_SHA256 -DWOLF_CRYPTO_CB_ONLY_SHA512 + -DWOLF_CRYPTO_CB_ONLY_AES name: make check (${{ matrix.name }}) if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} runs-on: ubuntu-24.04 diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index fb34d7c6f2..d64831361e 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -966,6 +966,8 @@ WOLFSSL_XIL_MSG_NO_SLEEP WOLFSSL_ZEPHYR WOLF_ALLOW_BUILTIN WOLF_CRYPTO_CB_CMD +WOLF_CRYPTO_CB_NO_SHA512_FALLBACK +WOLF_CRYPTO_CB_ONLY_SHA512 WOLF_CRYPTO_DEV WOLF_NO_TRAILING_ENUM_COMMAS WindowsCE diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c index 3393f25fef..92ae36e582 100644 --- a/src/ssl_crypto.c +++ b/src/ssl_crypto.c @@ -611,7 +611,8 @@ int wolfSSL_SHA512_Final(byte* output, WOLFSSL_SHA512_CTX* sha512) #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ - !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */ + !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */ && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512) /* no wc_Sha512Transform in CB-only */ /* Apply SHA-512 transformation to the data. * * @param [in, out] sha512 SHA512 context object. @@ -687,7 +688,8 @@ int wolfSSL_SHA512_224_Final(byte* output, WOLFSSL_SHA512_224_CTX* sha512) } #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512) /* no wc_Sha512_224Transform in CB-only */ /* Apply SHA-512-224 transformation to the data. * * @param [in, out] sha512 SHA512 context object. @@ -765,7 +767,8 @@ int wolfSSL_SHA512_256_Final(byte* output, WOLFSSL_SHA512_256_CTX* sha512) } #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512) /* no wc_Sha512_256Transform in CB-only */ /* Apply SHA-512-256 transformation to the data. * * @param [in, out] sha512 SHA512 context object. diff --git a/tests/api.c b/tests/api.c index a2873fd747..4cf30afcff 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27527,7 +27527,8 @@ static int test_SSL_CIPHER_get_xxx(void) #if defined(WOLF_CRYPTO_CB) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \ (!defined(WOLF_CRYPTO_CB_ONLY_SHA256) && !defined(WOLF_CRYPTO_CB_ONLY_AES) && \ - !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA)) + !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512)) static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer, int* keyFormat) @@ -28531,7 +28532,8 @@ static int test_wc_CryptoCb(void) EXPECT_DECLS; #if defined(WOLF_CRYPTO_CB) && \ (!defined(WOLF_CRYPTO_CB_ONLY_SHA256) && !defined(WOLF_CRYPTO_CB_ONLY_AES) && \ - !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA)) + !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512)) /* TODO: Add crypto callback API tests */ #ifdef HAVE_IO_TESTS_DEPENDENCIES diff --git a/tests/api/test_sha512.c b/tests/api/test_sha512.c index 85ed2ab328..eb5a31c8f5 100644 --- a/tests/api/test_sha512.c +++ b/tests/api/test_sha512.c @@ -1058,3 +1058,100 @@ int test_wc_sha512_cryptocb_fallback(void) return EXPECT_RESULT(); } +/* Regression test for the no-_ex SHA-512/224 and SHA-512/256 initializers under + * WOLF_CRYPTO_CB_ONLY_SHA512. With the software path stripped, they must adopt + * the registered default CryptoCb device just like wc_InitSha512() and + * wc_InitSha384(); otherwise devId stays INVALID_DEVID and the public streaming + * API returns NO_VALID_DEVID even though a default device is registered. */ +int test_wc_sha512_variants_default_devid(void) +{ + EXPECT_DECLS; +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_ONLY_SHA512) && \ + defined(WOLFSSL_SHA512) && !defined(NO_SHA2_CRYPTO_CB) && \ + !defined(WC_NO_DEFAULT_DEVID) && \ + (!defined(WOLFSSL_NOSHA512_224) || !defined(WOLFSSL_NOSHA512_256)) + typedef struct { + const char* name; + int (*initFn)(wc_Sha512* sha); + } Sha512VariantCase; + static const Sha512VariantCase cases[] = { +#ifndef WOLFSSL_NOSHA512_224 + { "SHA-512/224", wc_InitSha512_224 }, +#endif +#ifndef WOLFSSL_NOSHA512_256 + { "SHA-512/256", wc_InitSha512_256 }, +#endif + }; + Sha512DevCbCtx cbCtx; + int defaultDevId; + wc_Sha512 sha; + const Sha512VariantCase* tc; + size_t c; + + XMEMSET(&cbCtx, 0, sizeof(cbCtx)); + + ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_CRYPTOCB_SHA512_DEVID, + sha512_dev_cb, &cbCtx), 0); + defaultDevId = wc_CryptoCb_DefaultDevID(); + ExpectIntNE(defaultDevId, INVALID_DEVID); + + for (c = 0; c < sizeof(cases) / sizeof(cases[0]); c++) { + tc = &cases[c]; + + XMEMSET(&sha, 0, sizeof(sha)); + sha.devId = INVALID_DEVID; + + /* the no-_ex initializer must adopt the default device rather than + * leaving devId INVALID_DEVID (which the stripped software path would + * surface as NO_VALID_DEVID from the public streaming API) */ + ExpectIntEQ(tc->initFn(&sha), 0); + ExpectIntEQ(sha.devId, defaultDevId); + + wc_Sha512Free(&sha); + } + + wc_CryptoCb_UnRegisterDevice(TEST_CRYPTOCB_SHA512_DEVID); +#endif + return EXPECT_RESULT(); +} + +/* WOLF_CRYPTO_CB_FREE under WOLF_CRYPTO_CB_ONLY_SHA512: the + * stripped-software wc_Sha512Free()/wc_Sha384Free() must route through the + * crypto callback. */ +int test_wc_sha512_cryptocb_free(void) +{ + EXPECT_DECLS; +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE) && \ + defined(WOLF_CRYPTO_CB_ONLY_SHA512) && defined(WOLFSSL_SHA512) + Sha512DevCbCtx cbCtx; + wc_Sha512 sha512; +#ifdef WOLFSSL_SHA384 + wc_Sha384 sha384; +#endif + + XMEMSET(&cbCtx, 0, sizeof(cbCtx)); + + ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_CRYPTOCB_SHA512_DEVID, + sha512_dev_cb, &cbCtx), 0); + + XMEMSET(&sha512, 0, sizeof(sha512)); + ExpectIntEQ(wc_InitSha512_ex(&sha512, HEAP_HINT, + TEST_CRYPTOCB_SHA512_DEVID), 0); + wc_Sha512Free(&sha512); + /* the free must reach the device callback */ + ExpectIntEQ(cbCtx.freeSeen, 1); + +#ifdef WOLFSSL_SHA384 + cbCtx.freeSeen = 0; + XMEMSET(&sha384, 0, sizeof(sha384)); + ExpectIntEQ(wc_InitSha384_ex(&sha384, HEAP_HINT, + TEST_CRYPTOCB_SHA512_DEVID), 0); + wc_Sha384Free(&sha384); + ExpectIntEQ(cbCtx.freeSeen, 1); +#endif + + wc_CryptoCb_UnRegisterDevice(TEST_CRYPTOCB_SHA512_DEVID); +#endif + return EXPECT_RESULT(); +} + diff --git a/tests/api/test_sha512.h b/tests/api/test_sha512.h index 4d584b824a..3347424455 100644 --- a/tests/api/test_sha512.h +++ b/tests/api/test_sha512.h @@ -67,6 +67,8 @@ int test_wc_Sha384Copy(void); int test_wc_Sha384GetHash(void); int test_wc_Sha384_Flags(void); int test_wc_sha512_cryptocb_fallback(void); +int test_wc_sha512_variants_default_devid(void); +int test_wc_sha512_cryptocb_free(void); #define TEST_SHA512_DECLS \ TEST_DECL_GROUP("sha512", test_wc_InitSha512), \ @@ -79,7 +81,9 @@ int test_wc_sha512_cryptocb_fallback(void); TEST_DECL_GROUP("sha512", test_wc_Sha512GetHash), \ TEST_DECL_GROUP("sha512", test_wc_Sha512Transform), \ TEST_DECL_GROUP("sha512", test_wc_Sha512_Flags), \ - TEST_DECL_GROUP("sha512", test_wc_sha512_cryptocb_fallback) + TEST_DECL_GROUP("sha512", test_wc_sha512_cryptocb_fallback), \ + TEST_DECL_GROUP("sha512", test_wc_sha512_variants_default_devid), \ + TEST_DECL_GROUP("sha512", test_wc_sha512_cryptocb_free) #define TEST_SHA512_224_DECLS \ TEST_DECL_GROUP("sha512_224", test_wc_InitSha512_224), \ diff --git a/tests/swdev/swdev.c b/tests/swdev/swdev.c index db06f20409..24271eda1e 100644 --- a/tests/swdev/swdev.c +++ b/tests/swdev/swdev.c @@ -249,6 +249,177 @@ static int swdev_sha224(wc_CryptoInfo* info) #endif /* WOLFSSL_SHA224 */ #endif /* !NO_SHA256 */ +#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) +/* Copy hash state between caller's wc_Sha512 and swdev's shadow, leaving + * admin fields (heap, devId, devCtx, W, async, HW ctx) per-side. The same + * helper works for SHA-384, SHA-512/224, SHA-512/256 since they all typedef + * to wc_Sha512. */ +static void swdev_sha512_copy_state(wc_Sha512* dst, const wc_Sha512* src) +{ + XMEMCPY(dst->digest, src->digest, sizeof(dst->digest)); + XMEMCPY(dst->buffer, src->buffer, sizeof(dst->buffer)); + dst->buffLen = src->buffLen; + dst->loLen = src->loLen; + dst->hiLen = src->hiLen; +#ifdef WC_C_DYNAMIC_FALLBACK + dst->sha_method = src->sha_method; +#endif +#ifdef WOLFSSL_HASH_FLAGS + dst->flags = src->flags; +#endif +#if defined(WOLFSSL_SHA512_HASHTYPE) + dst->hashType = src->hashType; +#endif +} +#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */ + +#ifdef WOLFSSL_SHA512 +static int swdev_sha512(wc_CryptoInfo* info) +{ + wc_Sha512* sha512 = info->hash.sha512; + wc_Sha512 shadow; + int ret; + + if (sha512 == NULL) + return BAD_FUNC_ARG; + + ret = wc_InitSha512(&shadow); + if (ret != 0) + return ret; + + swdev_sha512_copy_state(&shadow, sha512); + + if (info->hash.in != NULL) { + ret = wc_Sha512Update(&shadow, info->hash.in, info->hash.inSz); + if (ret != 0) + goto out; + } + + if (info->hash.digest != NULL) { + ret = wc_Sha512Final(&shadow, info->hash.digest); + if (ret != 0) + goto out; + } + + swdev_sha512_copy_state(sha512, &shadow); + +out: + wc_Sha512Free(&shadow); + return ret; +} + +#if !defined(WOLFSSL_NOSHA512_224) && \ + !defined(WOLFSSL_SWDEV_SHA512_GENERAL_ONLY) +static int swdev_sha512_224(wc_CryptoInfo* info) +{ + wc_Sha512 shadow; + wc_Sha512* sha = info->hash.sha512; + int ret; + + if (sha == NULL) + return BAD_FUNC_ARG; + + ret = wc_InitSha512_224(&shadow); + if (ret != 0) + return ret; + + swdev_sha512_copy_state(&shadow, sha); + + if (info->hash.in != NULL) { + ret = wc_Sha512_224Update(&shadow, info->hash.in, info->hash.inSz); + if (ret != 0) + goto out; + } + if (info->hash.digest != NULL) { + ret = wc_Sha512_224Final(&shadow, info->hash.digest); + if (ret != 0) + goto out; + } + + swdev_sha512_copy_state(sha, &shadow); + +out: + wc_Sha512_224Free(&shadow); + return ret; +} +#endif + +#if !defined(WOLFSSL_NOSHA512_256) && \ + !defined(WOLFSSL_SWDEV_SHA512_GENERAL_ONLY) +static int swdev_sha512_256(wc_CryptoInfo* info) +{ + wc_Sha512 shadow; + wc_Sha512* sha = info->hash.sha512; + int ret; + + if (sha == NULL) + return BAD_FUNC_ARG; + + ret = wc_InitSha512_256(&shadow); + if (ret != 0) + return ret; + + swdev_sha512_copy_state(&shadow, sha); + + if (info->hash.in != NULL) { + ret = wc_Sha512_256Update(&shadow, info->hash.in, info->hash.inSz); + if (ret != 0) + goto out; + } + if (info->hash.digest != NULL) { + ret = wc_Sha512_256Final(&shadow, info->hash.digest); + if (ret != 0) + goto out; + } + + swdev_sha512_copy_state(sha, &shadow); + +out: + wc_Sha512_256Free(&shadow); + return ret; +} +#endif +#endif /* WOLFSSL_SHA512 */ + +#if defined(WOLFSSL_SHA384) && !defined(WOLFSSL_SWDEV_SHA512_GENERAL_ONLY) +/* SHA-384 is SHA-512 with a different IV/truncation; wc_Sha384 is a typedef + * of wc_Sha512, so the shadow/copy-state dance is identical to swdev_sha512. + * When WOLFSSL_SWDEV_SHA512_GENERAL_ONLY is set this is omitted so swdev declines + * SHA-384 and the cryptocb dispatcher's SHA-512 fallback path is exercised. */ +static int swdev_sha384(wc_CryptoInfo* info) +{ + wc_Sha384* sha384 = info->hash.sha384; + wc_Sha384 shadow; + int ret; + + if (sha384 == NULL) + return BAD_FUNC_ARG; + + ret = wc_InitSha384(&shadow); + if (ret != 0) + return ret; + + swdev_sha512_copy_state(&shadow, sha384); + + if (info->hash.in != NULL) { + ret = wc_Sha384Update(&shadow, info->hash.in, info->hash.inSz); + if (ret != 0) + goto out; + } + if (info->hash.digest != NULL) { + ret = wc_Sha384Final(&shadow, info->hash.digest); + if (ret != 0) + goto out; + } + + swdev_sha512_copy_state(sha384, &shadow); + +out: + wc_Sha384Free(&shadow); + return ret; +} +#endif /* WOLFSSL_SHA384 && !WOLFSSL_SWDEV_SHA512_GENERAL_ONLY */ + #ifndef NO_AES /* Rebuild a software AES shadow from the caller's raw devKey, since the * caller's Aes has no software round-key schedule under CB_ONLY_AES. */ @@ -546,14 +717,35 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info, return CRYPTOCB_UNAVAILABLE; } #endif -#ifndef NO_SHA256 +#if !defined(NO_SHA256) || defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) case WC_ALGO_TYPE_HASH: switch (info->hash.type) { + #ifndef NO_SHA256 case WC_HASH_TYPE_SHA256: return swdev_sha256(info); + #endif #ifdef WOLFSSL_SHA224 case WC_HASH_TYPE_SHA224: return swdev_sha224(info); + #endif + #ifdef WOLFSSL_SHA512 + case WC_HASH_TYPE_SHA512: + return swdev_sha512(info); + #if !defined(WOLFSSL_NOSHA512_224) && \ + !defined(WOLFSSL_SWDEV_SHA512_GENERAL_ONLY) + case WC_HASH_TYPE_SHA512_224: + return swdev_sha512_224(info); + #endif + #if !defined(WOLFSSL_NOSHA512_256) && \ + !defined(WOLFSSL_SWDEV_SHA512_GENERAL_ONLY) + case WC_HASH_TYPE_SHA512_256: + return swdev_sha512_256(info); + #endif + #endif + #if defined(WOLFSSL_SHA384) && \ + !defined(WOLFSSL_SWDEV_SHA512_GENERAL_ONLY) + case WC_HASH_TYPE_SHA384: + return swdev_sha384(info); #endif default: return CRYPTOCB_UNAVAILABLE; diff --git a/tests/swdev/user_settings.h b/tests/swdev/user_settings.h index 09073ea2b9..c04f056b02 100644 --- a/tests/swdev/user_settings.h +++ b/tests/swdev/user_settings.h @@ -25,6 +25,7 @@ #undef WOLF_CRYPTO_CB_ONLY_RSA #undef WOLF_CRYPTO_CB_ONLY_ECC #undef WOLF_CRYPTO_CB_ONLY_SHA256 +#undef WOLF_CRYPTO_CB_ONLY_SHA512 #undef WOLF_CRYPTO_CB_ONLY_AES #ifndef WOLF_CRYPTO_CB diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index c2cb707f3f..ce41423166 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -62,6 +62,7 @@ Crypto Callback Build Options: * 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 + * WOLF_CRYPTO_CB_ONLY_SHA512: Use only callbacks for SHA-512 default: off * WOLF_CRYPTO_CB_ONLY_AES: Use only callbacks for AES default: off */ @@ -2154,7 +2155,7 @@ int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, 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) { + if (sha512 != NULL && digestSz == WC_SHA512_224_DIGEST_SIZE) { sha512->digest[0] = W64LIT(0x8c3d37c819544da2); sha512->digest[1] = W64LIT(0x73e1996689dcd4d6); sha512->digest[2] = W64LIT(0x1dfab7ae32ff9c82); @@ -2166,7 +2167,7 @@ int wc_CryptoCb_Sha512Hash(wc_Sha512* sha512, const byte* in, } #endif #if !defined(WOLFSSL_NOSHA512_256) - if (digestSz == WC_SHA512_256_DIGEST_SIZE) { + if (sha512 != NULL && digestSz == WC_SHA512_256_DIGEST_SIZE) { sha512->digest[0] = W64LIT(0x22312194fc2bf72c); sha512->digest[1] = W64LIT(0x9f555fa3c84c64c2); sha512->digest[2] = W64LIT(0x2393b86b6f53b151); diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 425ad745c2..b2f57b13b8 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -56,6 +56,12 @@ #include +#if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && \ + defined(WOLF_CRYPTO_CB_ONLY_SHA512) && defined(WOLFSSL_RISCV_ASM) + #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with SHA-512 hardware" \ + " acceleration backends" +#endif + #if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && \ !defined(WOLFSSL_RISCV_ASM) @@ -159,6 +165,45 @@ /* #define DEBUG_YMM */ #endif +#ifdef WOLF_CRYPTO_CB_ONLY_SHA512 +/* WOLF_CRYPTO_CB_ONLY_SHA512 strips the software SHA-512 implementation and + * routes every operation (SHA-512, SHA-384, SHA-512/224, SHA-512/256) through + * the crypto callback. It is mutually exclusive with any in-tree SHA-512 + * hardware/asm backend: keep this list in sync with the backend dispatch + * chains in sha512.c. The RISC-V asm guard lives before the outer file guard; + * these guards live before the dispatch chain so they are evaluated before a + * hardware backend wins the #elif chain (in which case the + * WOLF_CRYPTO_CB_ONLY_SHA512 branch itself is never compiled). */ +#if (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \ + !defined(WOLFSSL_QNX_CAAM)) || \ + defined(WOLFSSL_SILABS_SHA512) || \ + defined(WOLFSSL_KCAPI_HASH) || \ + (defined(WOLFSSL_RENESAS_RSIP) && \ + !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)) || \ + defined(MAX3266X_SHA) || \ + (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)) || \ + defined(STM32_HASH_SHA512) || \ + defined(PSOC6_HASH_SHA2) || \ + defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) || \ + defined(WOLFSSL_ARMASM) || \ + (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) + #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with SHA-512 hardware" \ + " acceleration backends" +#endif +#if defined(HAVE_FIPS) + #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with FIPS builds" +#endif +/* WOLFSSL_HASH_KEEP accumulates all Update data into sha->msg and passes it + * all to hardware in Final. That pattern is driven by port-specific backends + * (e.g. CAAM) which are already excluded above; the crypto-callback Update + * path dispatches each chunk directly to the callback instead, so the two + * mechanisms are incompatible. */ +#ifdef WOLFSSL_HASH_KEEP + #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with WOLFSSL_HASH_KEEP" +#endif +#endif /* WOLF_CRYPTO_CB_ONLY_SHA512 */ + #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \ !defined(WOLFSSL_QNX_CAAM) /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */ @@ -318,6 +363,544 @@ #elif defined(PSOC6_HASH_SHA2) /* Functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */ +#elif defined(WOLF_CRYPTO_CB_ONLY_SHA512) + +static int Sha512_CbReset(wc_Sha512* sha512, const word64* initDigest, + int hashType) +{ + int i; + + if (sha512 == NULL) + return BAD_FUNC_ARG; + + for (i = 0; i < 8; i++) + sha512->digest[i] = initDigest[i]; + + sha512->buffLen = 0; + XMEMSET(sha512->buffer, 0, sizeof(sha512->buffer)); + sha512->loLen = 0; + sha512->hiLen = 0; +#ifdef WOLFSSL_HASH_FLAGS + sha512->flags = 0; +#endif +#if defined(WOLFSSL_SHA512_HASHTYPE) + sha512->hashType = hashType; +#else + (void)hashType; +#endif + return 0; +} + +static int Sha512_CbInit(wc_Sha512* sha512, const word64* initDigest, + void* heap, int devId, int hashType) +{ + int ret; + + /* Zero the whole struct first so fields not touched by the callback path + * (e.g. asyncDev, W, devCtx) never expose uninitialized stack data to a + * callback; the admin fields below are then set explicitly. */ + if (sha512 != NULL) + XMEMSET(sha512, 0, sizeof(*sha512)); + + ret = Sha512_CbReset(sha512, initDigest, hashType); + if (ret != 0) + return ret; + + sha512->heap = heap; + sha512->devId = devId; + sha512->devCtx = NULL; + + return 0; +} + +#ifdef WOLFSSL_SHA512 + +static const word64 sha512Init[8] = { + W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), + W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), + W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), + W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179) +}; + +static int Sha512_CbFinal(wc_Sha512* sha512, byte* hash, size_t digestSz) +{ + if (sha512 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + #ifndef WOLF_CRYPTO_CB_FIND + if (sha512->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, hash, digestSz); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + } + return NO_VALID_DEVID; +} + +int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) +{ + return Sha512_CbInit(sha512, sha512Init, heap, devId, + WC_HASH_TYPE_SHA512); +} + +int wc_InitSha512(wc_Sha512* sha512) +{ + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha512_ex(sha512, NULL, devId); +} + +int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) +{ + if (sha512 == NULL) + return BAD_FUNC_ARG; + if (data == NULL && len == 0) + return 0; + if (data == NULL) + return BAD_FUNC_ARG; + + #ifndef WOLF_CRYPTO_CB_FIND + if (sha512->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL, 0); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + } + return NO_VALID_DEVID; +} + +int wc_Sha512Final(wc_Sha512* sha512, byte* hash) +{ + return Sha512_CbFinal(sha512, hash, WC_SHA512_DIGEST_SIZE); +} + +void wc_Sha512Free(wc_Sha512* sha512) +{ +#ifdef WOLF_CRYPTO_CB_FREE + int ret = 0; +#endif + + if (sha512 == NULL) + return; + +#ifdef WOLF_CRYPTO_CB_FREE + #ifndef WOLF_CRYPTO_CB_FIND + if (sha512->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Free(sha512->devId, WC_ALGO_TYPE_HASH, + WC_HASH_TYPE_SHA512, 0, (void*)sha512); + /* If they want the standard free, they can call it themselves */ + /* via their callback setting devId to INVALID_DEVID */ + /* otherwise assume the callback handled it */ + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return; + /* fall-through when unavailable */ + } + + /* silence compiler warning */ + (void)ret; +#endif /* WOLF_CRYPTO_CB_FREE */ + + ForceZero(sha512, sizeof(*sha512)); +} + +int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash) +{ + int ret; + WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0); + + if (sha512 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + return MEMORY_E); + + ret = wc_Sha512Copy(sha512, tmpSha512); + if (ret == 0) { + ret = wc_Sha512Final(tmpSha512, hash); + wc_Sha512Free(tmpSha512); + } + + WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + +int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) +{ + int ret = 0; + + if (src == NULL || dst == NULL) + return BAD_FUNC_ARG; + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY) + #ifndef WOLF_CRYPTO_CB_FIND + if (src->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH, + WC_HASH_TYPE_SHA512, (void*)src, (void*)dst); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when the callback is unavailable */ + } + ret = 0; /* discard CRYPTOCB_UNAVAILABLE before the plain struct copy */ +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */ + + wc_Sha512Free(dst); + XMEMCPY(dst, src, sizeof(wc_Sha512)); + +#ifdef WOLFSSL_HASH_FLAGS + dst->flags |= WC_HASH_FLAG_ISCOPY; +#endif + + return ret; +} + +#ifdef WOLFSSL_HASH_FLAGS +int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags) +{ + if (sha512) + sha512->flags = flags; + return 0; +} +int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags) +{ + if (sha512 && flags) + *flags = sha512->flags; + return 0; +} +#endif /* WOLFSSL_HASH_FLAGS */ + +#if !defined(WOLFSSL_NOSHA512_224) && !defined(HAVE_SELFTEST) + +static const word64 sha512_224Init[8] = { + W64LIT(0x8c3d37c819544da2), W64LIT(0x73e1996689dcd4d6), + W64LIT(0x1dfab7ae32ff9c82), W64LIT(0x679dd514582f9fcf), + W64LIT(0x0f6d2b697bd44da8), W64LIT(0x77e36f7304c48942), + W64LIT(0x3f9d85a86a1d36c8), W64LIT(0x1112e6ad91d692a1) +}; + +int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId) +{ + return Sha512_CbInit(sha512, sha512_224Init, heap, devId, + WC_HASH_TYPE_SHA512_224); +} + +int wc_InitSha512_224(wc_Sha512* sha512) +{ + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha512_224_ex(sha512, NULL, devId); +} + +int wc_Sha512_224Update(wc_Sha512* sha512, const byte* data, word32 len) +{ + return wc_Sha512Update(sha512, data, len); +} + +int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash) +{ + return Sha512_CbFinal(sha512, hash, WC_SHA512_224_DIGEST_SIZE); +} + +void wc_Sha512_224Free(wc_Sha512* sha512) +{ + wc_Sha512Free(sha512); +} + +int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst) +{ + return wc_Sha512Copy(src, dst); +} + +int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash) +{ + int ret; + WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0); + + if (sha512 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + return MEMORY_E); + + ret = wc_Sha512_224Copy(sha512, tmpSha512); + if (ret == 0) { + ret = wc_Sha512_224Final(tmpSha512, hash); + wc_Sha512_224Free(tmpSha512); + } + + WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + +#ifdef WOLFSSL_HASH_FLAGS +int wc_Sha512_224SetFlags(wc_Sha512* sha512, word32 flags) +{ + return wc_Sha512SetFlags(sha512, flags); +} +int wc_Sha512_224GetFlags(wc_Sha512* sha512, word32* flags) +{ + return wc_Sha512GetFlags(sha512, flags); +} +#endif /* WOLFSSL_HASH_FLAGS */ + +#endif /* !WOLFSSL_NOSHA512_224 && !HAVE_SELFTEST */ + +#if !defined(WOLFSSL_NOSHA512_256) && !defined(HAVE_SELFTEST) + +static const word64 sha512_256Init[8] = { + W64LIT(0x22312194fc2bf72c), W64LIT(0x9f555fa3c84c64c2), + W64LIT(0x2393b86b6f53b151), W64LIT(0x963877195940eabd), + W64LIT(0x96283ee2a88effe3), W64LIT(0xbe5e1e2553863992), + W64LIT(0x2b0199fc2c85b8aa), W64LIT(0x0eb72ddc81c52ca2) +}; + +int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId) +{ + return Sha512_CbInit(sha512, sha512_256Init, heap, devId, + WC_HASH_TYPE_SHA512_256); +} + +int wc_InitSha512_256(wc_Sha512* sha512) +{ + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha512_256_ex(sha512, NULL, devId); +} + +int wc_Sha512_256Update(wc_Sha512* sha512, const byte* data, word32 len) +{ + return wc_Sha512Update(sha512, data, len); +} + +int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash) +{ + return Sha512_CbFinal(sha512, hash, WC_SHA512_256_DIGEST_SIZE); +} + +void wc_Sha512_256Free(wc_Sha512* sha512) +{ + wc_Sha512Free(sha512); +} + +int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst) +{ + return wc_Sha512Copy(src, dst); +} + +int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash) +{ + int ret; + WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0); + + if (sha512 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + return MEMORY_E); + + ret = wc_Sha512_256Copy(sha512, tmpSha512); + if (ret == 0) { + ret = wc_Sha512_256Final(tmpSha512, hash); + wc_Sha512_256Free(tmpSha512); + } + + WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + +#ifdef WOLFSSL_HASH_FLAGS +int wc_Sha512_256SetFlags(wc_Sha512* sha512, word32 flags) +{ + return wc_Sha512SetFlags(sha512, flags); +} +int wc_Sha512_256GetFlags(wc_Sha512* sha512, word32* flags) +{ + return wc_Sha512GetFlags(sha512, flags); +} +#endif /* WOLFSSL_HASH_FLAGS */ + +#endif /* !WOLFSSL_NOSHA512_256 && !HAVE_SELFTEST */ + +#endif /* WOLFSSL_SHA512 */ + +#ifdef WOLFSSL_SHA384 + +static const word64 sha384Init[8] = { + W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), + W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), + W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), + W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4) +}; + +int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) +{ + return Sha512_CbInit(sha384, sha384Init, heap, devId, + WC_HASH_TYPE_SHA384); +} + +int wc_InitSha384(wc_Sha384* sha384) +{ + int devId = INVALID_DEVID; + +#ifdef WOLF_CRYPTO_CB + devId = wc_CryptoCb_DefaultDevID(); +#endif + return wc_InitSha384_ex(sha384, NULL, devId); +} + +int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len) +{ + if (sha384 == NULL) + return BAD_FUNC_ARG; + if (data == NULL && len == 0) + return 0; + if (data == NULL) + return BAD_FUNC_ARG; + + #ifndef WOLF_CRYPTO_CB_FIND + if (sha384->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha384Hash(sha384, data, len, NULL); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + } + return NO_VALID_DEVID; +} + +int wc_Sha384Final(wc_Sha384* sha384, byte* hash) +{ + if (sha384 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + #ifndef WOLF_CRYPTO_CB_FIND + if (sha384->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha384Hash(sha384, NULL, 0, hash); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + } + return NO_VALID_DEVID; +} + +void wc_Sha384Free(wc_Sha384* sha384) +{ +#ifdef WOLF_CRYPTO_CB_FREE + int ret = 0; +#endif + + if (sha384 == NULL) + return; + +#ifdef WOLF_CRYPTO_CB_FREE + #ifndef WOLF_CRYPTO_CB_FIND + if (sha384->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Free(sha384->devId, WC_ALGO_TYPE_HASH, + WC_HASH_TYPE_SHA384, 0, (void*)sha384); + /* If they want the standard free, they can call it themselves */ + /* via their callback setting devId to INVALID_DEVID */ + /* otherwise assume the callback handled it */ + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return; + /* fall-through when unavailable */ + } + + /* silence compiler warning */ + (void)ret; +#endif /* WOLF_CRYPTO_CB_FREE */ + + ForceZero(sha384, sizeof(*sha384)); +} + +int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash) +{ + int ret; + WC_DECLARE_VAR(tmpSha384, wc_Sha384, 1, 0); + + if (sha384 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + WC_CALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + return MEMORY_E); + + ret = wc_Sha384Copy(sha384, tmpSha384); + if (ret == 0) { + ret = wc_Sha384Final(tmpSha384, hash); + wc_Sha384Free(tmpSha384); + } + + WC_FREE_VAR_EX(tmpSha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + +int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) +{ + int ret = 0; + + if (src == NULL || dst == NULL) + return BAD_FUNC_ARG; + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY) + #ifndef WOLF_CRYPTO_CB_FIND + if (src->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH, + WC_HASH_TYPE_SHA384, (void*)src, (void*)dst); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when the callback is unavailable */ + } + ret = 0; /* discard CRYPTOCB_UNAVAILABLE before the plain struct copy */ +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */ + + wc_Sha384Free(dst); + XMEMCPY(dst, src, sizeof(wc_Sha384)); + +#ifdef WOLFSSL_HASH_FLAGS + dst->flags |= WC_HASH_FLAG_ISCOPY; +#endif + + return ret; +} + +#ifdef WOLFSSL_HASH_FLAGS +int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags) +{ + if (sha384) + sha384->flags = flags; + return 0; +} +int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags) +{ + if (sha384 && flags) + *flags = sha384->flags; + return 0; +} +#endif /* WOLFSSL_HASH_FLAGS */ + +#endif /* WOLFSSL_SHA384 */ #else #ifdef WOLFSSL_SHA512 @@ -1393,6 +1976,7 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) #endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA512 */ +#ifndef WOLF_CRYPTO_CB_ONLY_SHA512 #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ @@ -2857,4 +3441,6 @@ int wc_Sha384_Grow(wc_Sha384* sha384, const byte* in, int inSz) } #endif /* WOLFSSL_SHA384 */ #endif /* WOLFSSL_HASH_KEEP */ + +#endif /* !WOLF_CRYPTO_CB_ONLY_SHA512 */ #endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 45ec4c4b15..8858601d32 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -73231,6 +73231,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hash.sha384->devId = INVALID_DEVID; #endif + #if defined(WOLF_CRYPTO_CB_ONLY_SHA512) + #ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar); + #endif + if (myCtx->exampleVar == 99) { + info->hash.sha384->devId = devIdArg; + return 0; + } + #endif if (info->hash.in != NULL) { ret = wc_Sha384Update( @@ -73260,6 +73269,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hash.sha512->devId = INVALID_DEVID; #endif + #if defined(WOLF_CRYPTO_CB_ONLY_SHA512) + #ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar); + #endif + if (myCtx->exampleVar == 99) { + info->hash.sha512->devId = devIdArg; + return 0; + } + #endif if (info->hash.in != NULL) { ret = wc_Sha512Update( diff --git a/wolfssl/openssl/sha.h b/wolfssl/openssl/sha.h index 1b863b17e9..e8a1678a14 100644 --- a/wolfssl/openssl/sha.h +++ b/wolfssl/openssl/sha.h @@ -254,8 +254,10 @@ WOLFSSL_API int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha); WOLFSSL_API int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input, unsigned long sz); WOLFSSL_API int wolfSSL_SHA512_Final(byte* output, WOLFSSL_SHA512_CTX* sha); +#ifndef WOLF_CRYPTO_CB_ONLY_SHA512 /* no underlying wc_Sha512Transform */ WOLFSSL_API int wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX* sha512, const unsigned char* data); +#endif #if !defined(OPENSSL_COEXIST) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) enum { SHA512_DIGEST_LENGTH = 64 @@ -266,7 +268,9 @@ typedef WOLFSSL_SHA512_CTX SHA512_CTX; #define SHA512_Init wolfSSL_SHA512_Init #define SHA512_Update wolfSSL_SHA512_Update #define SHA512_Final wolfSSL_SHA512_Final +#ifndef WOLF_CRYPTO_CB_ONLY_SHA512 /* no underlying wc_Sha512Transform */ #define SHA512_Transform wolfSSL_SHA512_Transform +#endif #if defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) /* SHA512 is only available in non-fips mode because of SHA512 enum in FIPS * build. */ @@ -283,14 +287,18 @@ WOLFSSL_API int wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX* sha, const void* input, unsigned long sz); WOLFSSL_API int wolfSSL_SHA512_224_Final(byte* output, WOLFSSL_SHA512_224_CTX* sha); +#ifndef WOLF_CRYPTO_CB_ONLY_SHA512 /* no underlying wc_Sha512_224Transform */ WOLFSSL_API int wolfSSL_SHA512_224_Transform(WOLFSSL_SHA512_CTX* sha512, const unsigned char* data); +#endif #if !defined(OPENSSL_COEXIST) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) #define SHA512_224_Init wolfSSL_SHA512_224_Init #define SHA512_224_Update wolfSSL_SHA512_224_Update #define SHA512_224_Final wolfSSL_SHA512_224_Final +#ifndef WOLF_CRYPTO_CB_ONLY_SHA512 /* no underlying wc_Sha512_224Transform */ #define SHA512_224_Transform wolfSSL_SHA512_224_Transform +#endif #if defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) #define SHA512_224 wolfSSL_SHA512_224 @@ -306,14 +314,18 @@ WOLFSSL_API int wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_CTX* sha); WOLFSSL_API int wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX* sha, const void* input, unsigned long sz); WOLFSSL_API int wolfSSL_SHA512_256_Final(byte* output, WOLFSSL_SHA512_256_CTX* sha); +#ifndef WOLF_CRYPTO_CB_ONLY_SHA512 /* no underlying wc_Sha512_256Transform */ WOLFSSL_API int wolfSSL_SHA512_256_Transform(WOLFSSL_SHA512_CTX* sha512, const unsigned char* data); +#endif #if !defined(OPENSSL_COEXIST) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) #define SHA512_256_Init wolfSSL_SHA512_256_Init #define SHA512_256_Update wolfSSL_SHA512_256_Update #define SHA512_256_Final wolfSSL_SHA512_256_Final +#ifndef WOLF_CRYPTO_CB_ONLY_SHA512 /* no underlying wc_Sha512_256Transform */ #define SHA512_256_Transform wolfSSL_SHA512_256_Transform +#endif #if defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) #define SHA512_256 wolfSSL_SHA512_256 diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 3247bb9298..e34116c358 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -5224,6 +5224,12 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS." #if defined(WOLF_CRYPTO_CB_ONLY_SHA256) && !defined(WOLF_CRYPTO_CB) #error "WOLF_CRYPTO_CB_ONLY_SHA256 requires WOLF_CRYPTO_CB" #endif +#if defined(WOLF_CRYPTO_CB_ONLY_SHA512) && !defined(WOLF_CRYPTO_CB) + #error "WOLF_CRYPTO_CB_ONLY_SHA512 requires WOLF_CRYPTO_CB" +#endif +#if defined(WOLF_CRYPTO_CB_ONLY_SHA512) && defined(HAVE_FIPS) + #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with FIPS builds" +#endif #if defined(WOLF_CRYPTO_CB_ONLY_AES) && !defined(WOLF_CRYPTO_CB) #error "WOLF_CRYPTO_CB_ONLY_AES requires WOLF_CRYPTO_CB" #endif diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 292021c44b..4491700a2f 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -80,6 +80,12 @@ #include #endif +/* no raw hash access when software transform is stripped */ +#if defined(WOLF_CRYPTO_CB_ONLY_SHA512) +#undef WOLFSSL_NO_HASH_RAW +#define WOLFSSL_NO_HASH_RAW +#endif + #define SHA512_NOINLINE WC_NO_INLINE #ifdef WOLFSSL_SHA512 @@ -238,7 +244,9 @@ WOLFSSL_LOCAL void Transform_Sha512_Len_base(wc_Sha512* sha512, WOLFSSL_API int wc_InitSha512(wc_Sha512* sha); WOLFSSL_API int wc_InitSha512_ex(wc_Sha512* sha, void* heap, int devId); WOLFSSL_API int wc_Sha512Update(wc_Sha512* sha, const byte* data, word32 len); +#if !defined(WOLF_CRYPTO_CB_ONLY_SHA512) WOLFSSL_API int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash); +#endif WOLFSSL_API int wc_Sha512Final(wc_Sha512* sha512, byte* hash); WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha); @@ -253,7 +261,8 @@ WOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst); WOLFSSL_API int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags); #endif -#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL) +#if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512) WOLFSSL_API int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data); #endif @@ -262,7 +271,9 @@ WOLFSSL_API int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data); WOLFSSL_API int wc_InitSha512_224(wc_Sha512* sha); WOLFSSL_API int wc_InitSha512_224_ex(wc_Sha512* sha, void* heap, int devId); WOLFSSL_API int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len); +#if !defined(WOLF_CRYPTO_CB_ONLY_SHA512) WOLFSSL_API int wc_Sha512_224FinalRaw(wc_Sha512* sha512, byte* hash); +#endif WOLFSSL_API int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash); WOLFSSL_API void wc_Sha512_224Free(wc_Sha512* sha); WOLFSSL_API int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash); @@ -272,7 +283,8 @@ WOLFSSL_API int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst); WOLFSSL_API int wc_Sha512_224GetFlags(wc_Sha512* sha512, word32* flags); #endif -#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL) +#if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512) WOLFSSL_API int wc_Sha512_224Transform(wc_Sha512* sha, const unsigned char* data); #endif /* OPENSSL_EXTRA */ @@ -283,7 +295,9 @@ WOLFSSL_API int wc_Sha512_224Transform(wc_Sha512* sha, WOLFSSL_API int wc_InitSha512_256(wc_Sha512* sha); WOLFSSL_API int wc_InitSha512_256_ex(wc_Sha512* sha, void* heap, int devId); WOLFSSL_API int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len); +#if !defined(WOLF_CRYPTO_CB_ONLY_SHA512) WOLFSSL_API int wc_Sha512_256FinalRaw(wc_Sha512* sha512, byte* hash); +#endif WOLFSSL_API int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash); WOLFSSL_API void wc_Sha512_256Free(wc_Sha512* sha); WOLFSSL_API int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash); @@ -293,7 +307,8 @@ WOLFSSL_API int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst); WOLFSSL_API int wc_Sha512_256GetFlags(wc_Sha512* sha512, word32* flags); #endif -#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL) +#if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512) WOLFSSL_API int wc_Sha512_256Transform(wc_Sha512* sha, const unsigned char* data); #endif /* OPENSSL_EXTRA */ @@ -334,7 +349,9 @@ WOLFSSL_API int wc_Sha512_256Transform(wc_Sha512* sha, WOLFSSL_API int wc_InitSha384(wc_Sha384* sha); WOLFSSL_API int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devId); WOLFSSL_API int wc_Sha384Update(wc_Sha384* sha, const byte* data, word32 len); +#if !defined(WOLF_CRYPTO_CB_ONLY_SHA512) WOLFSSL_API int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash); +#endif WOLFSSL_API int wc_Sha384Final(wc_Sha384* sha384, byte* hash); WOLFSSL_API void wc_Sha384Free(wc_Sha384* sha);