Skip to content

Commit de44d8d

Browse files
committed
WOLF_CRYPTO_CB_ONLY_SHA256: strip software SHA-256 and dispatch via swdev
Add WOLF_CRYPTO_CB_ONLY_SHA256: when set, the SHA-256 software. wc_Sha256FinalRaw is reduced to a stub returning NO_VALID_DEVID, and sha256.h force-defines WOLFSSL_NO_HASH_RAW so the constant-time TLS HMAC path falls back to its backend-opaque variant. Incompatible with WOLFSSL_SHA224, which aliases the SHA-256 statics; #error guard added. Add wc_swdev support for SHA-256 for testing.
1 parent bd5e435 commit de44d8d

8 files changed

Lines changed: 222 additions & 5 deletions

File tree

.github/workflows/cryptocb-only.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ jobs:
2828
# software path via cryptocb.
2929
- name: RSA
3030
cppflags: -DWOLF_CRYPTO_CB_ONLY_RSA
31+
# WOLF_CRYPTO_CB_ONLY_SHA256: strips software SHA-256; swdev provides
32+
# the software path via cryptocb. SHA-224 piggybacks on the SHA-256
33+
# software core so it is incompatible with this strip and must be
34+
# explicitly disabled (it is default-on on x86_64/aarch64).
35+
- name: SHA256
36+
extra_config: --disable-sha224
37+
cppflags: -DWOLF_CRYPTO_CB_ONLY_SHA256
3138
name: make check (${{ matrix.name }})
3239
if: github.repository_owner == 'wolfssl'
3340
runs-on: ubuntu-24.04

tests/api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28472,6 +28472,7 @@ static int test_SSL_CIPHER_get_xxx(void)
2847228472
}
2847328473

2847428474
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
28475+
!defined(WOLF_CRYPTO_CB_ONLY_SHA256) && \
2847528476
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA)
2847628477

2847728478
static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer,
@@ -29475,6 +29476,7 @@ static int test_wc_CryptoCb(void)
2947529476
{
2947629477
EXPECT_DECLS;
2947729478
#if defined(WOLF_CRYPTO_CB) && \
29479+
!defined(WOLF_CRYPTO_CB_ONLY_SHA256) && \
2947829480
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA)
2947929481
/* TODO: Add crypto callback API tests */
2948029482

tests/swdev/swdev.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#ifdef HAVE_ECC
1414
#include <wolfssl/wolfcrypt/ecc.h>
1515
#endif
16+
#ifndef NO_SHA256
17+
#include <wolfssl/wolfcrypt/sha256.h>
18+
#endif
1619

1720
static int swdev_initialized = 0;
1821

@@ -120,6 +123,62 @@ static int swdev_ecc_get_sig_size(wc_CryptoInfo* info)
120123
}
121124
#endif /* HAVE_ECC */
122125

