Skip to content

Commit d4e2e43

Browse files
committed
Add crypto callback only mode for curve25519
1 parent e79c581 commit d4e2e43

7 files changed

Lines changed: 102 additions & 10 deletions

File tree

.github/workflows/cryptocb-only.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,27 @@ jobs:
200200
"--enable-ocspstapling2", "--enable-dtls", "--enable-dtls13",
201201
"--enable-tls13",
202202
"CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_AES -DSWDEV_AES_ONLYECB"]},
203+
{"name": "curve25519", "minutes": 2,
204+
"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.",
205+
"configure": ["--enable-swdev", "--enable-cryptocb", "--enable-ecc",
206+
"--enable-rsa", "--enable-dh", "--enable-aesgcm",
207+
"--enable-aesccm", "--enable-aesctr", "--enable-aescfb",
208+
"--enable-aeskeywrap", "--enable-aessiv", "--enable-aesofb",
209+
"--enable-aesxts", "--enable-camellia", "--enable-chacha",
210+
"--enable-poly1305", "--enable-sha", "--enable-sha3",
211+
"--enable-shake128", "--enable-shake256", "--enable-blake2",
212+
"--enable-blake2s", "--enable-hkdf", "--enable-hashdrbg",
213+
"--enable-hashflags", "--enable-curve25519", "--enable-ed25519",
214+
"--enable-curve448", "--enable-ed448", "--enable-mlkem",
215+
"--enable-dilithium", "--enable-scrypt", "--enable-pwdbased",
216+
"--enable-pkcs7", "--enable-pkcs12", "--enable-certgen",
217+
"--enable-certreq", "--enable-certext", "--enable-keygen",
218+
"--enable-asn=all", "--enable-cmac", "--enable-xchacha",
219+
"--enable-crl", "--enable-ocsp", "--enable-ocspstapling",
220+
"--enable-ocspstapling2", "--enable-dtls", "--enable-dtls13",
221+
"--enable-tls13", "CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_CURVE25519"]},
203222
{"name": "all", "minutes": 2,
204-
"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.",
223+
"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.",
205224
"configure": ["--enable-swdev", "--enable-cryptocb", "--enable-ecc",
206225
"--enable-rsa", "--enable-dh", "--enable-aesgcm",
207226
"--enable-aesccm", "--enable-aesctr", "--enable-aescfb",
@@ -219,7 +238,7 @@ jobs:
219238
"--enable-crl", "--enable-ocsp", "--enable-ocspstapling",
220239
"--enable-ocspstapling2", "--enable-dtls", "--enable-dtls13",
221240
"--enable-tls13",
222-
"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"]}
241+
"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"]}
223242
]
224243
EOF
225244
.github/scripts/parallel-make-check.py \

tests/swdev/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ compiled separately from the main library, linked into the test
66
programs only, and exposes exactly two C symbols. **It is not a
77
production component and must not be linked into shipping binaries.**
88

9-
The four switches it supports are:
9+
The switches it supports are:
1010

1111
| Macro | Strips | Test target |
1212
|--------------------------------|----------------|--------------------|
1313
| `WOLF_CRYPTO_CB_ONLY_RSA` | software RSA | RSA via CryptoCb |
1414
| `WOLF_CRYPTO_CB_ONLY_ECC` | software ECC | ECC via CryptoCb |
1515
| `WOLF_CRYPTO_CB_ONLY_SHA256` | software SHA-256 | SHA-256 via CryptoCb |
1616
| `WOLF_CRYPTO_CB_ONLY_AES` | software AES | AES via CryptoCb |
17+
| `WOLF_CRYPTO_CB_ONLY_CURVE25519` | software X25519 | X25519 via CryptoCb |
1718

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

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

7879
To prevent symbol collisions when both are linked into the same test
7980
binary, `tests/swdev/Makefile` does the following:

tests/swdev/swdev.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
#ifndef NO_AES
4141
#include <wolfssl/wolfcrypt/aes.h>
4242
#endif
43+
#ifdef HAVE_CURVE25519
44+
#include <wolfssl/wolfcrypt/curve25519.h>
45+
#endif
4346

4447
static int swdev_initialized = 0;
4548

@@ -238,6 +241,23 @@ static int swdev_ecc_check_pub(wc_CryptoInfo* info)
238241
#endif /* HAVE_ECC_CHECK_KEY */
239242
#endif /* HAVE_ECC */
240243

244+
#ifdef HAVE_CURVE25519
245+
static int swdev_curve25519_keygen(wc_CryptoInfo* info)
246+
{
247+
return wc_curve25519_make_key(info->pk.curve25519kg.rng,
248+
info->pk.curve25519kg.size, info->pk.curve25519kg.key);
249+
}
250+
251+
#ifdef HAVE_CURVE25519_SHARED_SECRET
252+
static int swdev_curve25519(wc_CryptoInfo* info)
253+
{
254+
return wc_curve25519_shared_secret_ex(info->pk.curve25519.private_key,
255+
info->pk.curve25519.public_key, info->pk.curve25519.out,
256+
info->pk.curve25519.outlen, info->pk.curve25519.endian);
257+
}
258+
#endif /* HAVE_CURVE25519_SHARED_SECRET */
259+
#endif /* HAVE_CURVE25519 */
260+
241261
#ifndef NO_SHA256
242262
/* Copy hash state between caller's wc_Sha256 and swdev's shadow, leaving
243263
* admin fields (heap, devId, devCtx, W, async, HW ctx) per-side. */
@@ -771,7 +791,7 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
771791
return ret;
772792

