Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions .github/workflows/cryptocb-only.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: cryptocb-only Tests

# START OF COMMON SECTION
Expand Down Expand Up @@ -200,8 +200,27 @@
"--enable-ocspstapling2", "--enable-dtls", "--enable-dtls13",
"--enable-tls13",
"CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_AES -DSWDEV_AES_ONLYECB"]},
{"name": "curve25519", "minutes": 2,
"comment": "WOLF_CRYPTO_CB_ONLY_CURVE25519: strips software X25519 (keygen/shared-secret); swdev provides the software path via cryptocb. Nonblock and async X25519 have no callback path and are left disabled.",
"configure": ["--enable-swdev", "--enable-cryptocb", "--enable-ecc",
"--enable-rsa", "--enable-dh", "--enable-aesgcm",
"--enable-aesccm", "--enable-aesctr", "--enable-aescfb",
"--enable-aeskeywrap", "--enable-aessiv", "--enable-aesofb",
"--enable-aesxts", "--enable-camellia", "--enable-chacha",
"--enable-poly1305", "--enable-sha", "--enable-sha3",
"--enable-shake128", "--enable-shake256", "--enable-blake2",
"--enable-blake2s", "--enable-hkdf", "--enable-hashdrbg",
"--enable-hashflags", "--enable-curve25519", "--enable-ed25519",
"--enable-curve448", "--enable-ed448", "--enable-mlkem",
"--enable-dilithium", "--enable-scrypt", "--enable-pwdbased",
"--enable-pkcs7", "--enable-pkcs12", "--enable-certgen",
"--enable-certreq", "--enable-certext", "--enable-keygen",
"--enable-asn=all", "--enable-cmac", "--enable-xchacha",
"--enable-crl", "--enable-ocsp", "--enable-ocspstapling",
"--enable-ocspstapling2", "--enable-dtls", "--enable-dtls13",
"--enable-tls13", "CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_CURVE25519"]},
{"name": "all", "minutes": 2,
"comment": "All five ONLY_* macros at once: every supported software primitive is stripped and dispatched through cryptocb. Catches any cross-algorithm call that a single-strip entry would still resolve via the remaining software paths.",
"comment": "All six ONLY_* macros at once: every supported software primitive is stripped and dispatched through cryptocb. Catches any cross-algorithm call that a single-strip entry would still resolve via the remaining software paths.",
"configure": ["--enable-swdev", "--enable-cryptocb", "--enable-ecc",
"--enable-rsa", "--enable-dh", "--enable-aesgcm",
"--enable-aesccm", "--enable-aesctr", "--enable-aescfb",
Expand All @@ -219,7 +238,7 @@
"--enable-crl", "--enable-ocsp", "--enable-ocspstapling",
"--enable-ocspstapling2", "--enable-dtls", "--enable-dtls13",
"--enable-tls13",
"CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_ECC -DWOLF_CRYPTO_CB_ONLY_RSA -DWOLF_CRYPTO_CB_ONLY_SHA256 -DWOLF_CRYPTO_CB_ONLY_SHA512 -DWOLF_CRYPTO_CB_ONLY_AES"]}
"CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_ECC -DWOLF_CRYPTO_CB_ONLY_RSA -DWOLF_CRYPTO_CB_ONLY_SHA256 -DWOLF_CRYPTO_CB_ONLY_SHA512 -DWOLF_CRYPTO_CB_ONLY_AES -DWOLF_CRYPTO_CB_ONLY_CURVE25519"]}
]
EOF
.github/scripts/parallel-make-check.py \
Expand Down
6 changes: 4 additions & 2 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -28757,7 +28757,8 @@ static int test_SSL_CIPHER_get_current_kx(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_SHA512))
!defined(WOLF_CRYPTO_CB_ONLY_SHA512) && \
!defined(WOLF_CRYPTO_CB_ONLY_CURVE25519))

static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer,
int* keyFormat)
Expand Down Expand Up @@ -29762,7 +29763,8 @@ static int test_wc_CryptoCb(void)
#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_SHA512))
!defined(WOLF_CRYPTO_CB_ONLY_SHA512) && \
!defined(WOLF_CRYPTO_CB_ONLY_CURVE25519))
/* TODO: Add crypto callback API tests */

