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
Expand Up @@ -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",
Expand All @@ -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 \
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_ED25519))

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_ED25519))
/* TODO: Add crypto callback API tests */

#ifdef HAVE_IO_TESTS_DEPENDENCIES
Expand Down
12 changes: 7 additions & 5 deletions tests/swdev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 |
| |
Expand All @@ -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:
Expand Down
51 changes: 50 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_ED25519
#include <wolfssl/wolfcrypt/ed25519.h>
#endif

static int swdev_initialized = 0;

Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
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_ED25519

#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_ED25519: Use only callbacks for Ed25519 default: off
*/

#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
Expand Down
74 changes: 68 additions & 6 deletions wolfcrypt/src/ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,20 @@ 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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semi-related change to add these missing guards. The cb find mechanism would have failed here.

if (key->devId != INVALID_DEVID)
#endif
{
ret = wc_CryptoCb_Ed25519Gen(rng, keySz, key);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
}
#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;
Expand All @@ -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 */

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Comment on lines +636 to +637

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me it looks like that the priv check must be inside the software blocks, not outside. So this is a bug that predate the PR. Probably a good idea to move it inside that software block instead of gating on !ONLY_ED25519, or just ignore it in this PR.

if (ret == 0) {
int i;
byte c = 0;
Expand Down Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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;
Expand All @@ -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))
Expand Down
Loading
Loading