Skip to content
Merged
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
7 changes: 5 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 @@ -111,9 +111,12 @@
{"name": "ed25519-no-curve25519",
"comment": "Same as ed25519 but with curve25519 off. curve25519 is the only other user of the ge/fe math, so without it the strip is complete and nothing must pull the math back in. The ed25519 entry above keeps curve25519 enabled, which leaves fe_operations.c compiled and would hide such a regression at link time.",
"configure": ["--disable-curve25519", "CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_ED25519"]},
{"name": "curve25519",
"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": ["CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_CURVE25519"]},
{"name": "all",
"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": ["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_ED25519"]}
"comment": "All seven 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": ["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_ED25519 -DWOLF_CRYPTO_CB_ONLY_CURVE25519"]}
]}
EOF
.github/scripts/parallel-make-check.py \
Expand Down
14 changes: 7 additions & 7 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -30160,7 +30160,8 @@ static int test_SSL_CIPHER_get_current_kx(void)
(!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_ED25519))
!defined(WOLF_CRYPTO_CB_ONLY_ED25519) && \
!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 @@ -31265,7 +31266,8 @@ static int test_wc_CryptoCb(void)
(!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_ED25519))
!defined(WOLF_CRYPTO_CB_ONLY_ED25519) && \
!defined(WOLF_CRYPTO_CB_ONLY_CURVE25519))
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \
(!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519))
int tlsVer;
Expand Down Expand Up @@ -37640,15 +37642,13 @@ TEST_CASE testCases[] = {
/* Can't memory test as client/server Asserts in thread. */
TEST_DECL(test_prioritize_psk),

/* test_wc_CryptoCb_registry is defined only inside the
* WOLF_CRYPTO_CB + HAVE_IO_TESTS_DEPENDENCIES block below; register it under
* the same condition so it is neither undeclared (when absent) nor
* defined-but-unused. */
/* Must match the guard on the definition of test_wc_CryptoCb_registry. */
#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_ED25519))
!defined(WOLF_CRYPTO_CB_ONLY_ED25519) && \
!defined(WOLF_CRYPTO_CB_ONLY_CURVE25519))
/* Can't memory test as client/server hangs. */
TEST_DECL(test_wc_CryptoCb_registry),
#endif
Expand Down
6 changes: 4 additions & 2 deletions tests/swdev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The switches it supports are:
| `WOLF_CRYPTO_CB_ONLY_SHA512` | software SHA-512 | SHA-512 via CryptoCb |
| `WOLF_CRYPTO_CB_ONLY_AES` | software AES | AES via CryptoCb |
| `WOLF_CRYPTO_CB_ONLY_ED25519` | software Ed25519 | Ed25519 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 @@ -57,7 +58,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 / Ed25519 software impl |
| PK -> RSA/ECC/Ed25519/X25519 software impl |
| HASH -> SHA-256 software impl |
| CIPHER -> AES (CBC/CTR/ECB/GCM/CCM) software impl |
| |
Expand All @@ -72,7 +73,8 @@ 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/SHA-512/AES/Ed25519 paths are gone.
set, so its software RSA/ECC/SHA-256/SHA-512/AES/Ed25519/X25519 paths
are gone.
2. **swdev** recompiles the same source set under
`tests/swdev/user_settings.h`, which `#undef`s every `_ONLY_*`
macro. swdev therefore contains the full software implementations.
Expand Down
31 changes: 30 additions & 1 deletion tests/swdev/swdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
#ifdef HAVE_ED25519
#include <wolfssl/wolfcrypt/ed25519.h>
#endif
#ifdef HAVE_CURVE25519
#include <wolfssl/wolfcrypt/curve25519.h>
#endif

static int swdev_initialized = 0;

Expand Down Expand Up @@ -318,6 +321,23 @@ static int swdev_ed25519_check_key(wc_CryptoInfo* info)
}
#endif /* HAVE_ED25519 */

#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 @@ -913,7 +933,8 @@ 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) || defined(HAVE_ED25519)
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_CURVE25519)
case WC_ALGO_TYPE_PK:
switch (info->pk.type) {
#ifndef NO_RSA
Expand Down Expand Up @@ -964,6 +985,14 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
case WC_PK_TYPE_ED25519_CHECK_KEY:
return swdev_ed25519_check_key(info);
#endif /* HAVE_ED25519 */
#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 @@ -28,6 +28,7 @@
#undef WOLF_CRYPTO_CB_ONLY_SHA512
#undef WOLF_CRYPTO_CB_ONLY_AES
#undef WOLF_CRYPTO_CB_ONLY_ED25519
#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 @@ -65,6 +65,7 @@ Crypto Callback Build Options:
* 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_ED25519: Use only callbacks for Ed25519 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 @@ -3157,7 +3157,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 @@ -76148,6 +76149,88 @@ static wc_test_ret_t ed25519_onlycb_test(myCryptoDevCtx *ctx)
}
#endif /* WOLF_CRYPTO_CB_ONLY_ED25519 */

#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 @@ -76543,6 +76626,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 @@ -76553,6 +76645,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 @@ -78860,10 +78961,17 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
ret = ed25519_onlycb_test(&myCtx);
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
11 changes: 6 additions & 5 deletions wolfssl/wolfcrypt/fe_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,15 @@
#define CURVED25519_ASM
#endif

/* curve25519 shares the ed25519 field math, and borrows the group math
* on some builds.
* For WOLF_CRYPTO_CB_ONLY_ED25519 to strip the fe/ge modules, ensure that
* curve25519 is disabled. */
/* curve25519 always uses its own field math, but on some builds it borrows
* ed25519's group math via WOLFSSL_CURVE25519_USE_ED25519 below. Under
* WOLF_CRYPTO_CB_ONLY_ED25519 ed25519's group math is removed. */
#if (defined(CURVED25519_ASM_64BIT) || defined(HAVE_ED25519)) && \
!defined(WOLFSSL_CURVE25519_BLINDING) && \
!defined(WOLFSSL_CURVE25519_NOT_USE_ED25519) && \
(!defined(WOLF_CRYPTO_CB_ONLY_ED25519) || defined(HAVE_CURVE25519))
(!defined(WOLF_CRYPTO_CB_ONLY_ED25519) || \
(defined(HAVE_CURVE25519) && \
!defined(WOLF_CRYPTO_CB_ONLY_CURVE25519)))
#undef WOLFSSL_CURVE25519_USE_ED25519
#define WOLFSSL_CURVE25519_USE_ED25519
#endif
Expand Down
Loading
Loading