#ifdef HAVE_IO_TESTS_DEPENDENCIES
Expand Down
11 changes: 6 additions & 5 deletions tests/swdev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ compiled separately from the main library, linked into the test
programs only, and exposes exactly two C symbols. **It is not a
production component and must not be linked into shipping binaries.**

The four switches it supports are:
The switches it supports are:

| Macro | Strips | Test target |
|--------------------------------|----------------|--------------------|
| `WOLF_CRYPTO_CB_ONLY_RSA` | software RSA | RSA via CryptoCb |
| `WOLF_CRYPTO_CB_ONLY_ECC` | software ECC | ECC via CryptoCb |
| `WOLF_CRYPTO_CB_ONLY_SHA256` | software SHA-256 | SHA-256 via CryptoCb |
| `WOLF_CRYPTO_CB_ONLY_AES` | software AES | AES via CryptoCb |
| `WOLF_CRYPTO_CB_ONLY_CURVE25519` | software X25519 | X25519 via CryptoCb |

When a test program calls e.g. `wc_AesCbcEncrypt()` against a libwolfssl
built with `-DWOLF_CRYPTO_CB_ONLY_AES`, the software AES path is gone;
Expand Down Expand Up @@ -55,7 +56,7 @@ internal copy of the AES code, and returns the result.
| wc_SwDev_Callback(devId, info, ctx) |
| - swdev_ensure_init() lazy wolfCrypt_Init |
| - switch (info->algo_type): |
| PK -> RSA / ECC software impl |
| PK -> RSA / ECC / X25519 software impl |
| HASH -> SHA-256 software impl |
| CIPHER -> AES (CBC/CTR/ECB/GCM/CCM) software impl |
| |
Expand All @@ -70,10 +71,10 @@ internal copy of the AES code, and returns the result.
The whole mechanism rests on compiling the wolfcrypt sources twice:

1. **libwolfssl** is built normally with the user's `_ONLY_*` flags
set, so its software RSA/ECC/SHA-256/AES paths are gone.
set, so its software RSA/ECC/SHA-256/AES/X25519 paths are gone.
2. **swdev** recompiles the same source set under
`tests/swdev/user_settings.h`, which `#undef`s all four `_ONLY_*`
macros. swdev therefore contains the full software implementations.
`tests/swdev/user_settings.h`, which `#undef`s every `_ONLY_*`
macro. swdev therefore contains the full software implementations.

To prevent symbol collisions when both are linked into the same test
binary, `tests/swdev/Makefile` does the following:
Expand Down
30 changes: 29 additions & 1 deletion tests/swdev/swdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
#ifndef NO_AES
#include <wolfssl/wolfcrypt/aes.h>
#endif
#ifdef HAVE_CURVE25519
#include <wolfssl/wolfcrypt/curve25519.h>
#endif

static int swdev_initialized = 0;

Expand Down Expand Up @@ -238,6 +241,23 @@ static int swdev_ecc_check_pub(wc_CryptoInfo* info)
#endif /* HAVE_ECC_CHECK_KEY */
#endif /* HAVE_ECC */

#ifdef HAVE_CURVE25519
static int swdev_curve25519_keygen(wc_CryptoInfo* info)
{
return wc_curve25519_make_key(info->pk.curve25519kg.rng,
info->pk.curve25519kg.size, info->pk.curve25519kg.key);
}

#ifdef HAVE_CURVE25519_SHARED_SECRET
static int swdev_curve25519(wc_CryptoInfo* info)
{
return wc_curve25519_shared_secret_ex(info->pk.curve25519.private_key,
info->pk.curve25519.public_key, info->pk.curve25519.out,
info->pk.curve25519.outlen, info->pk.curve25519.endian);
}
#endif /* HAVE_CURVE25519_SHARED_SECRET */
#endif /* HAVE_CURVE25519 */

#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. */
Expand Down Expand Up @@ -771,7 +791,7 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
return ret;

