mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 13:10:52 +02:00
Merge pull request #10552 from julek-wolfssl/evp-x25519-x448
Add NID_X25519 and NID_X448 support to the EVP layer
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+143
-1
@@ -47,6 +47,12 @@
|
||||
#ifdef HAVE_ED448
|
||||
#include <wolfssl/wolfcrypt/ed448.h>
|
||||
#endif
|
||||
#ifdef HAVE_CURVE25519
|
||||
#include <wolfssl/wolfcrypt/curve25519.h>
|
||||
#endif
|
||||
#ifdef HAVE_CURVE448
|
||||
#include <wolfssl/wolfcrypt/curve448.h>
|
||||
#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;
|
||||
}
|
||||
@@ -11822,6 +11943,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user