126+
#ifndef NO_SHA256
127+
/* Copy hash state between caller's wc_Sha256 and swdev's shadow, leaving
128+
* admin fields (heap, devId, devCtx, W, async, HW ctx) per-side. */
129+
static void swdev_sha256_copy_state(wc_Sha256* dst, const wc_Sha256* src)
130+
{
131+
XMEMCPY(dst->digest, src->digest, sizeof(dst->digest));
132+
XMEMCPY(dst->buffer, src->buffer, sizeof(dst->buffer));
133+
dst->buffLen = src->buffLen;
134+
dst->loLen = src->loLen;
135+
dst->hiLen = src->hiLen;
136+
#ifdef WC_C_DYNAMIC_FALLBACK
137+
dst->sha_method = src->sha_method;
138+
#endif
139+
#ifdef WOLFSSL_HASH_FLAGS
140+
dst->flags = src->flags;
141+
#endif
142+
}
143+
144+
/* Run the op on a per-call shadow wc_Sha256 owned by swdev, copying state
145+
* in and out around it. The caller's struct, allocated by libwolfssl with
146+
* the software init stripped, can't be used directly. */
147+
static int swdev_sha256(wc_CryptoInfo* info)
148+
{
149+
wc_Sha256* sha256 = info->hash.sha256;
150+
wc_Sha256 shadow;
151+
int ret;
152+
153+
if (sha256 == NULL)
154+
return BAD_FUNC_ARG;
155+
156+
ret = wc_InitSha256(&shadow);
157+
if (ret != 0)
158+
return ret;
159+
160+
swdev_sha256_copy_state(&shadow, sha256);
161+
162+
if (info->hash.in != NULL) {
163+
ret = wc_Sha256Update(&shadow, info->hash.in, info->hash.inSz);
164+
if (ret != 0)
165+
goto out;
166+
}
167+
168+
if (info->hash.digest != NULL) {
169+
ret = wc_Sha256Final(&shadow, info->hash.digest);
170+
if (ret != 0)
171+
goto out;
172+
}
173+
174+
swdev_sha256_copy_state(sha256, &shadow);
175+
176+
out:
177+
wc_Sha256Free(&shadow);
178+
return ret;
179+
}
180+
#endif /* !NO_SHA256 */
181+
123182
WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
124183
void* ctx)
125184
{
@@ -164,6 +223,15 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
164223
default:
165224
return CRYPTOCB_UNAVAILABLE;
166225
}
226+
#endif
227+
#ifndef NO_SHA256
228+
case WC_ALGO_TYPE_HASH:
229+
switch (info->hash.type) {
230+
case WC_HASH_TYPE_SHA256:
231+
return swdev_sha256(info);
232+
default:
233+
return CRYPTOCB_UNAVAILABLE;
234+
}
167235
#endif
168236
default:
169237
return CRYPTOCB_UNAVAILABLE;

tests/swdev/user_settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#undef WOLF_CRYPTO_CB_ONLY_RSA
1717
#undef WOLF_CRYPTO_CB_ONLY_ECC
18+
#undef WOLF_CRYPTO_CB_ONLY_SHA256
1819

1920
#ifndef WOLF_CRYPTO_CB
2021
#error "wc_swdev requires the main build to define WOLF_CRYPTO_CB"

wolfcrypt/src/cryptocb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Crypto Callback Build Options:
5252
* and SHA-512 operations.
5353
* WOLF_CRYPTO_CB_ONLY_ECC: Use only callbacks for ECC default: off
5454
* WOLF_CRYPTO_CB_ONLY_RSA: Use only callbacks for RSA default: off
55+
* WOLF_CRYPTO_CB_ONLY_SHA256: Use only callbacks for SHA-256 default: off
5556
*/
5657

5758
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>

wolfcrypt/src/sha256.c

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ on the specific device platform.
6060

6161
#if !defined(NO_SHA256) && !defined(WOLFSSL_RISCV_ASM)
6262

63+
#if defined(WOLF_CRYPTO_CB_ONLY_SHA256) && defined(WOLFSSL_SHA224)
64+
#error "WOLF_CRYPTO_CB_ONLY_SHA256 is incompatible with WOLFSSL_SHA224"
65+
#endif
66+
6367
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
6468
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
6569
#define FIPS_NO_WRAPPERS
@@ -290,7 +294,8 @@ static int InitSha256(wc_Sha256* sha256)
290294

291295
/* Hardware Acceleration */
292296
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
293-
(defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
297+
(defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) && \
298+
!defined(WOLF_CRYPTO_CB_ONLY_SHA256)
294299

295300
/* in case intel instructions aren't available, plus we need the K[] global */
296301
#define NEED_SOFT_SHA256
@@ -1080,7 +1085,7 @@ static int InitSha256(wc_Sha256* sha256)
10801085
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
10811086

10821087
/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
1083-
#elif defined(WOLFSSL_PPC32_ASM)
1088+
#elif defined(WOLFSSL_PPC32_ASM) && !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
10841089

10851090
extern void Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
10861091
word32 len);
@@ -1110,7 +1115,7 @@ static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
11101115
#define XTRANSFORM Transform_Sha256
11111116
#define XTRANSFORM_LEN Transform_Sha256_Len
11121117

