Skip to content
20 changes: 20 additions & 0 deletions src/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -6262,6 +6262,16 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
case DHk:
type = WC_EVP_PKEY_DH;
break;
#ifdef HAVE_ED25519
case ED25519k:
type = WC_EVP_PKEY_ED25519;
break;
#endif
#ifdef HAVE_ED448
case ED448k:
type = WC_EVP_PKEY_ED448;
break;
#endif
default:
type = WOLFSSL_FATAL_ERROR;
break;
Expand Down Expand Up @@ -6409,6 +6419,16 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **key,
case DHk:
type = WC_EVP_PKEY_DH;
break;
#ifdef HAVE_ED25519
case ED25519k:
type = WC_EVP_PKEY_ED25519;
break;
#endif
#ifdef HAVE_ED448
case ED448k:
type = WC_EVP_PKEY_ED448;
break;
#endif
default:
type = WOLFSSL_FATAL_ERROR;
break;
Expand Down
32 changes: 32 additions & 0 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -17747,6 +17747,14 @@ word32 nid2oid(int nid, int grp)
return CTC_SHA3_512wECDSA;
#endif
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case WC_NID_ED25519:
return CTC_ED25519;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case WC_NID_ED448:
return CTC_ED448;
#endif /* HAVE_ED448 */
}
break;

Expand All @@ -17765,6 +17773,14 @@ word32 nid2oid(int nid, int grp)
case WC_NID_X9_62_id_ecPublicKey:
return ECDSAk;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case WC_NID_ED25519:
return ED25519k;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case WC_NID_ED448:
return ED448k;
#endif /* HAVE_ED448 */
}
break;

Expand Down Expand Up @@ -18123,6 +18139,14 @@ int oid2nid(word32 oid, int grp)
return WC_NID_ecdsa_with_SHA3_512;
#endif
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case CTC_ED25519:
return WC_NID_ED25519;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case CTC_ED448:
return WC_NID_ED448;
#endif /* HAVE_ED448 */
}
break;

Expand All @@ -18145,6 +18169,14 @@ int oid2nid(word32 oid, int grp)
case ECDSAk:
return WC_NID_X9_62_id_ecPublicKey;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ED25519k:
return WC_NID_ED25519;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case ED448k:
return WC_NID_ED448;
#endif /* HAVE_ED448 */
}
break;

Expand Down
12 changes: 12 additions & 0 deletions src/ssl_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -5256,6 +5256,18 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
WOLFSSL_MSG("populating ECC key");
ret = ECC_populate_EVP_PKEY(pkey, pkey->ecc);
break;
#endif
#ifdef HAVE_ED25519
case WC_EVP_PKEY_ED25519:
/* DER is already stored in pkey->pkey.ptr by d2i_evp_pkey. */
WOLFSSL_MSG("populating Ed25519 key");
break;
#endif
#ifdef HAVE_ED448
case WC_EVP_PKEY_ED448:
/* DER is already stored in pkey->pkey.ptr by d2i_evp_pkey. */
WOLFSSL_MSG("populating Ed448 key");
break;
#endif
default:
ret = 0;
Expand Down
132 changes: 132 additions & 0 deletions tests/api/test_evp_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -2357,3 +2357,135 @@ int test_wolfSSL_EVP_PKEY_print_public(void)
return EXPECT_RESULT();
}

int test_wolfSSL_EVP_PKEY_ed25519(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
WOLFSSL_EVP_PKEY* pkey = NULL;
const unsigned char* p;

static const unsigned char rawPub[32] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
Comment thread
lealem47 marked this conversation as resolved.

static const unsigned char spkiPub[] = {
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};

/* Exercise the WC_EVP_PKEY_ED25519 case in d2i_evp_pkey()
* including the algId match for the PKCS#8 wrapper. */
p = server_ed25519_key;
ExpectNotNull(pkey = wolfSSL_d2i_PrivateKey(EVP_PKEY_ED25519, NULL,
&p, (long)sizeof_server_ed25519_key));
ExpectIntEQ(wolfSSL_EVP_PKEY_id(pkey), EVP_PKEY_ED25519);
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;

p = spkiPub;
ExpectNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &p, (long)sizeof(spkiPub)));
ExpectIntEQ(wolfSSL_EVP_PKEY_id(pkey), EVP_PKEY_ED25519);
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;

/* Exercise d2iTryEd25519Key's raw fallback where the caller passes
* the raw bytes from the SPKI BIT STRING rather than a wrapped SPKI. */
p = rawPub;
ExpectNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &p, (long)sizeof(rawPub)));
ExpectIntEQ(wolfSSL_EVP_PKEY_id(pkey), EVP_PKEY_ED25519);
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;

{
static const unsigned char junk[16] = { 0 };
const unsigned char* jp = junk;
ExpectNull(wolfSSL_d2i_PUBKEY(NULL, &jp, (long)sizeof(junk)));
}
#endif
return EXPECT_RESULT();
}

