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
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
};

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

#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)

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

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