1113-
#elif defined(WOLFSSL_ARMASM)
1118+
#elif defined(WOLFSSL_ARMASM) && !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
11141119

11151120
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
11161121
{
@@ -1165,6 +1170,21 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
11651170
#define XTRANSFORM Transform_Sha256
11661171
#define XTRANSFORM_LEN Transform_Sha256_Len
11671172

1173+
#elif defined(WOLF_CRYPTO_CB_ONLY_SHA256)
1174+
/* Software SHA-256 stripped; every op dispatches via cryptocb. */
1175+
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1176+
{
1177+
int ret;
1178+
if (sha256 == NULL)
1179+
return BAD_FUNC_ARG;
1180+
ret = InitSha256(sha256);
1181+
if (ret != 0)
1182+
return ret;
1183+
sha256->heap = heap;
1184+
sha256->devId = devId;
1185+
sha256->devCtx = NULL;
1186+
return ret;
1187+
}
11681188
#else
11691189
#define NEED_SOFT_SHA256
11701190

@@ -1397,7 +1417,6 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
13971417
#endif
13981418
/* End wc_ software implementation */
13991419

1400-
14011420
#ifdef XTRANSFORM
14021421

14031422
static WC_INLINE void AddLength(wc_Sha256* sha256, word32 len)
@@ -1774,6 +1793,7 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
17741793

17751794
#if !defined(WOLFSSL_KCAPI_HASH)
17761795

1796+
#ifndef WOLFSSL_NO_HASH_RAW
17771797
int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
17781798
{
17791799
#ifdef LITTLE_ENDIAN_ORDER
@@ -1797,6 +1817,7 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
17971817

17981818
return 0;
17991819
}
1820+
#endif /* !WOLFSSL_NO_HASH_RAW */
18001821

18011822
int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
18021823
{
@@ -1960,6 +1981,55 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
19601981

19611982
#endif /* XTRANSFORM */
19621983

1984+
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
1985+
1986+
int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
1987+
{
1988+
if (sha256 == NULL) {
1989+
return BAD_FUNC_ARG;
1990+
}
1991+
if (data == NULL && len == 0) {
1992+
/* valid, but do nothing */
1993+
return 0;
1994+
}
1995+
if (data == NULL) {
1996+
return BAD_FUNC_ARG;
1997+
}
1998+
1999+
#ifndef WOLF_CRYPTO_CB_FIND
2000+
if (sha256->devId != INVALID_DEVID)
2001+
#endif
2002+
{
2003+
int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);
2004+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2005+
return ret;
2006+
}
2007+
2008+
return NO_VALID_DEVID;
2009+
}
2010+
2011+
int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
2012+
{
2013+
int ret;
2014+
2015+
if (sha256 == NULL || hash == NULL) {
2016+
return BAD_FUNC_ARG;
2017+
}
2018+
2019+
#ifndef WOLF_CRYPTO_CB_FIND
2020+
if (sha256->devId != INVALID_DEVID)
2021+
#endif
2022+
{
2023+
ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);
2024+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2025+
return ret;
2026+
}
2027+
2028+
return NO_VALID_DEVID;
2029+
}
2030+
2031+
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
2032+
19632033

19642034
#ifdef WOLFSSL_SHA224
19652035

wolfcrypt/test/test.c

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5665,7 +5665,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha256_test(void)
56655665
#undef LARGE_HASH_TEST_INPUT_SZ
56665666
#endif /* NO_LARGE_HASH_TEST */
56675667

