From 37b0c370b7eaebd1a5cd307b45f83fa2c3c2d99f Mon Sep 17 00:00:00 2001 From: Paul Adelsbach Date: Wed, 1 Jul 2026 11:22:14 -0700 Subject: [PATCH 1/2] Add crypto callback only mode for ed25519 --- .github/workflows/cryptocb-only.yml | 23 ++++++++- tests/swdev/README.md | 12 +++-- tests/swdev/swdev.c | 51 +++++++++++++++++++- tests/swdev/user_settings.h | 1 + wolfcrypt/src/cryptocb.c | 1 + wolfcrypt/src/ed25519.c | 74 ++++++++++++++++++++++++++--- wolfssl/wolfcrypt/settings.h | 19 ++++++++ 7 files changed, 167 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cryptocb-only.yml b/.github/workflows/cryptocb-only.yml index 9b5c89591b5..75b323f8788 100644 --- a/.github/workflows/cryptocb-only.yml +++ b/.github/workflows/cryptocb-only.yml @@ -200,8 +200,27 @@ jobs: "--enable-ocspstapling2", "--enable-dtls", "--enable-dtls13", "--enable-tls13", "CPPFLAGS=-DWOLF_CRYPTO_CB_ONLY_AES -DSWDEV_AES_ONLYECB"]}, + {"name": "ed25519", "minutes": 2, + "comment": "WOLF_CRYPTO_CB_ONLY_ED25519: strips software Ed25519 (keygen/sign/verify); swdev provides the software path via cryptocb. Streaming verify has no callback path and is 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_ED25519"]}, {"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", @@ -219,7 +238,7 @@ jobs: "--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_ED25519"]} ] EOF .github/scripts/parallel-make-check.py \ diff --git a/tests/swdev/README.md b/tests/swdev/README.md index eedbe1e5a10..0cf5ce2fded 100644 --- a/tests/swdev/README.md +++ b/tests/swdev/README.md @@ -6,14 +6,16 @@ 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_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 | 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; @@ -55,7 +57,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 / Ed25519 software impl | | HASH -> SHA-256 software impl | | CIPHER -> AES (CBC/CTR/ECB/GCM/CCM) software impl | | | @@ -70,10 +72,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/SHA-512/AES/Ed25519 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: diff --git a/tests/swdev/swdev.c b/tests/swdev/swdev.c index 92ae08cec1f..bd8f56362fd 100644 --- a/tests/swdev/swdev.c +++ b/tests/swdev/swdev.c @@ -40,6 +40,9 @@ #ifndef NO_AES #include #endif +#ifdef HAVE_ED25519 +#include +#endif static int swdev_initialized = 0; @@ -238,6 +241,38 @@ static int swdev_ecc_check_pub(wc_CryptoInfo* info) #endif /* HAVE_ECC_CHECK_KEY */ #endif /* HAVE_ECC */ +#ifdef HAVE_ED25519 +#ifdef HAVE_ED25519_MAKE_KEY +static int swdev_ed25519_keygen(wc_CryptoInfo* info) +{ + return wc_ed25519_make_key(info->pk.ed25519kg.rng, + info->pk.ed25519kg.size, info->pk.ed25519kg.key); +} +#endif + +#ifdef HAVE_ED25519_SIGN +static int swdev_ed25519_sign(wc_CryptoInfo* info) +{ + return wc_ed25519_sign_msg_ex(info->pk.ed25519sign.in, + info->pk.ed25519sign.inLen, info->pk.ed25519sign.out, + info->pk.ed25519sign.outLen, info->pk.ed25519sign.key, + info->pk.ed25519sign.type, info->pk.ed25519sign.context, + info->pk.ed25519sign.contextLen); +} +#endif + +#ifdef HAVE_ED25519_VERIFY +static int swdev_ed25519_verify(wc_CryptoInfo* info) +{ + return wc_ed25519_verify_msg_ex(info->pk.ed25519verify.sig, + info->pk.ed25519verify.sigLen, info->pk.ed25519verify.msg, + info->pk.ed25519verify.msgLen, info->pk.ed25519verify.res, + info->pk.ed25519verify.key, info->pk.ed25519verify.type, + info->pk.ed25519verify.context, info->pk.ed25519verify.contextLen); +} +#endif +#endif /* HAVE_ED25519 */ + #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. */ @@ -771,7 +806,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_ED25519) case WC_ALGO_TYPE_PK: switch (info->pk.type) { #ifndef NO_RSA @@ -802,6 +837,20 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info, return swdev_ecc_check_pub(info); #endif #endif /* HAVE_ECC */ + #ifdef HAVE_ED25519 + #ifdef HAVE_ED25519_MAKE_KEY + case WC_PK_TYPE_ED25519_KEYGEN: + return swdev_ed25519_keygen(info); + #endif + #ifdef HAVE_ED25519_SIGN + case WC_PK_TYPE_ED25519_SIGN: + return swdev_ed25519_sign(info); + #endif + #ifdef HAVE_ED25519_VERIFY + case WC_PK_TYPE_ED25519_VERIFY: + return swdev_ed25519_verify(info); + #endif + #endif /* HAVE_ED25519 */ default: return CRYPTOCB_UNAVAILABLE; } diff --git a/tests/swdev/user_settings.h b/tests/swdev/user_settings.h index c04f056b02f..46076d50070 100644 --- a/tests/swdev/user_settings.h +++ b/tests/swdev/user_settings.h @@ -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_ED25519 #ifndef WOLF_CRYPTO_CB #error "wc_swdev requires the main build to define WOLF_CRYPTO_CB" diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 9a27fab4820..562e287f416 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -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_ED25519: Use only callbacks for Ed25519 default: off */ #include diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 3cf8d807fec..7417873de16 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -376,7 +376,10 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) key->pubKeySet = 0; #ifdef WOLF_CRYPTO_CB - if (key->devId != INVALID_DEVID) { + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { ret = wc_CryptoCb_Ed25519Gen(rng, keySz, key); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; @@ -384,6 +387,9 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) } #endif +#ifdef WOLF_CRYPTO_CB_ONLY_ED25519 + return NO_VALID_DEVID; +#else ret = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE); if (ret != 0) return ret; @@ -407,6 +413,7 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) #endif return ret; +#endif /* WOLF_CRYPTO_CB_ONLY_ED25519 */ } #endif /* HAVE_ED25519_MAKE_KEY */ @@ -434,6 +441,30 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, (void)contextLen; (void)type; ret = se050_ed25519_sign_msg(in, inLen, out, outLen, key); +#elif defined(WOLF_CRYPTO_CB_ONLY_ED25519) + ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + + if (in == NULL || out == NULL || outLen == NULL || key == NULL || + (context == NULL && contextLen != 0)) { + return BAD_FUNC_ARG; + } + + if ((type == Ed25519ph) && + (inLen != WC_SHA512_DIGEST_SIZE)) + { + return BAD_LENGTH_E; + } + + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Ed25519Sign(in, inLen, out, outLen, key, type, + context, contextLen); + } + if (ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + ret = NO_VALID_DEVID; + } #else #ifdef FREESCALE_LTC_ECC ALIGN16 byte tempBuf[ED25519_PRV_KEY_SIZE]; @@ -461,7 +492,10 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, } #ifdef WOLF_CRYPTO_CB - if (key->devId != INVALID_DEVID) { + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { ret = wc_CryptoCb_Ed25519Sign(in, inLen, out, outLen, key, type, context, contextLen); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) @@ -599,7 +633,8 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out, ForceZero(nonce, sizeof(nonce)); #endif /* WOLFSSL_SE050 */ -#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN +#if defined(WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN) && \ + !defined(WOLF_CRYPTO_CB_ONLY_ED25519) if (ret == 0) { int i; byte c = 0; @@ -696,7 +731,7 @@ int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out, #endif /* HAVE_ED25519_SIGN */ #ifdef HAVE_ED25519_VERIFY -#ifndef WOLFSSL_SE050 +#if !defined(WOLFSSL_SE050) && !defined(WOLF_CRYPTO_CB_ONLY_ED25519) #ifdef WOLFSSL_CHECK_VER_FAULTS static const byte sha512_empty[] = { @@ -928,7 +963,7 @@ static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen, return ret; } -#endif /* WOLFSSL_SE050 */ +#endif /* !WOLFSSL_SE050 && !WOLF_CRYPTO_CB_ONLY_ED25519 */ #if defined(WOLFSSL_ED25519_STREAMING_VERIFY) && !defined(WOLFSSL_SE050) @@ -972,6 +1007,30 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg, (void)contextLen; (void)ed25519Ctx; ret = se050_ed25519_verify_msg(sig, sigLen, msg, msgLen, key, res); +#elif defined(WOLF_CRYPTO_CB_ONLY_ED25519) + (void)ed25519Ctx; + ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + + if (sig == NULL || msg == NULL || res == NULL || key == NULL || + (context == NULL && contextLen != 0)) + return BAD_FUNC_ARG; + + if ((type == Ed25519ph) && + (msgLen != WC_SHA512_DIGEST_SIZE)) + { + return BAD_LENGTH_E; + } + + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_Ed25519Verify(sig, sigLen, msg, msgLen, res, key, + type, context, contextLen); + } + if (ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + ret = NO_VALID_DEVID; + } #else #ifdef WOLFSSL_ED25519_PERSISTENT_SHA wc_Sha512 *sha; @@ -991,7 +1050,10 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg, } #ifdef WOLF_CRYPTO_CB - if (key->devId != INVALID_DEVID) { + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { ret = wc_CryptoCb_Ed25519Verify(sig, sigLen, msg, msgLen, res, key, type, context, contextLen); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index aeb81cc35e4..52858cea7ae 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -5536,6 +5536,25 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS." #if defined(WOLF_CRYPTO_CB_ONLY_AES) && !defined(WOLF_CRYPTO_CB) #error "WOLF_CRYPTO_CB_ONLY_AES requires WOLF_CRYPTO_CB" #endif +#if defined(WOLF_CRYPTO_CB_ONLY_ED25519) && !defined(WOLF_CRYPTO_CB) + #error "WOLF_CRYPTO_CB_ONLY_ED25519 requires WOLF_CRYPTO_CB" +#endif +#if defined(WOLF_CRYPTO_CB_ONLY_ED25519) && !defined(HAVE_ED25519) + #error "WOLF_CRYPTO_CB_ONLY_ED25519 requires HAVE_ED25519" +#endif +/* Software Ed25519 is stripped, so no in-tree Ed25519 backend may be present + * and the streaming verify API (which has no callback path) must be off. */ +#if defined(WOLF_CRYPTO_CB_ONLY_ED25519) && defined(WOLFSSL_SE050) + #error "WOLF_CRYPTO_CB_ONLY_ED25519 is incompatible with WOLFSSL_SE050" +#endif +#if defined(WOLF_CRYPTO_CB_ONLY_ED25519) && defined(HAVE_FIPS) + #error "WOLF_CRYPTO_CB_ONLY_ED25519 is incompatible with FIPS builds" +#endif +#if defined(WOLF_CRYPTO_CB_ONLY_ED25519) && \ + defined(WOLFSSL_ED25519_STREAMING_VERIFY) + #error "WOLF_CRYPTO_CB_ONLY_ED25519 is incompatible with " \ + "WOLFSSL_ED25519_STREAMING_VERIFY" +#endif /* Early Data / Session Rules */ #if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_EARLY_DATA) && \ From 67cd0ad3305fce51324f439cdd95992dd170ebd6 Mon Sep 17 00:00:00 2001 From: Paul Adelsbach Date: Mon, 6 Jul 2026 10:01:54 -0700 Subject: [PATCH 2/2] Add missing checks for WOLF_CRYPTO_CB_ONLY_ED25519, add test case for no swdev --- tests/api.c | 6 +- wolfcrypt/test/test.c | 142 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 4 deletions(-) diff --git a/tests/api.c b/tests/api.c index 3d651b185d5..3401957edb6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -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_ED25519)) static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer, int* keyFormat) @@ -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_ED25519)) /* TODO: Add crypto callback API tests */ #ifdef HAVE_IO_TESTS_DEPENDENCIES diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 66bcfef3916..fa87aba376d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -3112,7 +3112,8 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ TEST_PASS("CURVE25519 test passed!\n"); #endif -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && \ + (!defined(WOLF_CRYPTO_CB_ONLY_ED25519) || defined(WOLFSSL_SWDEV)) PRIVATE_KEY_UNLOCK(); if ( (ret = ed25519_test()) != 0) TEST_FAIL("ED25519 test failed!\n", ret); @@ -73202,6 +73203,109 @@ static wc_test_ret_t aes_onlycb_test(myCryptoDevCtx *ctx) } #endif /* WOLF_CRYPTO_CB_ONLY_AES */ +#ifdef WOLF_CRYPTO_CB_ONLY_ED25519 +/* Exercise Ed25519 dispatch under CB_ONLY_ED25519: cb-handled then + * cb-delegated. */ +static wc_test_ret_t ed25519_onlycb_test(myCryptoDevCtx *ctx) +{ + wc_test_ret_t ret = 0; + ed25519_key key; +#if defined(HAVE_ED25519_SIGN) || defined(HAVE_ED25519_VERIFY) + byte sig[ED25519_SIG_SIZE]; + const byte msg[] = "abc"; +#endif +#ifdef HAVE_ED25519_SIGN + word32 sigLen = (word32)sizeof(sig); +#endif +#ifdef HAVE_ED25519_VERIFY + int res = 0; +#endif +#ifdef HAVE_ED25519_MAKE_KEY + WC_RNG rng; +#endif + +#if defined(HAVE_ED25519_SIGN) || defined(HAVE_ED25519_VERIFY) + XMEMSET(sig, 0, sizeof(sig)); +#endif + + ret = wc_ed25519_init_ex(&key, HEAP_HINT, devId); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + +#ifdef HAVE_ED25519_MAKE_KEY + ret = wc_InitRng(&rng); + if (ret != 0) { + wc_ed25519_free(&key); + return WC_TEST_RET_ENC_EC(ret); + } + + /* cb handles the op, expects 0(success) */ + ctx->exampleVar = 99; + ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &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_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key); + if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) { + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb); + } else { + ret = 0; + } +#endif /* HAVE_ED25519_MAKE_KEY */ + +#ifdef HAVE_ED25519_SIGN + /* cb handles the op, expects 0(success) */ + ctx->exampleVar = 99; + ret = wc_ed25519_sign_msg(msg, (word32)sizeof(msg) - 1, sig, &sigLen, + &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_ed25519_sign_msg(msg, (word32)sizeof(msg) - 1, sig, &sigLen, + &key); + if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) { + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb); + } else { + ret = 0; + } +#endif /* HAVE_ED25519_SIGN */ + +#ifdef HAVE_ED25519_VERIFY + /* cb handles the op, expects 0(success) */ + ctx->exampleVar = 99; + ret = wc_ed25519_verify_msg(sig, (word32)sizeof(sig), msg, + (word32)sizeof(msg) - 1, &res, &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_ed25519_verify_msg(sig, (word32)sizeof(sig), msg, + (word32)sizeof(msg) - 1, &res, &key); + if (ret != WC_NO_ERR_TRACE(NO_VALID_DEVID)) { + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_onlycb); + } else { + ret = 0; + } +#endif /* HAVE_ED25519_VERIFY */ + +#if defined(HAVE_ED25519_MAKE_KEY) || defined(HAVE_ED25519_SIGN) || \ + defined(HAVE_ED25519_VERIFY) +exit_onlycb: +#endif +#ifdef HAVE_ED25519_MAKE_KEY + wc_FreeRng(&rng); +#endif + wc_ed25519_free(&key); + (void)ctx; + return ret; +} +#endif /* WOLF_CRYPTO_CB_ONLY_ED25519 */ + #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 @@ -73621,6 +73725,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) if (info->pk.type == WC_PK_TYPE_ED25519_KEYGEN) { /* set devId to invalid, so software is used */ info->pk.ed25519kg.key->devId = INVALID_DEVID; + #if defined(WOLF_CRYPTO_CB_ONLY_ED25519) + #ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar); + #endif + if (myCtx->exampleVar == 99) { + info->pk.ed25519kg.key->devId = devIdArg; + return 0; + } + #endif ret = wc_ed25519_make_key(info->pk.ed25519kg.rng, info->pk.ed25519kg.size, info->pk.ed25519kg.key); @@ -73632,6 +73745,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) else if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) { /* set devId to invalid, so software is used */ info->pk.ed25519sign.key->devId = INVALID_DEVID; + #if defined(WOLF_CRYPTO_CB_ONLY_ED25519) + #ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar); + #endif + if (myCtx->exampleVar == 99) { + info->pk.ed25519sign.key->devId = devIdArg; + return 0; + } + #endif ret = wc_ed25519_sign_msg_ex( info->pk.ed25519sign.in, info->pk.ed25519sign.inLen, @@ -73647,6 +73769,15 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) else if (info->pk.type == WC_PK_TYPE_ED25519_VERIFY) { /* set devId to invalid, so software is used */ info->pk.ed25519verify.key->devId = INVALID_DEVID; + #if defined(WOLF_CRYPTO_CB_ONLY_ED25519) + #ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: exampleVar %d\n", myCtx->exampleVar); + #endif + if (myCtx->exampleVar == 99) { + info->pk.ed25519verify.key->devId = devIdArg; + return 0; + } + #endif ret = wc_ed25519_verify_msg_ex( info->pk.ed25519verify.sig, info->pk.ed25519verify.sigLen, @@ -75704,12 +75835,19 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void) if (ret == 0) ret = lms_test(); #endif -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) && \ + (!defined(WOLF_CRYPTO_CB_ONLY_ED25519) || defined(WOLFSSL_SWDEV)) PRIVATE_KEY_UNLOCK(); if (ret == 0) ret = ed25519_test(); PRIVATE_KEY_LOCK(); #endif +#if defined(WOLF_CRYPTO_CB_ONLY_ED25519) && !defined(WOLFSSL_SWDEV) + PRIVATE_KEY_UNLOCK(); + if (ret == 0) + ret = ed25519_onlycb_test(&myCtx); + PRIVATE_KEY_LOCK(); +#endif #ifdef HAVE_CURVE25519 if (ret == 0) ret = curve25519_test();