switch (info->algo_type) {
#if !defined(NO_RSA) || defined(HAVE_ECC)
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_CURVE25519)
case WC_ALGO_TYPE_PK:
switch (info->pk.type) {
#ifndef NO_RSA
Expand Down Expand Up @@ -802,6 +822,14 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
return swdev_ecc_check_pub(info);
#endif
#endif /* HAVE_ECC */
#ifdef HAVE_CURVE25519
case WC_PK_TYPE_CURVE25519_KEYGEN:
return swdev_curve25519_keygen(info);
#ifdef HAVE_CURVE25519_SHARED_SECRET
case WC_PK_TYPE_CURVE25519:
return swdev_curve25519(info);
#endif
#endif /* HAVE_CURVE25519 */
default:
return CRYPTOCB_UNAVAILABLE;
}
Expand Down
1 change: 1 addition & 0 deletions tests/swdev/user_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#undef WOLF_CRYPTO_CB_ONLY_SHA256
#undef WOLF_CRYPTO_CB_ONLY_SHA512
#undef WOLF_CRYPTO_CB_ONLY_AES
#undef WOLF_CRYPTO_CB_ONLY_CURVE25519

#ifndef WOLF_CRYPTO_CB
#error "wc_swdev requires the main build to define WOLF_CRYPTO_CB"
Expand Down
1 change: 1 addition & 0 deletions wolfcrypt/src/cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Crypto Callback Build Options:
* 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
* WOLF_CRYPTO_CB_ONLY_CURVE25519: Use only callbacks for X25519 default: off
*/

#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
Expand Down
20 changes: 18 additions & 2 deletions wolfcrypt/src/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,14 +563,21 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
return BAD_FUNC_ARG;

#ifdef WOLF_CRYPTO_CB
if (key->devId != INVALID_DEVID) {
#ifndef WOLF_CRYPTO_CB_FIND
if (key->devId != INVALID_DEVID)
#endif
{
ret = wc_CryptoCb_Curve25519Gen(rng, keysize, key);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
}
#endif

#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
/* software path stripped; callback is the only provider */
return NO_VALID_DEVID;
#else
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_X25519) && \
defined(WOLFSSL_ASYNC_CRYPT_SW)
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_X25519) {
Expand Down Expand Up @@ -614,6 +621,7 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
#endif /* !WOLFSSL_SE050 */

return ret;
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
}

#ifdef HAVE_CURVE25519_SHARED_SECRET
Expand Down Expand Up @@ -720,7 +728,10 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
#endif

#ifdef WOLF_CRYPTO_CB
if (private_key->devId != INVALID_DEVID) {
#ifndef WOLF_CRYPTO_CB_FIND
if (private_key->devId != INVALID_DEVID)
#endif
{
ret = wc_CryptoCb_Curve25519(private_key, public_key, out, outlen,
endian);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
Expand All @@ -729,6 +740,10 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
}
#endif

#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
/* software path stripped; callback is the only provider */
return NO_VALID_DEVID;
#else
#ifdef WC_X25519_NONBLOCK

#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_X25519) && \
Expand Down Expand Up @@ -814,6 +829,7 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
}

return ret;
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
}

#endif /* HAVE_CURVE25519_SHARED_SECRET */
Expand Down
112 changes: 110 additions & 2 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3105,7 +3105,8 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
TEST_PASS("FLATTEN ALT NAMES test passed!\n");
#endif

#ifdef HAVE_CURVE25519
#if defined(HAVE_CURVE25519) && \
(!defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) || defined(WOLFSSL_SWDEV))
if ( (ret = curve25519_test()) != 0)
TEST_FAIL("CURVE25519 test failed!\n", ret);
else
Expand Down Expand Up @@ -73202,6 +73203,88 @@ static wc_test_ret_t aes_onlycb_test(myCryptoDevCtx *ctx)
}
#endif /* WOLF_CRYPTO_CB_ONLY_AES */

