mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 20:10:49 +02:00
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.
This commit is contained in:
@@ -28,6 +28,13 @@ jobs:
|
||||
# software path via cryptocb.
|
||||
- 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 piggybacks on the SHA-256
|
||||
# software core so it is incompatible with this strip and must be
|
||||
# explicitly disabled (it is default-on on x86_64/aarch64).
|
||||
- name: SHA256
|
||||
extra_config: --disable-sha224
|
||||
cppflags: -DWOLF_CRYPTO_CB_ONLY_SHA256
|
||||
name: make check (${{ matrix.name }})
|
||||
if: github.repository_owner == 'wolfssl'
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
@@ -30609,6 +30609,7 @@ 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_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA)
|
||||
|
||||
static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer,
|
||||
@@ -31612,6 +31613,7 @@ static int test_wc_CryptoCb(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLF_CRYPTO_CB) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_SHA256) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA)
|
||||
/* TODO: Add crypto callback API tests */
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#ifdef HAVE_ECC
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#endif
|
||||
|
||||
static int swdev_initialized = 0;
|
||||
|
||||
@@ -120,6 +123,62 @@ static int swdev_ecc_get_sig_size(wc_CryptoInfo* info)
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
#ifndef NO_SHA256
|
||||
/* Copy hash state between caller's wc_Sha256 and swdev's shadow, leaving
|
||||
* admin fields (heap, devId, devCtx, W, async, HW ctx) per-side. */
|
||||
static void swdev_sha256_copy_state(wc_Sha256* dst, const wc_Sha256* 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
|
||||
}
|
||||
|
||||
/* Run the op on a per-call shadow wc_Sha256 owned by swdev, copying state
|
||||
* in and out around it. The caller's struct, allocated by libwolfssl with
|
||||
* the software init stripped, can't be used directly. */
|
||||
static int swdev_sha256(wc_CryptoInfo* info)
|
||||
{
|
||||
wc_Sha256* sha256 = info->hash.sha256;
|
||||
wc_Sha256 shadow;
|
||||
int ret;
|
||||
|
||||
if (sha256 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ret = wc_InitSha256(&shadow);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
swdev_sha256_copy_state(&shadow, sha256);
|
||||
|
||||
if (info->hash.in != NULL) {
|
||||
ret = wc_Sha256Update(&shadow, info->hash.in, info->hash.inSz);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (info->hash.digest != NULL) {
|
||||
ret = wc_Sha256Final(&shadow, info->hash.digest);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
swdev_sha256_copy_state(sha256, &shadow);
|
||||
|
||||
out:
|
||||
wc_Sha256Free(&shadow);
|
||||
return ret;
|
||||
}
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
|
||||
void* ctx)
|
||||
{
|
||||
@@ -164,6 +223,15 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
|
||||
default:
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case WC_ALGO_TYPE_HASH:
|
||||
switch (info->hash.type) {
|
||||
case WC_HASH_TYPE_SHA256:
|
||||
return swdev_sha256(info);
|
||||
default:
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return CRYPTOCB_UNAVAILABLE;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#undef WOLF_CRYPTO_CB_ONLY_RSA
|
||||
#undef WOLF_CRYPTO_CB_ONLY_ECC
|
||||
#undef WOLF_CRYPTO_CB_ONLY_SHA256
|
||||
|
||||
#ifndef WOLF_CRYPTO_CB
|
||||
#error "wc_swdev requires the main build to define WOLF_CRYPTO_CB"
|
||||
|
||||
@@ -52,6 +52,7 @@ Crypto Callback Build Options:
|
||||
* and SHA-512 operations.
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
+74
-4
@@ -60,6 +60,10 @@ 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
|
||||
@@ -291,7 +295,8 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
|
||||
/* Hardware Acceleration */
|
||||
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
|
||||
(defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
|
||||
(defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
|
||||
/* in case intel instructions aren't available, plus we need the K[] global */
|
||||
#define NEED_SOFT_SHA256
|
||||
@@ -1084,7 +1089,7 @@ static int InitSha256(wc_Sha256* sha256)
|
||||
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
|
||||
|
||||
/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
|
||||
#elif defined(WOLFSSL_PPC32_ASM)
|
||||
#elif defined(WOLFSSL_PPC32_ASM) && !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
|
||||
extern void Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
|
||||
word32 len);
|
||||
@@ -1114,7 +1119,7 @@ static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
|
||||
#define XTRANSFORM Transform_Sha256
|
||||
#define XTRANSFORM_LEN Transform_Sha256_Len
|
||||
|
||||
#elif defined(WOLFSSL_ARMASM)
|
||||
#elif defined(WOLFSSL_ARMASM) && !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
|
||||
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
|
||||
{
|
||||
@@ -1169,6 +1174,21 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
|
||||
#define XTRANSFORM Transform_Sha256
|
||||
#define XTRANSFORM_LEN Transform_Sha256_Len
|
||||
|
||||
#elif defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
/* Software SHA-256 stripped; every op dispatches via cryptocb. */
|
||||
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
|
||||
{
|
||||
int ret;
|
||||
if (sha256 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
ret = InitSha256(sha256);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
sha256->heap = heap;
|
||||
sha256->devId = devId;
|
||||
sha256->devCtx = NULL;
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define NEED_SOFT_SHA256
|
||||
|
||||
@@ -1401,7 +1421,6 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
|
||||
#endif
|
||||
/* End wc_ software implementation */
|
||||
|
||||
|
||||
#ifdef XTRANSFORM
|
||||
|
||||
static WC_INLINE void AddLength(wc_Sha256* sha256, word32 len)
|
||||
@@ -1778,6 +1797,7 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
|
||||
|
||||
#if !defined(WOLFSSL_KCAPI_HASH)
|
||||
|
||||
#ifndef WOLFSSL_NO_HASH_RAW
|
||||
int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
|
||||
{
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
@@ -1801,6 +1821,7 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !WOLFSSL_NO_HASH_RAW */
|
||||
|
||||
int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
|
||||
{
|
||||
@@ -1964,6 +1985,55 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
|
||||
|
||||
#endif /* XTRANSFORM */
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
|
||||
|
||||
int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
|
||||
{
|
||||
if (sha256 == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (data == NULL && len == 0) {
|
||||
/* valid, but do nothing */
|
||||
return 0;
|
||||
}
|
||||
if (data == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (sha256->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
}
|
||||
|
||||
return NO_VALID_DEVID;
|
||||
}
|
||||
|
||||
int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sha256 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (sha256->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
}
|
||||
|
||||
return NO_VALID_DEVID;
|
||||
}
|
||||
|
||||
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_SHA224
|
||||
|
||||
|
||||
+65
-2
@@ -5968,7 +5968,8 @@ exit:
|
||||
#undef LARGE_HASH_TEST_INPUT_SZ
|
||||
#endif /* NO_LARGE_HASH_TEST */
|
||||
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH)
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
static wc_test_ret_t sha256_lms_test(wc_Sha256* sha)
|
||||
{
|
||||
byte hash[WC_SHA256_DIGEST_SIZE];
|
||||
@@ -6061,7 +6062,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha256_test(void)
|
||||
if ((ret = sha256_large_hash_test(&sha)) != 0)
|
||||
return ret;
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH)
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
if ((ret = sha256_lms_test(&sha)) != 0)
|
||||
return ret;
|
||||
#endif
|
||||
@@ -71320,6 +71322,52 @@ exit_onlycb:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
|
||||
/* Exercise SHA-256 dispatch under CB_ONLY_SHA256: cb-handled then cb-delegated. */
|
||||
static wc_test_ret_t sha256_onlycb_test(myCryptoDevCtx *ctx)
|
||||
{
|
||||
wc_test_ret_t ret = 0;
|
||||
#if !defined(NO_SHA256)
|
||||
wc_Sha256 sha;
|
||||
byte hash[WC_SHA256_DIGEST_SIZE];
|
||||
const byte in[] = "abc";
|
||||
|
||||
ret = wc_InitSha256_ex(&sha, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
/* cb handles the op, expects 0(success) */
|
||||
ctx->exampleVar = 99;
|
||||
ret = wc_Sha256Update(&sha, in, (word32)sizeof(in) - 1);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
|
||||
ret = wc_Sha256Final(&sha, hash);
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
|
||||
|
||||
/* cb delegates to software, expects NO_VALID_DEVID(failure) */
|
||||
ctx->exampleVar = 1;
|
||||
ret = wc_Sha256Update(&sha, in, (word32)sizeof(in) - 1);
|
||||
if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
ret = wc_Sha256Final(&sha, hash);
|
||||
if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
exit_onlycb:
|
||||
wc_Sha256Free(&sha);
|
||||
#endif /* !NO_SHA256 */
|
||||
(void)ctx;
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
|
||||
|
||||
/* Example crypto dev callback function that calls software version */
|
||||
static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
{
|
||||
@@ -72034,6 +72082,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
|
||||
/* set devId to invalid, so software is used */
|
||||
info->hash.sha256->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.sha256->devId = devIdArg;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (info->hash.in != NULL) {
|
||||
ret = wc_Sha256Update(
|
||||
@@ -73162,6 +73219,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
|
||||
ret = ecc_onlycb_test(&myCtx);
|
||||
PRIVATE_KEY_LOCK();
|
||||
#endif
|
||||
#if defined(WOLF_CRYPTO_CB_ONLY_SHA256) && !defined(WOLFSSL_SWDEV)
|
||||
PRIVATE_KEY_UNLOCK();
|
||||
if (ret == 0)
|
||||
ret = sha256_onlycb_test(&myCtx);
|
||||
PRIVATE_KEY_LOCK();
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_MLKEM
|
||||
if (ret == 0)
|
||||
ret = mlkem_test();
|
||||
|
||||
@@ -102,6 +102,12 @@
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
#endif
|
||||
|
||||
/* no raw hash access when software transform is stripped */
|
||||
#if defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
#undef WOLFSSL_NO_HASH_RAW
|
||||
#define WOLFSSL_NO_HASH_RAW
|
||||
#endif
|
||||
|
||||
#define SHA256_NOINLINE WC_NO_INLINE
|
||||
|
||||
#if !defined(NO_OLD_SHA_NAMES)
|
||||
|
||||
Reference in New Issue
Block a user