int test_wolfSSL_CTX_use_PrivateKey_ed25519(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519) && \
!defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL_EVP_PKEY* pkey = NULL;
const unsigned char* p;

ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));

/* Load the matching Ed25519 server cert */
ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, server_ed25519_cert,
(long)sizeof_server_ed25519_cert, WOLFSSL_FILETYPE_ASN1),
WOLFSSL_SUCCESS);

/* Decode the Ed25519 private key as a WOLFSSL_EVP_PKEY */
p = server_ed25519_key;
ExpectNotNull(pkey = wolfSSL_d2i_PrivateKey(EVP_PKEY_ED25519, NULL,
&p, (long)sizeof_server_ed25519_key));
ExpectIntEQ(wolfSSL_EVP_PKEY_id(pkey), EVP_PKEY_ED25519);

/* Load the pkey and check for success */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WOLFSSL_SUCCESS);

wolfSSL_EVP_PKEY_free(pkey);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}

int test_wolfSSL_EVP_PKEY_ed448(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
WOLFSSL_EVP_PKEY* pkey = NULL;
const unsigned char* p;
/* 57 arbitrary bytes used as a "raw Ed448 public key". */
static const unsigned char rawPub[57] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38
};

static const unsigned char spkiPub[] = {
0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x71, 0x03, 0x3a, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38
Comment thread
lealem47 marked this conversation as resolved.
Outdated
};

/* SPKI path. */
p = spkiPub;
ExpectNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &p, (long)sizeof(spkiPub)));
ExpectIntEQ(wolfSSL_EVP_PKEY_id(pkey), EVP_PKEY_ED448);
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;

/* Raw 57-byte fallback path. */
p = rawPub;
ExpectNotNull(pkey = wolfSSL_d2i_PUBKEY(NULL, &p, (long)sizeof(rawPub)));
ExpectIntEQ(wolfSSL_EVP_PKEY_id(pkey), EVP_PKEY_ED448);
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
#endif
Comment thread
lealem47 marked this conversation as resolved.
return EXPECT_RESULT();
}

8 changes: 7 additions & 1 deletion tests/api/test_evp_pkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ int test_wolfSSL_EVP_MD_ecc_signing(void);
int test_wolfSSL_EVP_PKEY_encrypt(void);
int test_wolfSSL_EVP_PKEY_derive(void);
int test_wolfSSL_EVP_PKEY_print_public(void);
int test_wolfSSL_EVP_PKEY_ed25519(void);
int test_wolfSSL_CTX_use_PrivateKey_ed25519(void);
int test_wolfSSL_EVP_PKEY_ed448(void);
Comment thread
lealem47 marked this conversation as resolved.

#define TEST_EVP_PKEY_DECLS \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_CTX_new_id), \
Expand Down Expand Up @@ -97,6 +100,9 @@ int test_wolfSSL_EVP_PKEY_print_public(void);
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_ecc_signing), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_encrypt), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_derive), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_print_public)
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_print_public), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_ed25519), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_CTX_use_PrivateKey_ed25519), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_ed448)
Comment thread
lealem47 marked this conversation as resolved.

#endif /* WOLFCRYPT_TEST_EVP_PKEY_H */
26 changes: 26 additions & 0 deletions wolfcrypt/src/evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
#include <wolfssl/openssl/evp.h>
#include <wolfssl/openssl/kdf.h>
#include <wolfssl/wolfcrypt/wolfmath.h>
#ifdef HAVE_ED25519
#include <wolfssl/wolfcrypt/ed25519.h>
#endif
#ifdef HAVE_ED448
#include <wolfssl/wolfcrypt/ed448.h>
#endif

static const struct s_ent {
const enum wc_HashType macType;
Expand Down Expand Up @@ -11679,6 +11685,26 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key)
break;
#endif /* ! NO_DH ... */

#ifdef HAVE_ED25519
case WC_EVP_PKEY_ED25519:
if (key->ed25519 != NULL && key->ownEd25519 == 1) {
wc_ed25519_free(key->ed25519);
XFREE(key->ed25519, key->heap, DYNAMIC_TYPE_ED25519);
key->ed25519 = NULL;
}
break;
#endif /* HAVE_ED25519 */

#ifdef HAVE_ED448
case WC_EVP_PKEY_ED448:
if (key->ed448 != NULL && key->ownEd448 == 1) {
wc_ed448_free(key->ed448);
XFREE(key->ed448, key->heap, DYNAMIC_TYPE_ED448);
key->ed448 = NULL;
}
break;
#endif /* HAVE_ED448 */
Comment thread
lealem47 marked this conversation as resolved.

#ifdef HAVE_HKDF
case WC_EVP_PKEY_HKDF:
XFREE(key->hkdfSalt, NULL, DYNAMIC_TYPE_SALT);
Expand Down
Loading
Loading