5668-
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH)
5668+
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH) && \
5669+
!defined(WOLF_CRYPTO_CB_ONLY_SHA256)
56695670
{
56705671
WOLFSSL_SMALL_STACK_STATIC const unsigned char
56715672
data_hb[WC_SHA256_BLOCK_SIZE] = {
@@ -68106,6 +68107,52 @@ static wc_test_ret_t ecc_onlycb_test(myCryptoDevCtx *ctx)
6810668107
}
6810768108
#endif
6810868109

68110+
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
68111+
/* Exercise SHA-256 dispatch under CB_ONLY_SHA256: cb-handled then cb-delegated. */
68112+
static wc_test_ret_t sha256_onlycb_test(myCryptoDevCtx *ctx)
68113+
{
68114+
wc_test_ret_t ret = 0;
68115+
#if !defined(NO_SHA256)
68116+
wc_Sha256 sha;
68117+
byte hash[WC_SHA256_DIGEST_SIZE];
68118+
const byte in[] = "abc";
68119+
68120+
ret = wc_InitSha256_ex(&sha, HEAP_HINT, devId);
68121+
if (ret != 0)
68122+
return WC_TEST_RET_ENC_EC(ret);
68123+
68124+
/* cb handles the op, expects 0(success) */
68125+
ctx->exampleVar = 99;
68126+
ret = wc_Sha256Update(&sha, in, (word32)sizeof(in) - 1);
68127+
if (ret != 0)
68128+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
68129+
ret = wc_Sha256Final(&sha, hash);
68130+
if (ret != 0)
68131+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
68132+
68133+
/* cb delegates to software, expects NO_VALID_DEVID(failure) */
68134+
ctx->exampleVar = 1;
68135+
ret = wc_Sha256Update(&sha, in, (word32)sizeof(in) - 1);
68136+
if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) {
68137+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
68138+
} else {
68139+
ret = 0;
68140+
}
68141+
ret = wc_Sha256Final(&sha, hash);
68142+
if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) {
68143+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
68144+
} else {
68145+
ret = 0;
68146+
}
68147+
68148+
exit_onlycb:
68149+
wc_Sha256Free(&sha);
68150+
#endif /* !NO_SHA256 */
68151+
(void)ctx;
68152+
return ret;
68153+
}
68154+
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
68155+
6810968156
/* Example crypto dev callback function that calls software version */
6811068157
static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
6811168158
{
@@ -68727,6 +68774,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
6872768774

6872868775
/* set devId to invalid, so software is used */
6872968776
info->hash.sha256->devId = INVALID_DEVID;
68777+
#if defined(WOLF_CRYPTO_CB_ONLY_SHA256)
68778+
#ifdef DEBUG_WOLFSSL
68779+
printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar);
68780+
#endif
68781+
if (myCtx->exampleVar == 99) {
68782+
info->hash.sha256->devId = devIdArg;
68783+
return 0;
68784+
}
68785+
#endif
6873068786

6873168787
if (info->hash.in != NULL) {
6873268788
ret = wc_Sha256Update(
@@ -69857,6 +69913,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
6985769913
ret = ecc_onlycb_test(&myCtx);
6985869914
PRIVATE_KEY_LOCK();
6985969915
#endif
69916+
#if defined(WOLF_CRYPTO_CB_ONLY_SHA256) && !defined(WOLFSSL_SWDEV)
69917+
PRIVATE_KEY_UNLOCK();
69918+
if (ret == 0)
69919+
ret = sha256_onlycb_test(&myCtx);
69920+
PRIVATE_KEY_LOCK();
69921+
#endif
6986069922
#ifdef WOLFSSL_HAVE_MLKEM
6986169923
if (ret == 0)
6986269924
ret = mlkem_test();

wolfssl/wolfcrypt/sha256.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@
102102
#define WOLFSSL_NO_HASH_RAW
103103
#endif
104104

105+
/* no raw hash access when software transform is stripped */
106+
#if defined(WOLF_CRYPTO_CB_ONLY_SHA256)
107+
#undef WOLFSSL_NO_HASH_RAW
108+
#define WOLFSSL_NO_HASH_RAW
109+
#endif
110+
105111
#define SHA256_NOINLINE WC_NO_INLINE
106112

107113
#if !defined(NO_OLD_SHA_NAMES)

0 commit comments

Comments
 (0)