#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
/* Exercise Curve25519 dispatch under CB_ONLY_CURVE25519: cb-handled then
* cb-delegated. */
static wc_test_ret_t curve25519_onlycb_test(myCryptoDevCtx *ctx)
{
wc_test_ret_t ret = 0;
curve25519_key key;
#if defined(HAVE_CURVE25519_SHARED_SECRET) && \
defined(HAVE_CURVE25519_KEY_IMPORT)
curve25519_key pubKey;
const byte priv[CURVE25519_KEYSIZE] = {1};
const byte pub[CURVE25519_KEYSIZE] = {9};
byte out[CURVE25519_KEYSIZE];
word32 outLen = (word32)sizeof(out);
#endif
WC_RNG rng;

ret = wc_curve25519_init_ex(&key, HEAP_HINT, devId);
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

ret = wc_InitRng(&rng);
if (ret != 0) {
wc_curve25519_free(&key);
return WC_TEST_RET_ENC_EC(ret);
}

/* cb handles the op, expects 0(success) */
ctx->exampleVar = 99;
ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key);
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_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key);
if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);
} else {
ret = 0;
}

#if defined(HAVE_CURVE25519_SHARED_SECRET) && \
defined(HAVE_CURVE25519_KEY_IMPORT)
ret = wc_curve25519_init_ex(&pubKey, HEAP_HINT, devId);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb);

ret = wc_curve25519_import_private(priv, sizeof(priv), &key);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb_pub);
ret = wc_curve25519_import_public(pub, sizeof(pub), &pubKey);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb_pub);

/* cb handles the op, expects 0(success) */
ctx->exampleVar = 99;
ret = wc_curve25519_shared_secret(&key, &pubKey, out, &outLen);
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb_pub);

/* cb delegates to software, expects NO_VALID_DEVID(failure) */
ctx->exampleVar = 1;
ret = wc_curve25519_shared_secret(&key, &pubKey, out, &outLen);
if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb_pub);
} else {
ret = 0;
}

exit_onlycb_pub:
wc_curve25519_free(&pubKey);
#endif /* HAVE_CURVE25519_SHARED_SECRET && HAVE_CURVE25519_KEY_IMPORT */

exit_onlycb:
wc_FreeRng(&rng);
wc_curve25519_free(&key);
(void)ctx;
return ret;
}
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */

#if defined(HAVE_ECC) && !defined(WOLFSSL_NO_MALLOC) && \
defined(HAVE_ECC_KEY_EXPORT)
/* Serialize pub to X9.63 uncompressed (0x04 || X || Y) using the curve size
Expand Down Expand Up @@ -73597,6 +73680,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
if (info->pk.type == WC_PK_TYPE_CURVE25519_KEYGEN) {
/* set devId to invalid, so software is used */
info->pk.curve25519kg.key->devId = INVALID_DEVID;
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519)
#ifdef DEBUG_WOLFSSL
printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar);
#endif
if (myCtx->exampleVar == 99) {
info->pk.curve25519kg.key->devId = devIdArg;
return 0;
}
#endif

ret = wc_curve25519_make_key(info->pk.curve25519kg.rng,
info->pk.curve25519kg.size, info->pk.curve25519kg.key);
Expand All @@ -73607,6 +73699,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
else if (info->pk.type == WC_PK_TYPE_CURVE25519) {
/* set devId to invalid, so software is used */
info->pk.curve25519.private_key->devId = INVALID_DEVID;
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519)
#ifdef DEBUG_WOLFSSL
printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar);
#endif
if (myCtx->exampleVar == 99) {
info->pk.curve25519.private_key->devId = devIdArg;
return 0;
}
#endif

ret = wc_curve25519_shared_secret_ex(
info->pk.curve25519.private_key, info->pk.curve25519.public_key,
Expand Down Expand Up @@ -75710,10 +75811,17 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
ret = ed25519_test();
PRIVATE_KEY_LOCK();
#endif
#ifdef HAVE_CURVE25519
#if defined(HAVE_CURVE25519) && \
(!defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) || defined(WOLFSSL_SWDEV))
if (ret == 0)
ret = curve25519_test();
#endif
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && !defined(WOLFSSL_SWDEV)
PRIVATE_KEY_UNLOCK();
if (ret == 0)
ret = curve25519_onlycb_test(&myCtx);
PRIVATE_KEY_LOCK();
#endif
#if !defined(NO_AES) && !defined(WOLF_CRYPTO_CB_ONLY_AES)
/* CB_ONLY_AES skips these (aes_onlycb_test covers that path). */
#ifdef HAVE_AESGCM
Expand Down
Loading
Loading