773793
switch (info->algo_type) {
774-
#if !defined(NO_RSA) || defined(HAVE_ECC)
794+
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_CURVE25519)
775795
case WC_ALGO_TYPE_PK:
776796
switch (info->pk.type) {
777797
#ifndef NO_RSA
@@ -802,6 +822,14 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info,
802822
return swdev_ecc_check_pub(info);
803823
#endif
804824
#endif /* HAVE_ECC */
825+
#ifdef HAVE_CURVE25519
826+
case WC_PK_TYPE_CURVE25519_KEYGEN:
827+
return swdev_curve25519_keygen(info);
828+
#ifdef HAVE_CURVE25519_SHARED_SECRET
829+
case WC_PK_TYPE_CURVE25519:
830+
return swdev_curve25519(info);
831+
#endif
832+
#endif /* HAVE_CURVE25519 */
805833
default:
806834
return CRYPTOCB_UNAVAILABLE;
807835
}

tests/swdev/user_settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#undef WOLF_CRYPTO_CB_ONLY_SHA256
2828
#undef WOLF_CRYPTO_CB_ONLY_SHA512
2929
#undef WOLF_CRYPTO_CB_ONLY_AES
30+
#undef WOLF_CRYPTO_CB_ONLY_CURVE25519
3031

3132
#ifndef WOLF_CRYPTO_CB
3233
#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
@@ -64,6 +64,7 @@ Crypto Callback Build Options:
6464
* WOLF_CRYPTO_CB_ONLY_SHA256: Use only callbacks for SHA-256 default: off
6565
* WOLF_CRYPTO_CB_ONLY_SHA512: Use only callbacks for SHA-512 default: off
6666
* WOLF_CRYPTO_CB_ONLY_AES: Use only callbacks for AES default: off
67+
* WOLF_CRYPTO_CB_ONLY_CURVE25519: Use only callbacks for X25519 default: off
6768
*/
6869

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

wolfcrypt/src/curve25519.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,14 +563,21 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
563563
return BAD_FUNC_ARG;
564564

565565
#ifdef WOLF_CRYPTO_CB
566-
if (key->devId != INVALID_DEVID) {
566+
#ifndef WOLF_CRYPTO_CB_FIND
567+
if (key->devId != INVALID_DEVID)
568+
#endif
569+
{
567570
ret = wc_CryptoCb_Curve25519Gen(rng, keysize, key);
568571
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
569572
return ret;
570573
/* fall-through when unavailable */
571574
}
572575
#endif
573576

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

616623
return ret;
624+
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
617625
}
618626

619627
#ifdef HAVE_CURVE25519_SHARED_SECRET
@@ -720,7 +728,10 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
720728
#endif
721729

722730
#ifdef WOLF_CRYPTO_CB
723-
if (private_key->devId != INVALID_DEVID) {
731+
#ifndef WOLF_CRYPTO_CB_FIND
732+
if (private_key->devId != INVALID_DEVID)
733+
#endif
734+
{
724735
ret = wc_CryptoCb_Curve25519(private_key, public_key, out, outlen,
725736
endian);
726737
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
@@ -729,6 +740,10 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
729740
}
730741
#endif
731742

743+
#ifdef WOLF_CRYPTO_CB_ONLY_CURVE25519
744+
/* software path stripped; callback is the only provider */
745+
return NO_VALID_DEVID;
746+
#else
732747
#ifdef WC_X25519_NONBLOCK
733748

734749
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_X25519) && \
@@ -814,6 +829,7 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
814829
}
815830

816831
return ret;
832+
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE25519 */
817833
}
818834

819835
#endif /* HAVE_CURVE25519_SHARED_SECRET */

wolfssl/wolfcrypt/settings.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5536,6 +5536,32 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS."
55365536
#if defined(WOLF_CRYPTO_CB_ONLY_AES) && !defined(WOLF_CRYPTO_CB)
55375537
#error "WOLF_CRYPTO_CB_ONLY_AES requires WOLF_CRYPTO_CB"
55385538
#endif
5539+
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && !defined(WOLF_CRYPTO_CB)
5540+
#error "WOLF_CRYPTO_CB_ONLY_CURVE25519 requires WOLF_CRYPTO_CB"
5541+
#endif
5542+
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && !defined(HAVE_CURVE25519)
5543+
#error "WOLF_CRYPTO_CB_ONLY_CURVE25519 requires HAVE_CURVE25519"
5544+
#endif
5545+
/* Software X25519 is stripped, so no in-tree hardware backend may be present
5546+
* and the nonblock/async paths (which have no callback path) must be off. */
5547+
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && defined(WOLFSSL_SE050)
5548+
#error "WOLF_CRYPTO_CB_ONLY_CURVE25519 is incompatible with WOLFSSL_SE050"
5549+
#endif
5550+
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && defined(FREESCALE_LTC_ECC)
5551+
#error "WOLF_CRYPTO_CB_ONLY_CURVE25519 is incompatible with " \
5552+
"FREESCALE_LTC_ECC"
5553+
#endif
5554+
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && defined(HAVE_FIPS)
5555+
#error "WOLF_CRYPTO_CB_ONLY_CURVE25519 is incompatible with FIPS builds"
5556+
#endif
5557+
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && defined(WC_X25519_NONBLOCK)
5558+
#error "WOLF_CRYPTO_CB_ONLY_CURVE25519 is incompatible with " \
5559+
"WC_X25519_NONBLOCK"
5560+
#endif
5561+
#if defined(WOLF_CRYPTO_CB_ONLY_CURVE25519) && defined(WC_ASYNC_ENABLE_X25519)
5562+
#error "WOLF_CRYPTO_CB_ONLY_CURVE25519 is incompatible with " \
5563+
"WC_ASYNC_ENABLE_X25519"
5564+
#endif
55395565

55405566
/* Early Data / Session Rules */
55415567
#if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_EARLY_DATA) && \

0 commit comments

Comments
 (0)