diff --git a/tests/api/test_evp_pkey.c b/tests/api/test_evp_pkey.c index 13de8ebe25b..6b15f38d962 100644 --- a/tests/api/test_evp_pkey.c +++ b/tests/api/test_evp_pkey.c @@ -2702,3 +2702,162 @@ int test_wolfSSL_EVP_PKEY_ed448(void) return EXPECT_RESULT(); } +int test_wolfSSL_EVP_PKEY_x25519(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519) + EVP_PKEY* pkey = NULL; + EVP_PKEY* peer = NULL; + EVP_PKEY_CTX* genCtx = NULL; + EVP_PKEY_CTX* ctx = NULL; + unsigned char rawPriv[32]; + unsigned char rawPub[32]; + unsigned char secretA[32]; + unsigned char secretB[32]; + size_t secretLen; + int i; + + for (i = 0; i < 32; i++) { + rawPriv[i] = (unsigned char)i; + rawPub[i] = (unsigned char)(0x40 + i); + } + + /* Raw import with the correct length reports the X25519 type. */ + ExpectNotNull(pkey = EVP_PKEY_new_raw_public_key( + EVP_PKEY_X25519, NULL, rawPub, sizeof(rawPub))); + ExpectIntEQ(EVP_PKEY_id(pkey), EVP_PKEY_X25519); + EVP_PKEY_free(pkey); + pkey = NULL; + + ExpectNotNull(pkey = EVP_PKEY_new_raw_private_key( + EVP_PKEY_X25519, NULL, rawPriv, sizeof(rawPriv))); + ExpectIntEQ(EVP_PKEY_id(pkey), EVP_PKEY_X25519); + + /* X25519 is key-agreement only: signing must be rejected. */ + ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL)); + ExpectIntNE(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS); + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + EVP_PKEY_free(pkey); + pkey = NULL; + + /* Wrong raw lengths are rejected. */ + ExpectNull(EVP_PKEY_new_raw_public_key( + EVP_PKEY_X25519, NULL, rawPub, 16)); + ExpectNull(EVP_PKEY_new_raw_private_key( + EVP_PKEY_X25519, NULL, rawPriv, 16)); + + /* Generate two key pairs and confirm ECDH agreement is symmetric. This + * also exercises the little-endian convention used on import/derive. */ + ExpectNotNull(genCtx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL)); + ExpectIntEQ(EVP_PKEY_keygen_init(genCtx), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_keygen(genCtx, &pkey), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_keygen(genCtx, &peer), WOLFSSL_SUCCESS); + EVP_PKEY_CTX_free(genCtx); + genCtx = NULL; + + ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL)); + ExpectIntEQ(EVP_PKEY_derive_init(ctx), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_derive_set_peer(ctx, peer), WOLFSSL_SUCCESS); + secretLen = sizeof(secretA); + ExpectIntEQ(EVP_PKEY_derive(ctx, secretA, &secretLen), WOLFSSL_SUCCESS); + ExpectIntEQ((int)secretLen, 32); + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + + ExpectNotNull(ctx = EVP_PKEY_CTX_new(peer, NULL)); + ExpectIntEQ(EVP_PKEY_derive_init(ctx), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_derive_set_peer(ctx, pkey), WOLFSSL_SUCCESS); + secretLen = sizeof(secretB); + ExpectIntEQ(EVP_PKEY_derive(ctx, secretB, &secretLen), WOLFSSL_SUCCESS); + ExpectIntEQ((int)secretLen, 32); + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + + ExpectIntEQ(XMEMCMP(secretA, secretB, 32), 0); + + EVP_PKEY_free(peer); + EVP_PKEY_free(pkey); +#endif + return EXPECT_RESULT(); +} + +int test_wolfSSL_EVP_PKEY_x448(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448) + EVP_PKEY* pkey = NULL; + EVP_PKEY* peer = NULL; + EVP_PKEY_CTX* genCtx = NULL; + EVP_PKEY_CTX* ctx = NULL; + unsigned char rawPriv[56]; + unsigned char rawPub[56]; + unsigned char secretA[56]; + unsigned char secretB[56]; + size_t secretLen; + int i; + + for (i = 0; i < 56; i++) { + rawPriv[i] = (unsigned char)i; + rawPub[i] = (unsigned char)(0x40 + i); + } + + /* Raw import with the correct length reports the X448 type. */ + ExpectNotNull(pkey = EVP_PKEY_new_raw_public_key( + EVP_PKEY_X448, NULL, rawPub, sizeof(rawPub))); + ExpectIntEQ(EVP_PKEY_id(pkey), EVP_PKEY_X448); + EVP_PKEY_free(pkey); + pkey = NULL; + + ExpectNotNull(pkey = EVP_PKEY_new_raw_private_key( + EVP_PKEY_X448, NULL, rawPriv, sizeof(rawPriv))); + ExpectIntEQ(EVP_PKEY_id(pkey), EVP_PKEY_X448); + + /* X448 is key-agreement only: signing must be rejected. */ + ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL)); + ExpectIntNE(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS); + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + EVP_PKEY_free(pkey); + pkey = NULL; + + /* Wrong raw lengths are rejected. */ + ExpectNull(EVP_PKEY_new_raw_public_key( + EVP_PKEY_X448, NULL, rawPub, 16)); + ExpectNull(EVP_PKEY_new_raw_private_key( + EVP_PKEY_X448, NULL, rawPriv, 16)); + + /* Generate two key pairs and confirm ECDH agreement is symmetric. */ + ExpectNotNull(genCtx = EVP_PKEY_CTX_new_id(EVP_PKEY_X448, NULL)); + ExpectIntEQ(EVP_PKEY_keygen_init(genCtx), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_keygen(genCtx, &pkey), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_keygen(genCtx, &peer), WOLFSSL_SUCCESS); + EVP_PKEY_CTX_free(genCtx); + genCtx = NULL; + + ExpectNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL)); + ExpectIntEQ(EVP_PKEY_derive_init(ctx), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_derive_set_peer(ctx, peer), WOLFSSL_SUCCESS); + secretLen = sizeof(secretA); + ExpectIntEQ(EVP_PKEY_derive(ctx, secretA, &secretLen), WOLFSSL_SUCCESS); + ExpectIntEQ((int)secretLen, 56); + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + + ExpectNotNull(ctx = EVP_PKEY_CTX_new(peer, NULL)); + ExpectIntEQ(EVP_PKEY_derive_init(ctx), WOLFSSL_SUCCESS); + ExpectIntEQ(EVP_PKEY_derive_set_peer(ctx, pkey), WOLFSSL_SUCCESS); + secretLen = sizeof(secretB); + ExpectIntEQ(EVP_PKEY_derive(ctx, secretB, &secretLen), WOLFSSL_SUCCESS); + ExpectIntEQ((int)secretLen, 56); + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + + ExpectIntEQ(XMEMCMP(secretA, secretB, 56), 0); + + EVP_PKEY_free(peer); + EVP_PKEY_free(pkey); +#endif + return EXPECT_RESULT(); +} + diff --git a/tests/api/test_evp_pkey.h b/tests/api/test_evp_pkey.h index 2b77782a59c..97388dfd7a8 100644 --- a/tests/api/test_evp_pkey.h +++ b/tests/api/test_evp_pkey.h @@ -66,6 +66,8 @@ 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); +int test_wolfSSL_EVP_PKEY_x25519(void); +int test_wolfSSL_EVP_PKEY_x448(void); #define TEST_EVP_PKEY_DECLS \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_CTX_new_id), \ @@ -110,6 +112,8 @@ int test_wolfSSL_EVP_PKEY_ed448(void); 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) + TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_ed448), \ + TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_x25519), \ + TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_x448) #endif /* WOLFCRYPT_TEST_EVP_PKEY_H */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 4790b20d8d9..c8b68cfe202 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -47,6 +47,12 @@ #ifdef HAVE_ED448 #include #endif +#ifdef HAVE_CURVE25519 +#include +#endif +#ifdef HAVE_CURVE448 +#include +#endif static const struct s_ent { const enum wc_HashType macType; @@ -2767,7 +2773,7 @@ int wolfSSL_EVP_PKEY_CTX_ctrl_str(WOLFSSL_EVP_PKEY_CTX *ctx, #endif /* NO_WOLFSSL_STUB */ #if (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || defined(HAVE_ECC) || \ - defined(HAVE_HKDF) + defined(HAVE_HKDF) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { int len; @@ -2884,6 +2890,54 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ *keylen = (size_t)len; break; #endif +#ifdef HAVE_CURVE25519 + case WC_EVP_PKEY_X25519: + if (!ctx->pkey->curve25519 || !ctx->peerKey->curve25519) { + return WOLFSSL_FAILURE; + } + len = CURVE25519_KEYSIZE; + if (key) { + word32 len32 = (word32)*keylen; + if (*keylen < (size_t)len) { + WOLFSSL_MSG("buffer too short"); + return WOLFSSL_FAILURE; + } + /* X25519 shared secret is little-endian (RFC 7748). */ + if (wc_curve25519_shared_secret_ex(ctx->pkey->curve25519, + ctx->peerKey->curve25519, key, &len32, + EC25519_LITTLE_ENDIAN) != 0) { + WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed"); + return WOLFSSL_FAILURE; + } + len = (int)len32; + } + *keylen = (size_t)len; + break; +#endif +#ifdef HAVE_CURVE448 + case WC_EVP_PKEY_X448: + if (!ctx->pkey->curve448 || !ctx->peerKey->curve448) { + return WOLFSSL_FAILURE; + } + len = CURVE448_KEY_SIZE; + if (key) { + word32 len32 = (word32)*keylen; + if (*keylen < (size_t)len) { + WOLFSSL_MSG("buffer too short"); + return WOLFSSL_FAILURE; + } + /* X448 shared secret is little-endian (RFC 7748). */ + if (wc_curve448_shared_secret_ex(ctx->pkey->curve448, + ctx->peerKey->curve448, key, &len32, + EC448_LITTLE_ENDIAN) != 0) { + WOLFSSL_MSG("wc_curve448_shared_secret_ex failed"); + return WOLFSSL_FAILURE; + } + len = (int)len32; + } + *keylen = (size_t)len; + break; +#endif #ifdef HAVE_HKDF case WC_EVP_PKEY_HKDF: (void)len; @@ -3761,6 +3815,12 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, if (ctx->pkey == NULL || (ctx->pkey->type != WC_EVP_PKEY_EC && ctx->pkey->type != WC_EVP_PKEY_RSA && + #ifdef HAVE_CURVE25519 + ctx->pkey->type != WC_EVP_PKEY_X25519 && + #endif + #ifdef HAVE_CURVE448 + ctx->pkey->type != WC_EVP_PKEY_X448 && + #endif ctx->pkey->type != WC_EVP_PKEY_DH)) { WOLFSSL_MSG("Key not set or key type not supported"); return WOLFSSL_FAILURE; @@ -3821,6 +3881,57 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, } } break; +#endif +#ifdef HAVE_CURVE25519 + case WC_EVP_PKEY_X25519: + if (pkey->curve25519 == NULL) { + pkey->curve25519 = (curve25519_key*)XMALLOC( + sizeof(curve25519_key), pkey->heap, DYNAMIC_TYPE_CURVE25519); + if (pkey->curve25519 == NULL) { + ret = MEMORY_E; + break; + } + if (wc_curve25519_init_ex(pkey->curve25519, pkey->heap, + INVALID_DEVID) != 0) { + XFREE(pkey->curve25519, pkey->heap, DYNAMIC_TYPE_CURVE25519); + pkey->curve25519 = NULL; + break; + } + #ifdef WOLFSSL_CURVE25519_BLINDING + /* Use the EVP_PKEY's RNG for scalar blinding on derive. */ + (void)wc_curve25519_set_rng(pkey->curve25519, &pkey->rng); + #endif + pkey->ownCurve25519 = 1; + } + /* Reuse the RNG already initialized on the EVP_PKEY. */ + if (wc_curve25519_make_key(&pkey->rng, CURVE25519_KEYSIZE, + pkey->curve25519) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; +#endif +#ifdef HAVE_CURVE448 + case WC_EVP_PKEY_X448: + if (pkey->curve448 == NULL) { + pkey->curve448 = (curve448_key*)XMALLOC(sizeof(curve448_key), + pkey->heap, DYNAMIC_TYPE_CURVE448); + if (pkey->curve448 == NULL) { + ret = MEMORY_E; + break; + } + if (wc_curve448_init(pkey->curve448) != 0) { + XFREE(pkey->curve448, pkey->heap, DYNAMIC_TYPE_CURVE448); + pkey->curve448 = NULL; + break; + } + pkey->ownCurve448 = 1; + } + /* Reuse the RNG already initialized on the EVP_PKEY. */ + if (wc_curve448_make_key(&pkey->rng, CURVE448_KEY_SIZE, + pkey->curve448) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; #endif default: break; @@ -3871,6 +3982,16 @@ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) return wc_ecc_sig_size((ecc_key*)(pkey->ecc->internal)); #endif /* HAVE_ECC */ +#ifdef HAVE_CURVE25519 + case WC_EVP_PKEY_X25519: + return CURVE25519_KEYSIZE; +#endif + +#ifdef HAVE_CURVE448 + case WC_EVP_PKEY_X448: + return CURVE448_KEY_SIZE; +#endif + default: break; } @@ -11818,6 +11939,27 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) break; #endif /* HAVE_ED448 */ + #ifdef HAVE_CURVE25519 + case WC_EVP_PKEY_X25519: + if (key->curve25519 != NULL && key->ownCurve25519 == 1) { + wc_curve25519_free(key->curve25519); + XFREE(key->curve25519, key->heap, + DYNAMIC_TYPE_CURVE25519); + key->curve25519 = NULL; + } + break; + #endif /* HAVE_CURVE25519 */ + + #ifdef HAVE_CURVE448 + case WC_EVP_PKEY_X448: + if (key->curve448 != NULL && key->ownCurve448 == 1) { + wc_curve448_free(key->curve448); + XFREE(key->curve448, key->heap, DYNAMIC_TYPE_CURVE448); + key->curve448 = NULL; + } + break; + #endif /* HAVE_CURVE448 */ + #ifdef HAVE_HKDF case WC_EVP_PKEY_HKDF: XFREE(key->hkdfSalt, NULL, DYNAMIC_TYPE_SALT); diff --git a/wolfcrypt/src/evp_pk.c b/wolfcrypt/src/evp_pk.c index 03eb059b8c7..c9a59473b2a 100644 --- a/wolfcrypt/src/evp_pk.c +++ b/wolfcrypt/src/evp_pk.c @@ -439,6 +439,64 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_raw_public_key(int type, ok = 1; break; } + #endif + #ifdef HAVE_CURVE25519 + case WC_EVP_PKEY_X25519: { + curve25519_key* cKey; + if (len != CURVE25519_PUB_KEY_SIZE) { + break; + } + cKey = (curve25519_key*)XMALLOC(sizeof(curve25519_key), pkey->heap, + DYNAMIC_TYPE_CURVE25519); + if (cKey == NULL) { + break; + } + if (wc_curve25519_init_ex(cKey, pkey->heap, INVALID_DEVID) != 0) { + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE25519); + break; + } + /* Raw X25519 keys are little-endian (RFC 7748). */ + if (wc_curve25519_import_public_ex(pub, (word32)len, cKey, + EC25519_LITTLE_ENDIAN) != 0) { + wc_curve25519_free(cKey); + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE25519); + break; + } + pkey->type = WC_EVP_PKEY_X25519; + pkey->curve25519 = cKey; + pkey->ownCurve25519 = 1; + ok = 1; + break; + } + #endif + #ifdef HAVE_CURVE448 + case WC_EVP_PKEY_X448: { + curve448_key* cKey; + if (len != CURVE448_PUB_KEY_SIZE) { + break; + } + cKey = (curve448_key*)XMALLOC(sizeof(curve448_key), pkey->heap, + DYNAMIC_TYPE_CURVE448); + if (cKey == NULL) { + break; + } + if (wc_curve448_init(cKey) != 0) { + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE448); + break; + } + /* Raw X448 keys are little-endian (RFC 7748). */ + if (wc_curve448_import_public_ex(pub, (word32)len, cKey, + EC448_LITTLE_ENDIAN) != 0) { + wc_curve448_free(cKey); + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE448); + break; + } + pkey->type = WC_EVP_PKEY_X448; + pkey->curve448 = cKey; + pkey->ownCurve448 = 1; + ok = 1; + break; + } #endif default: break; @@ -526,6 +584,68 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_raw_private_key(int type, ok = 1; break; } + #endif + #ifdef HAVE_CURVE25519 + case WC_EVP_PKEY_X25519: { + curve25519_key* cKey; + if (len != CURVE25519_KEYSIZE) { + break; + } + cKey = (curve25519_key*)XMALLOC(sizeof(curve25519_key), pkey->heap, + DYNAMIC_TYPE_CURVE25519); + if (cKey == NULL) { + break; + } + if (wc_curve25519_init_ex(cKey, pkey->heap, INVALID_DEVID) != 0) { + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE25519); + break; + } + #ifdef WOLFSSL_CURVE25519_BLINDING + /* Use the EVP_PKEY's RNG for scalar blinding on shared-secret. */ + (void)wc_curve25519_set_rng(cKey, &pkey->rng); + #endif + /* Raw X25519 keys are little-endian (RFC 7748). */ + if (wc_curve25519_import_private_ex(priv, (word32)len, cKey, + EC25519_LITTLE_ENDIAN) != 0) { + wc_curve25519_free(cKey); + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE25519); + break; + } + pkey->type = WC_EVP_PKEY_X25519; + pkey->curve25519 = cKey; + pkey->ownCurve25519 = 1; + ok = 1; + break; + } + #endif + #ifdef HAVE_CURVE448 + case WC_EVP_PKEY_X448: { + curve448_key* cKey; + if (len != CURVE448_KEY_SIZE) { + break; + } + cKey = (curve448_key*)XMALLOC(sizeof(curve448_key), pkey->heap, + DYNAMIC_TYPE_CURVE448); + if (cKey == NULL) { + break; + } + if (wc_curve448_init(cKey) != 0) { + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE448); + break; + } + /* Raw X448 keys are little-endian (RFC 7748). */ + if (wc_curve448_import_private_ex(priv, (word32)len, cKey, + EC448_LITTLE_ENDIAN) != 0) { + wc_curve448_free(cKey); + XFREE(cKey, pkey->heap, DYNAMIC_TYPE_CURVE448); + break; + } + pkey->type = WC_EVP_PKEY_X448; + pkey->curve448 = cKey; + pkey->ownCurve448 = 1; + ok = 1; + break; + } #endif default: break; diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 9b90563cf8e..bc873695bf0 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -455,6 +455,12 @@ enum { #endif #ifdef HAVE_ED448 WC_EVP_PKEY_ED448 = WC_NID_ED448, +#endif +#ifdef HAVE_CURVE25519 + WC_EVP_PKEY_X25519 = WC_NID_X25519, +#endif +#ifdef HAVE_CURVE448 + WC_EVP_PKEY_X448 = WC_NID_X448, #endif WC_AES_128_CFB1_TYPE = 24, WC_AES_192_CFB1_TYPE = 25, @@ -529,6 +535,12 @@ enum { #ifdef HAVE_ED448 #define EVP_PKEY_ED448 WC_EVP_PKEY_ED448 #endif +#ifdef HAVE_CURVE25519 +#define EVP_PKEY_X25519 WC_EVP_PKEY_X25519 +#endif +#ifdef HAVE_CURVE448 +#define EVP_PKEY_X448 WC_EVP_PKEY_X448 +#endif #define AES_128_CFB1_TYPE WC_AES_128_CFB1_TYPE #define AES_192_CFB1_TYPE WC_AES_192_CFB1_TYPE #define AES_256_CFB1_TYPE WC_AES_256_CFB1_TYPE diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 0081cfc494d..2281bb2f264 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -609,6 +609,12 @@ struct WOLFSSL_EVP_PKEY { #ifdef HAVE_ED448 struct ed448_key* ed448; #endif + #ifdef HAVE_CURVE25519 + struct curve25519_key* curve25519; + #endif + #ifdef HAVE_CURVE448 + struct curve448_key* curve448; + #endif WC_RNG rng; #ifdef HAVE_HKDF const WOLFSSL_EVP_MD* hkdfMd; @@ -640,6 +646,12 @@ struct WOLFSSL_EVP_PKEY { #ifdef HAVE_ED448 WC_BITFIELD ownEd448:1; /* if struct owns Ed448 and should free it */ #endif +#ifdef HAVE_CURVE25519 + WC_BITFIELD ownCurve25519:1; /* if struct owns X25519 and should free it */ +#endif +#ifdef HAVE_CURVE448 + WC_BITFIELD ownCurve448:1; /* if struct owns X448 and should free it */ +#endif };