From 0c8cabedff0e5c0890f3c8887dfd6b8880e16212 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Tue, 19 May 2026 09:30:42 +0200 Subject: [PATCH 1/2] crpytocb: support SHA224 under WOLF_CRYPTO_CB_ONLY_SHA256 --- .github/workflows/cryptocb-only.yml | 4 +- tests/swdev/README.md | 5 +- tests/swdev/swdev.c | 42 ++++++++++++++++ wolfcrypt/src/sha256.c | 77 +++++++++++++++++++++++++++-- wolfcrypt/test/test.c | 34 +++++++++++++ 5 files changed, 151 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cryptocb-only.yml b/.github/workflows/cryptocb-only.yml index 101c74dffcc..ef96358f098 100644 --- a/.github/workflows/cryptocb-only.yml +++ b/.github/workflows/cryptocb-only.yml @@ -29,9 +29,8 @@ jobs: - name: RSA cppflags: -DWOLF_CRYPTO_CB_ONLY_RSA # WOLF_CRYPTO_CB_ONLY_SHA256: strips software SHA-256; swdev provides - # the software path via cryptocb. SHA-224 not yet supported. + # the software path via cryptocb. - name: SHA256 - extra_config: --disable-sha224 cppflags: -DWOLF_CRYPTO_CB_ONLY_SHA256 # WOLF_CRYPTO_CB_ONLY_AES: strips software AES; swdev provides the # software path via cryptocb. @@ -49,7 +48,6 @@ jobs: # algorithm call that a single-strip entry would still resolve via # the remaining software paths. - name: ALL - extra_config: --disable-sha224 cppflags: >- -DWOLF_CRYPTO_CB_ONLY_ECC -DWOLF_CRYPTO_CB_ONLY_RSA -DWOLF_CRYPTO_CB_ONLY_SHA256 -DWOLF_CRYPTO_CB_ONLY_AES diff --git a/tests/swdev/README.md b/tests/swdev/README.md index 80b097299f4..3fc8f24e362 100644 --- a/tests/swdev/README.md +++ b/tests/swdev/README.md @@ -119,8 +119,7 @@ struct layouts, so flipping them between the two compiles is safe. CPPFLAGS="-DWOLF_CRYPTO_CB_ONLY_ECC \ -DWOLF_CRYPTO_CB_ONLY_RSA \ -DWOLF_CRYPTO_CB_ONLY_SHA256 \ - -DWOLF_CRYPTO_CB_ONLY_AES" \ - --disable-sha224 + -DWOLF_CRYPTO_CB_ONLY_AES" make make check ``` @@ -135,8 +134,6 @@ Notes: Out-of-tree (VPATH) builds fail at configure time. swdev is built from `wolfcrypt/test/include.am` and inherits `PARENT_SRCS`, `PARENT_BUILD_CFLAGS`, etc., from the parent build. -- `--disable-sha224` is required when `WOLF_CRYPTO_CB_ONLY_SHA256` is - set: SHA-224 is unsupported for now. For the full CI matrix that exercises each `_ONLY_*` macro, see `.github/workflows/cryptocb-only.yml`. diff --git a/tests/swdev/swdev.c b/tests/swdev/swdev.c index 18bcfaed1bf..db06f204092 100644 --- a/tests/swdev/swdev.c +++ b/tests/swdev/swdev.c @@ -209,6 +209,44 @@ static int swdev_sha256(wc_CryptoInfo* info) wc_Sha256Free(&shadow); return ret; } + +#ifdef WOLFSSL_SHA224 +/* SHA-224 is SHA-256 with a different IV/truncation; wc_Sha224 is a typedef + * of wc_Sha256, so the same shadow/copy-state dance applies. */ +static int swdev_sha224(wc_CryptoInfo* info) +{ + wc_Sha224* sha224 = info->hash.sha224; + wc_Sha224 shadow; + int ret; + + if (sha224 == NULL) + return BAD_FUNC_ARG; + + ret = wc_InitSha224(&shadow); + if (ret != 0) + return ret; + + swdev_sha256_copy_state((wc_Sha256*)&shadow, (const wc_Sha256*)sha224); + + if (info->hash.in != NULL) { + ret = wc_Sha224Update(&shadow, info->hash.in, info->hash.inSz); + if (ret != 0) + goto out; + } + + if (info->hash.digest != NULL) { + ret = wc_Sha224Final(&shadow, info->hash.digest); + if (ret != 0) + goto out; + } + + swdev_sha256_copy_state((wc_Sha256*)sha224, (const wc_Sha256*)&shadow); + +out: + wc_Sha224Free(&shadow); + return ret; +} +#endif /* WOLFSSL_SHA224 */ #endif /* !NO_SHA256 */ #ifndef NO_AES @@ -513,6 +551,10 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info, switch (info->hash.type) { case WC_HASH_TYPE_SHA256: return swdev_sha256(info); + #ifdef WOLFSSL_SHA224 + case WC_HASH_TYPE_SHA224: + return swdev_sha224(info); + #endif default: return CRYPTOCB_UNAVAILABLE; } diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index e5be2bcc8a2..9246c1405f7 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -60,10 +60,6 @@ on the specific device platform. #if !defined(NO_SHA256) && !defined(WOLFSSL_RISCV_ASM) -#if defined(WOLF_CRYPTO_CB_ONLY_SHA256) && defined(WOLFSSL_SHA224) - #error "WOLF_CRYPTO_CB_ONLY_SHA256 is incompatible with WOLFSSL_SHA224" -#endif - #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ #define FIPS_NO_WRAPPERS @@ -2148,6 +2144,35 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data, #elif defined(PSOC6_HASH_SHA2) /* Implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */ +#elif defined(WOLF_CRYPTO_CB_ONLY_SHA256) + int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId) + { + int ret; + if (sha224 == NULL) + return BAD_FUNC_ARG; + ret = InitSha256((wc_Sha256*)sha224); + if (ret != 0) + return ret; + sha224->digest[0] = 0xc1059ed8; + sha224->digest[1] = 0x367cd507; + sha224->digest[2] = 0x3070dd17; + sha224->digest[3] = 0xf70e5939; + sha224->digest[4] = 0xffc00b31; + sha224->digest[5] = 0x68581511; + sha224->digest[6] = 0x64f98fa7; + sha224->digest[7] = 0xbefa4fa4; + sha224->heap = heap; + sha224->devId = devId; + sha224->devCtx = NULL; + #ifdef WOLFSSL_SMALL_STACK_CACHE + sha224->W = NULL; + #endif + #ifdef WOLFSSL_ASYNC_CRYPT + XMEMSET(&sha224->asyncDev, 0, sizeof(sha224->asyncDev)); + #endif + return ret; + } + #else #define NEED_SOFT_SHA224 @@ -2369,6 +2394,50 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data, } #endif /* end of SHA224 software implementation */ +#ifdef WOLF_CRYPTO_CB_ONLY_SHA256 + + int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len) + { + if (sha224 == 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 (sha224->devId != INVALID_DEVID) + #endif + { + int ret = wc_CryptoCb_Sha224Hash(sha224, data, len, NULL); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + } + + return NO_VALID_DEVID; + } + + int wc_Sha224Final(wc_Sha224* sha224, byte* hash) + { + int ret; + + if (sha224 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + #ifndef WOLF_CRYPTO_CB_FIND + if (sha224->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Sha224Hash(sha224, NULL, 0, hash); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + } + + return NO_VALID_DEVID; + } + +#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */ + int wc_InitSha224(wc_Sha224* sha224) { int devId = INVALID_DEVID; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6057056b545..c2f91012859 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -72301,6 +72301,40 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) } else #endif + #ifdef WOLFSSL_SHA224 + if (info->hash.type == WC_HASH_TYPE_SHA224) { + if (info->hash.sha224 == NULL) + return NOT_COMPILED_IN; + + /* set devId to invalid, so software is used */ + info->hash.sha224->devId = INVALID_DEVID; + #if defined(WOLF_CRYPTO_CB_ONLY_SHA256) + #ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar); + #endif + if (myCtx->exampleVar == 99) { + info->hash.sha224->devId = devIdArg; + return 0; + } + #endif + + if (info->hash.in != NULL) { + ret = wc_Sha224Update( + info->hash.sha224, + info->hash.in, + info->hash.inSz); + } + if (info->hash.digest != NULL) { + ret = wc_Sha224Final( + info->hash.sha224, + info->hash.digest); + } + + /* reset devId */ + info->hash.sha224->devId = devIdArg; + } + else + #endif #ifdef WOLFSSL_SHA384 if (info->hash.type == WC_HASH_TYPE_SHA384) { if (info->hash.sha384 == NULL) From 408ea84c839ebfef113b336c802dc42a52c23b29 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Wed, 20 May 2026 11:28:59 +0200 Subject: [PATCH 2/2] sha256: check no hw accelleartion is enabled with CB_ONLY_SHA256 --- wolfcrypt/src/sha256.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 9246c1405f7..047c57dade8 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -97,6 +97,42 @@ on the specific device platform. #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW #endif +/* WOLF_CRYPTO_CB_ONLY_SHA256 strips the software SHA-256 implementation and + * routes every operation through the crypto callback. It is mutually exclusive + * with any in-tree SHA-256 hardware/asm backend below: keep this list in sync + * with the #elif chain at the start of the "Hardware Acceleration" section. */ +#if defined(WOLF_CRYPTO_CB_ONLY_SHA256) && ( \ + defined(WOLFSSL_TI_HASH) || \ + defined(WOLFSSL_CRYPTOCELL) || \ + defined(MAX3266X_SHA) || \ + defined(FREESCALE_LTC_SHA) || \ + defined(FREESCALE_MMCAU_SHA) || \ + defined(WOLFSSL_PIC32MZ_HASH) || \ + defined(STM32_HASH_SHA2) || \ + (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)) || \ + (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)) || \ + defined(WOLFSSL_AFALG_HASH) || \ + defined(WOLFSSL_DEVCRYPTO_HASH) || \ + (defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_HASH)) || \ + defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) || \ + defined(WOLFSSL_RENESAS_TSIP_TLS) || \ + defined(WOLFSSL_RENESAS_SCEPROTECT) || \ + defined(WOLFSSL_RENESAS_RSIP) || \ + defined(PSOC6_HASH_SHA2) || \ + defined(WOLFSSL_IMXRT_DCP) || \ + defined(WOLFSSL_NXP_HASHCRYPT_SHA) || \ + defined(WOLFSSL_SILABS_SE_ACCEL) || \ + defined(WOLFSSL_KCAPI_HASH) || \ + (defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)) || \ + defined(WOLFSSL_RENESAS_RX64_HASH) || \ + defined(WOLFSSL_PPC32_ASM) || \ + 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_SHA256 is incompatible with SHA-256 hardware" \ + " acceleration backends" +#endif + #ifdef WOLFSSL_ESPIDF /* Define the ESP_LOGx(TAG, WOLFSSL_ESPIDF_BLANKLINE_MESSAGE value for output messages here. **