Skip to content

Add more ECX tests, fix minor issues #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
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
19 changes: 11 additions & 8 deletions src/wp_ecx_kmgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ typedef int (*WP_ECX_CHECK_KEY)(void* key);
typedef struct wp_EcxData {
/** Type of key. */
int keyType;
/** Number of bits in curve. */
/** Cryptographic length in bits. */
int bits;
/** Length of curve in bytes. */
int len;
Expand Down Expand Up @@ -193,6 +193,7 @@ typedef struct wp_EcxGenCtx {

/* Prototype for ECX generation initialization. */
static int wp_ecx_gen_set_params(wp_EcxGenCtx* ctx, const OSSL_PARAM params[]);
static size_t wp_ecx_export_keypair_alloc_size(wp_Ecx* ecx, int priv);

/*
* ECX key
Expand Down Expand Up @@ -455,10 +456,10 @@ static int wp_ecx_get_security_bits(wp_Ecx* ecx)
{
int bits = 0;

if (ecx->data->bits >= 448) {
bits = 192;
if (ecx->data->bits >= 456) {
bits = 224;
}
else if (ecx->data->bits >= 255) {
else if (ecx->data->bits >= 256) {
bits = 128;
}

Expand Down Expand Up @@ -548,8 +549,10 @@ static int wp_ecx_get_params(wp_Ecx* ecx, OSSL_PARAM params[])
OSSL_PARAM* p;

p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE);
if ((p != NULL) && !OSSL_PARAM_set_int(p, ecx->data->len)) {
ok = 0;
if (p != NULL) {
if (!OSSL_PARAM_set_int(p, (int)wp_ecx_export_keypair_alloc_size(ecx, 1))) {
ok = 0;
}
}
if (ok) {
p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS);
Expand Down Expand Up @@ -1540,7 +1543,7 @@ static int wp_ed25519_import_private(const byte* in, word32 inLen,
/** Ed25519 data and wolfSSL functions. */
static const wp_EcxData ed25519Data = {
WP_KEY_TYPE_ED25519,
255,
ED25519_KEY_SIZE * 8,
ED25519_KEY_SIZE,

(WP_ECX_INIT)&wc_ed25519_init,
Expand Down Expand Up @@ -1674,7 +1677,7 @@ static int wp_ed448_import_private(const byte* in, word32 inLen,
/** Ed448 data and wolfSSL functions. */
static const wp_EcxData ed448Data = {
WP_KEY_TYPE_ED448,
448,
ED448_KEY_SIZE * 8,
ED448_KEY_SIZE,

(WP_ECX_INIT)&wc_ed448_init,
Expand Down
242 changes: 228 additions & 14 deletions test/test_ecx.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,17 @@
#include <openssl/store.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/wolfcrypt/ed448.h>

#if defined(WP_HAVE_ED25519) || defined(WP_HAVE_ECD448)

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) ((sizeof(a)/sizeof(a[0])))
#endif

#ifndef ED25519_SIGSIZE
#define ED25519_SIGSIZE 64
#endif

#ifndef ED448_SIGSIZE
#define ED448_SIGSIZE 114
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif

#ifdef WP_HAVE_ED25519
Expand Down Expand Up @@ -145,10 +143,10 @@ int test_ecx_sign_verify(void *data)
const unsigned char *p;

#ifdef WP_HAVE_ED25519
unsigned char sig_ed25519[ED25519_SIGSIZE];
unsigned char sig_ed25519[ED25519_SIG_SIZE];
#endif
#ifdef WP_HAVE_ED448
unsigned char sig_ed448[ED448_SIGSIZE];
unsigned char sig_ed448[ED448_SIG_SIZE];
#endif

(void)data;
Expand Down Expand Up @@ -179,7 +177,8 @@ int test_ecx_sign_verify(void *data)
p = types[i].key;

if (err == 0) {
pkey = d2i_PrivateKey(types[i].type, NULL, &p, types[i].keyLen);
pkey = d2i_PrivateKey_ex(types[i].type, NULL, &p, types[i].keyLen,
wpLibCtx, NULL);
err = pkey == NULL;
if (err) {
PRINT_MSG("could not create key");
Expand All @@ -203,12 +202,14 @@ int test_ecx_sign_verify_raw_priv(void *data)

EVP_PKEY *pkey_ossl = NULL;
EVP_PKEY *pkey_wolf = NULL;
unsigned char readback_ossl[MAX(ED25519_KEY_SIZE, ED448_KEY_SIZE)];
unsigned char readback_wolf[MAX(ED25519_KEY_SIZE, ED448_KEY_SIZE)];

#ifdef WP_HAVE_ED25519
unsigned char sig_ed25519[ED25519_SIGSIZE];
unsigned char sig_ed25519[ED25519_SIG_SIZE];
#endif
#ifdef WP_HAVE_ED448
unsigned char sig_ed448[ED448_SIGSIZE];
unsigned char sig_ed448[ED448_SIG_SIZE];
#endif

struct {
Expand All @@ -233,6 +234,7 @@ int test_ecx_sign_verify_raw_priv(void *data)
PRINT_MSG("Testing ECX sign/verify with raw keys (%s)",
types[i].name);

/* Create private keys from the byte arrays */
if (err == 0) {
pkey_ossl = EVP_PKEY_new_raw_private_key_ex(osslLibCtx,
types[i].name, NULL, types[i].key, types[i].keyLen);
Expand All @@ -251,6 +253,7 @@ int test_ecx_sign_verify_raw_priv(void *data)
}
}

/* Compare keys */
if (err == 0) {
if (EVP_PKEY_cmp(pkey_wolf, pkey_ossl) != 1) {
PRINT_MSG("EVP_PKEY_cmp failed");
Expand All @@ -262,6 +265,48 @@ int test_ecx_sign_verify_raw_priv(void *data)
}
}

/* Verify readback of the key */
if (err == 0) {
PRINT_MSG("Verify readback of private key with OpenSSL (%s)", types[i].name);
size_t readbackLen_ossl = types[i].keyLen;
/* EVP_PKEY_get_raw_private_key returns 1 for success */
err = EVP_PKEY_get_raw_private_key(pkey_ossl, readback_ossl, &readbackLen_ossl);
err = err != 1;
if (err) {
PRINT_MSG("EVP_PKEY_get_raw_private_key failed");
err = 1;
}
if (readbackLen_ossl != types[i].keyLen) {
PRINT_MSG("EVP_PKEY_get_raw_private_key length mismatch");
err = 1;
}
if (memcmp(readback_ossl, types[i].key, readbackLen_ossl) != 0) {
PRINT_MSG("EVP_PKEY_get_raw_private_key data mismatch");
err = 1;
}
}

/* Compare key with WolfSSL */
if (err == 0) {
PRINT_MSG("Verify readback of private key with WolfSSL (%s)", types[i].name);
size_t readbackLen_wolf = types[i].keyLen;
/* EVP_PKEY_get_raw_private_key returns 1 for success */
err = EVP_PKEY_get_raw_private_key(pkey_wolf, readback_wolf, &readbackLen_wolf);
err = err != 1;
if (err) {
PRINT_MSG("EVP_PKEY_get_raw_private_key failed");
err = 1;
}
if (readbackLen_wolf != types[i].keyLen) {
PRINT_MSG("EVP_PKEY_get_raw_private_key length mismatch");
err = 1;
}
if (memcmp(readback_wolf, types[i].key, readbackLen_wolf) != 0) {
PRINT_MSG("EVP_PKEY_get_raw_private_key data mismatch");
err = 1;
}
}

if (err == 0) {
err = sign_verify(types[i].sig, types[i].sigLen, pkey_ossl,
types[i].name);
Expand Down Expand Up @@ -290,12 +335,14 @@ int test_ecx_sign_verify_raw_pub(void *data)
const unsigned char *p = NULL;
unsigned char buf[128];
size_t bufLen = 0;
unsigned char readback_ossl[MAX(ED25519_KEY_SIZE, ED448_KEY_SIZE)];
unsigned char readback_wolf[MAX(ED25519_KEY_SIZE, ED448_KEY_SIZE)];

#ifdef WP_HAVE_ED25519
unsigned char sig_ed25519[ED25519_SIGSIZE];
unsigned char sig_ed25519[ED25519_SIG_SIZE];
#endif
#ifdef WP_HAVE_ED448
unsigned char sig_ed448[ED448_SIGSIZE];
unsigned char sig_ed448[ED448_SIG_SIZE];
#endif

struct {
Expand Down Expand Up @@ -341,7 +388,8 @@ int test_ecx_sign_verify_raw_pub(void *data)
}
}

/* Use OpenSSL to sign the block of random bytes */
/* Use OpenSSL to sign the block of random bytes. We will use this
* signature to verify with the public key */
if (err == 0) {
PRINT_MSG("Sign with OpenSSL (%s)", types[i].name);
err = test_digest_sign(pkey_der, osslLibCtx, buf, bufLen, NULL,
Expand Down Expand Up @@ -379,6 +427,48 @@ int test_ecx_sign_verify_raw_pub(void *data)
}
}

/* Verify readback of the key with OpenSSL */
if (err == 0) {
PRINT_MSG("Verify readback of public key with OpenSSL (%s)", types[i].name);
size_t readbackLen_ossl = types[i].pubKeyLen;
/* EVP_PKEY_get_raw_public_key returns 1 for success */
err = EVP_PKEY_get_raw_public_key(pkey_ossl, readback_ossl, &readbackLen_ossl);
err = err != 1;
if (err) {
PRINT_MSG("EVP_PKEY_get_raw_public_key failed");
err = 1;
}
if (readbackLen_ossl != types[i].pubKeyLen) {
PRINT_MSG("EVP_PKEY_get_raw_public_key length mismatch");
err = 1;
}
if (memcmp(readback_ossl, types[i].pubKey, readbackLen_ossl) != 0) {
PRINT_MSG("EVP_PKEY_get_raw_public_key data mismatch");
err = 1;
}
}

/* Verify readback of the key with WolfSSL */
if (err == 0) {
PRINT_MSG("Verify readback of public key with WolfSSL (%s)", types[i].name);
size_t readbackLen_wolf = types[i].pubKeyLen;
/* EVP_PKEY_get_raw_public_key returns 1 for success */
err = EVP_PKEY_get_raw_public_key(pkey_wolf, readback_wolf, &readbackLen_wolf);
err = err != 1;
if (err) {
PRINT_MSG("EVP_PKEY_get_raw_public_key failed");
err = 1;
}
if (readbackLen_wolf != types[i].pubKeyLen) {
PRINT_MSG("EVP_PKEY_get_raw_public_key length mismatch");
err = 1;
}
if (memcmp(readback_wolf, types[i].pubKey, readbackLen_wolf) != 0) {
PRINT_MSG("EVP_PKEY_get_raw_public_key data mismatch");
err = 1;
}
}

/* Verify the signature with the public keys */
if (err == 0) {
PRINT_MSG("Verify with OpenSSL (%s)", types[i].name);
Expand Down Expand Up @@ -412,4 +502,128 @@ int test_ecx_sign_verify_raw_pub(void *data)
return err;
}

int test_ecx_misc(void *data)
{
int err = 0;
(void)data;

EVP_PKEY *pkey_ossl = NULL;
EVP_PKEY *pkey_wolf = NULL;
EVP_PKEY_CTX *ctx_ossl = NULL;
EVP_PKEY_CTX *ctx_wolf = NULL;

struct {
int type;
const char* name;
} types[] = {
#ifdef WP_HAVE_ED25519
{ EVP_PKEY_ED25519, "ED25519" },
#endif
#ifdef WP_HAVE_ED448
{ EVP_PKEY_ED448, "ED448" },
#endif
};

for (unsigned i = 0; i < ARRAY_SIZE(types) && err == 0; i++) {
/* Generate context */
if (err == 0) {
ctx_ossl = EVP_PKEY_CTX_new_from_name(osslLibCtx, types[i].name, NULL);
err = ctx_ossl == NULL;
}
if (err == 0) {
ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, types[i].name, NULL);
err = ctx_wolf == NULL;
}

/* Init context */
if (err == 0) {
err = EVP_PKEY_keygen_init(ctx_ossl);
err = err != 1;
}
if (err == 0) {
err = EVP_PKEY_keygen_init(ctx_wolf);
err = err != 1;
}

/* Generate keys */
if (err == 0) {
pkey_ossl = NULL;
err = EVP_PKEY_generate(ctx_ossl, &pkey_ossl);
err = err != 1;
}
if (err == 0) {
pkey_wolf = NULL;
err = EVP_PKEY_generate(ctx_wolf, &pkey_wolf);
err = err != 1;
}

/* Compare various util routines */
if (err == 0) {
int id_ossl = EVP_PKEY_get_id(pkey_ossl);
int id_wolf = EVP_PKEY_get_id(pkey_wolf);
if (id_ossl != id_wolf) {
PRINT_MSG("EVP_PKEY_get_id failed %d %d", id_ossl, id_wolf);
err = 1;
}
}

if (err == 0) {
int base_id_ossl = EVP_PKEY_get_base_id(pkey_ossl);
int base_id_wolf = EVP_PKEY_get_base_id(pkey_wolf);
if (base_id_ossl != base_id_wolf) {
PRINT_MSG("EVP_PKEY_get_base_id failed %d %d",
base_id_ossl, base_id_wolf);
err = 1;
}
}

if (err == 0) {
int bits_ossl = EVP_PKEY_get_bits(pkey_ossl);
int bits_wolf = EVP_PKEY_get_bits(pkey_wolf);
if (bits_ossl != bits_wolf) {
PRINT_MSG("EVP_PKEY_get_bits failed %d %d",
bits_ossl, bits_wolf);
err = 1;
}
}

if (err == 0) {
int sec_ossl = EVP_PKEY_get_security_bits(pkey_ossl);
int sec_wolf = EVP_PKEY_get_security_bits(pkey_wolf);
if (sec_ossl != sec_wolf) {
PRINT_MSG("EVP_PKEY_get_security_bits failed %d %d",
sec_ossl, sec_wolf);
err = 1;
}
}

if (err == 0) {
int size_ossl = EVP_PKEY_get_size(pkey_ossl);
int size_wolf = EVP_PKEY_get_size(pkey_wolf);
if (size_ossl != size_wolf) {
PRINT_MSG("EVP_PKEY_get_size failed %d %d",
size_ossl, size_wolf);
err = 1;
}
}

if (err == 0) {
int sign_ossl = EVP_PKEY_can_sign(pkey_ossl);
int sign_wolf = EVP_PKEY_can_sign(pkey_wolf);
if (sign_ossl != sign_wolf) {
PRINT_MSG("EVP_PKEY_can_sign failed %d %d",
sign_ossl, sign_wolf);
err = 1;
}
}

EVP_PKEY_free(pkey_ossl);
EVP_PKEY_free(pkey_wolf);
EVP_PKEY_CTX_free(ctx_ossl);
EVP_PKEY_CTX_free(ctx_wolf);
}

return err;
}

#endif /* defined(WP_HAVE_ED25519) || defined(WP_HAVE_ECD444) */
Loading