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
143 changes: 143 additions & 0 deletions tests/api/test_evp_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -2357,3 +2357,146 @@ 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;

/* Known-valid Ed25519 public key matching server_ed25519_key. The bytes
* are the raw 32-byte BIT STRING contents from
* ./certs/ed25519/server-ed25519-key.der so the import succeeds even
* under strict point-validation. */
static const unsigned char rawPub[32] = {
0x23, 0xaa, 0x4d, 0x60, 0x50, 0xe0, 0x13, 0xd3,
0x3a, 0xed, 0xab, 0xf6, 0xa9, 0xcc, 0x4a, 0xfe,
0xd7, 0x4d, 0x2f, 0xd2, 0x5b, 0x1a, 0x10, 0x05,
0xef, 0x5a, 0x41, 0x25, 0xce, 0x1b, 0x53, 0x78
};
Comment thread
lealem47 marked this conversation as resolved.

/* SPKI wrapper around the same known-valid public key (the full
* contents of ./certs/ed25519/server-ed25519-key.der). */
static const unsigned char spkiPub[] = {
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00,
0x23, 0xaa, 0x4d, 0x60, 0x50, 0xe0, 0x13, 0xd3,
0x3a, 0xed, 0xab, 0xf6, 0xa9, 0xcc, 0x4a, 0xfe,
0xd7, 0x4d, 0x2f, 0xd2, 0x5b, 0x1a, 0x10, 0x05,
0xef, 0x5a, 0x41, 0x25, 0xce, 0x1b, 0x53, 0x78
};

/* 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;

/* Known-valid Ed448 public key: the raw 57-byte BIT STRING contents
* from ./certs/ed448/server-ed448-key.der so the import succeeds even
* under strict point-validation. */
static const unsigned char rawPub[57] = {
0x54, 0x81, 0x39, 0x01, 0xeb, 0x37, 0xd9, 0xa9,
0x07, 0xcd, 0x01, 0xbc, 0x9d, 0x70, 0x16, 0xc2,
0x2c, 0x2b, 0x75, 0x5b, 0x63, 0xdb, 0xee, 0x3a,
0x2d, 0x44, 0x92, 0x46, 0xb4, 0x7b, 0x07, 0x03,
0x4f, 0xa2, 0xae, 0x86, 0x86, 0xdc, 0x8b, 0x4b,
0x2c, 0x7f, 0xe8, 0x6b, 0x14, 0x8d, 0x58, 0xdd,
0x6d, 0xe7, 0x6f, 0x3a, 0x05, 0x95, 0xa8, 0xef,
0x00
};

/* SPKI wrapper around the same known-valid public key (the full
* contents of ./certs/ed448/server-ed448-key.der). */
static const unsigned char spkiPub[] = {
0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x71, 0x03, 0x3a, 0x00,
0x54, 0x81, 0x39, 0x01, 0xeb, 0x37, 0xd9, 0xa9,
0x07, 0xcd, 0x01, 0xbc, 0x9d, 0x70, 0x16, 0xc2,
0x2c, 0x2b, 0x75, 0x5b, 0x63, 0xdb, 0xee, 0x3a,
0x2d, 0x44, 0x92, 0x46, 0xb4, 0x7b, 0x07, 0x03,
0x4f, 0xa2, 0xae, 0x86, 0x86, 0xdc, 0x8b, 0x4b,
0x2c, 0x7f, 0xe8, 0x6b, 0x14, 0x8d, 0x58, 0xdd,
0x6d, 0xe7, 0x6f, 0x3a, 0x05, 0x95, 0xa8, 0xef,
0x00
};

/* 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