The resulting EVP_PKEYs do not do anything useful yet, but we are able to parse them. Teaching them to sign will be done in a follow-up. Creating these from in-memory keys is also slightly different from other types. We don't have or need a public ED25519_KEY struct in curve25519.h, so I've added tighter constructor functions which should hopefully be easier to use anyway. BUG=187 Change-Id: I0bbeea37350d4fdca05b6c6c0f152c15e6ade5bb Reviewed-on: https://boringssl-review.googlesource.com/14446 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>kris/onging/CECPQ3_patch15
@@ -17,6 +17,7 @@ EVP,115,INVALID_PADDING_MODE | |||
EVP,116,INVALID_PSS_SALTLEN | |||
EVP,117,KEYS_NOT_SET | |||
EVP,118,MISSING_PARAMETERS | |||
EVP,130,NOT_A_PRIVATE_KEY | |||
EVP,119,NO_DEFAULT_DIGEST | |||
EVP,120,NO_KEY_SET | |||
EVP,121,NO_MDC2_SUPPORT | |||
@@ -12,6 +12,7 @@ add_library( | |||
p_dsa_asn1.c | |||
p_ec.c | |||
p_ec_asn1.c | |||
p_ed25519_asn1.c | |||
p_rsa.c | |||
p_rsa_asn1.c | |||
pbkdf.c | |||
@@ -198,6 +198,8 @@ static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) { | |||
return &ec_asn1_meth; | |||
case EVP_PKEY_DSA: | |||
return &dsa_asn1_meth; | |||
case EVP_PKEY_ED25519: | |||
return &ed25519_asn1_meth; | |||
default: | |||
return NULL; | |||
} | |||
@@ -72,6 +72,7 @@ static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = { | |||
&rsa_asn1_meth, | |||
&ec_asn1_meth, | |||
&dsa_asn1_meth, | |||
&ed25519_asn1_meth, | |||
}; | |||
static int parse_key_type(CBS *cbs, int *out_type) { | |||
@@ -80,8 +81,7 @@ static int parse_key_type(CBS *cbs, int *out_type) { | |||
return 0; | |||
} | |||
unsigned i; | |||
for (i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { | |||
for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { | |||
const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i]; | |||
if (CBS_len(&oid) == method->oid_len && | |||
OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) { | |||
@@ -540,3 +540,85 @@ TEST(EVPExtraTest, d2i_PrivateKey) { | |||
sizeof(kExampleRSAKeyPKCS8))); | |||
ERR_clear_error(); | |||
} | |||
TEST(EVPExtraTest, Ed25519) { | |||
static const uint8_t kPublicKey[32] = { | |||
0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, | |||
0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, | |||
0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a, | |||
}; | |||
static const uint8_t kPublicKeySPKI[] = { | |||
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, | |||
0x00, 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, | |||
0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, | |||
0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a, | |||
}; | |||
static const uint8_t kPrivateKey[64] = { | |||
0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, 0x4a, | |||
0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, | |||
0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60, 0xd7, | |||
0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3, | |||
0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, | |||
0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a, | |||
}; | |||
static const uint8_t kPrivateKeyPKCS8[] = { | |||
0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, | |||
0x04, 0x22, 0x04, 0x20, 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, | |||
0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, | |||
0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60, | |||
}; | |||
// Create a public key. | |||
bssl::UniquePtr<EVP_PKEY> pubkey(EVP_PKEY_new_ed25519_public(kPublicKey)); | |||
ASSERT_TRUE(pubkey); | |||
EXPECT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(pubkey.get())); | |||
// The public key must encode properly. | |||
bssl::ScopedCBB cbb; | |||
uint8_t *der; | |||
size_t der_len; | |||
ASSERT_TRUE(CBB_init(cbb.get(), 0)); | |||
ASSERT_TRUE(EVP_marshal_public_key(cbb.get(), pubkey.get())); | |||
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len)); | |||
bssl::UniquePtr<uint8_t> free_der(der); | |||
EXPECT_EQ(Bytes(kPublicKeySPKI), Bytes(der, der_len)); | |||
// The public key must gracefully fail to encode as a private key. | |||
ASSERT_TRUE(CBB_init(cbb.get(), 0)); | |||
EXPECT_FALSE(EVP_marshal_private_key(cbb.get(), pubkey.get())); | |||
uint32_t err = ERR_get_error(); | |||
EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err)); | |||
EXPECT_EQ(EVP_R_NOT_A_PRIVATE_KEY, ERR_GET_REASON(err)); | |||
cbb.Reset(); | |||
// Create a private key. | |||
bssl::UniquePtr<EVP_PKEY> privkey(EVP_PKEY_new_ed25519_private(kPrivateKey)); | |||
ASSERT_TRUE(privkey); | |||
EXPECT_EQ(EVP_PKEY_ED25519, EVP_PKEY_id(privkey.get())); | |||
// The public key must encode from the private key. | |||
ASSERT_TRUE(CBB_init(cbb.get(), 0)); | |||
ASSERT_TRUE(EVP_marshal_public_key(cbb.get(), privkey.get())); | |||
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len)); | |||
free_der.reset(der); | |||
EXPECT_EQ(Bytes(kPublicKeySPKI), Bytes(der, der_len)); | |||
// The private key must encode properly. | |||
ASSERT_TRUE(CBB_init(cbb.get(), 0)); | |||
ASSERT_TRUE(EVP_marshal_private_key(cbb.get(), privkey.get())); | |||
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len)); | |||
free_der.reset(der); | |||
EXPECT_EQ(Bytes(kPrivateKeyPKCS8), Bytes(der, der_len)); | |||
// Test EVP_PKEY_cmp. | |||
EXPECT_TRUE(EVP_PKEY_cmp(pubkey.get(), privkey.get())); | |||
static const uint8_t kZeros[32] = {0}; | |||
bssl::UniquePtr<EVP_PKEY> pubkey2(EVP_PKEY_new_ed25519_public(kZeros)); | |||
ASSERT_TRUE(pubkey2); | |||
EXPECT_FALSE(EVP_PKEY_cmp(pubkey.get(), pubkey2.get())); | |||
EXPECT_FALSE(EVP_PKEY_cmp(privkey.get(), pubkey2.get())); | |||
} |
@@ -110,6 +110,9 @@ static int GetKeyType(FileTest *t, const std::string &name) { | |||
if (name == "DSA") { | |||
return EVP_PKEY_DSA; | |||
} | |||
if (name == "Ed25519") { | |||
return EVP_PKEY_ED25519; | |||
} | |||
t->PrintLine("Unknown key type: '%s'", name.c_str()); | |||
return EVP_PKEY_NONE; | |||
} | |||
@@ -84,6 +84,36 @@ PublicKey = DSA-1024-SPKI-No-Params | |||
Type = DSA | |||
Input = 308192300906072a8648ce38040103818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a | |||
# An Ed25519 private key. | |||
PrivateKey = Ed25519 | |||
Type = Ed25519 | |||
Input = 302e020100300506032b6570042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 | |||
# The same as the above, but with an invalid NULL parameter. | |||
PrivateKey = Ed25519-NULL | |||
Input = 3030020100300706032b65700500042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 | |||
Error = DECODE_ERROR | |||
# The above key as an SPKI. | |||
PublicKey = Ed25519-SPKI | |||
Type = Ed25519 | |||
Input = 302a300506032b6570032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a | |||
# The same as the above, but with an invalid NULL parameter. | |||
PublicKey = Ed25519-SPKI-NULL | |||
Input = 302c300706032b65700500032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a | |||
Error = DECODE_ERROR | |||
# Sample public key from draft-ietf-curdle-pkix-04. | |||
PublicKey = Ed25519-SPKI-Spec | |||
Type = Ed25519 | |||
Input = 302a300506032b657003210019bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1 | |||
# Sample private key from draft-ietf-curdle-pkix-04. | |||
PrivateKey = Ed25519-Spec | |||
Type = Ed25519 | |||
Input = 302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842 | |||
# RSA tests | |||
@@ -219,6 +219,7 @@ struct evp_pkey_method_st { | |||
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; | |||
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; | |||
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; | |||
extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; | |||
extern const EVP_PKEY_METHOD rsa_pkey_meth; | |||
extern const EVP_PKEY_METHOD ec_pkey_meth; | |||
@@ -0,0 +1,207 @@ | |||
/* Copyright (c) 2017, Google Inc. | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any | |||
* purpose with or without fee is hereby granted, provided that the above | |||
* copyright notice and this permission notice appear in all copies. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | |||
#include <openssl/evp.h> | |||
#include <openssl/bytestring.h> | |||
#include <openssl/curve25519.h> | |||
#include <openssl/err.h> | |||
#include <openssl/mem.h> | |||
#include "internal.h" | |||
#include "../internal.h" | |||
typedef struct { | |||
union { | |||
uint8_t priv[64]; | |||
struct { | |||
/* Shift the location of the public key to align with where it is in the | |||
* private key representation. */ | |||
uint8_t pad[32]; | |||
uint8_t value[32]; | |||
} pub; | |||
} key; | |||
char has_private; | |||
} ED25519_KEY; | |||
static void ed25519_free(EVP_PKEY *pkey) { | |||
if (pkey->pkey.ptr != NULL) { | |||
ED25519_KEY *key = pkey->pkey.ptr; | |||
OPENSSL_cleanse(key, sizeof(ED25519_KEY)); | |||
OPENSSL_free(key); | |||
pkey->pkey.ptr = NULL; | |||
} | |||
} | |||
static int set_pubkey(EVP_PKEY *pkey, const uint8_t pubkey[32]) { | |||
ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); | |||
if (key == NULL) { | |||
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); | |||
return 0; | |||
} | |||
key->has_private = 0; | |||
OPENSSL_memcpy(key->key.pub.value, pubkey, 32); | |||
ed25519_free(pkey); | |||
pkey->pkey.ptr = key; | |||
return 1; | |||
} | |||
static int set_privkey(EVP_PKEY *pkey, const uint8_t privkey[64]) { | |||
ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); | |||
if (key == NULL) { | |||
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); | |||
return 0; | |||
} | |||
key->has_private = 1; | |||
OPENSSL_memcpy(key->key.priv, privkey, 64); | |||
ed25519_free(pkey); | |||
pkey->pkey.ptr = key; | |||
return 1; | |||
} | |||
static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { | |||
/* See draft-ietf-curdle-pkix-04, section 4. */ | |||
/* The parameters must be omitted. Public keys have length 32. */ | |||
if (CBS_len(params) != 0 || | |||
CBS_len(key) != 32) { | |||
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); | |||
return 0; | |||
} | |||
return set_pubkey(out, CBS_data(key)); | |||
} | |||
static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { | |||
const ED25519_KEY *key = pkey->pkey.ptr; | |||
/* See draft-ietf-curdle-pkix-04, section 4. */ | |||
CBB spki, algorithm, oid, key_bitstring; | |||
if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || | |||
!CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || | |||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || | |||
!CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || | |||
!CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || | |||
!CBB_add_u8(&key_bitstring, 0 /* padding */) || | |||
!CBB_add_bytes(&key_bitstring, key->key.pub.value, 32) || | |||
!CBB_flush(out)) { | |||
OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); | |||
return 0; | |||
} | |||
return 1; | |||
} | |||
static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { | |||
const ED25519_KEY *a_key = a->pkey.ptr; | |||
const ED25519_KEY *b_key = b->pkey.ptr; | |||
return OPENSSL_memcmp(a_key->key.pub.value, b_key->key.pub.value, 32) == 0; | |||
} | |||
static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { | |||
/* See draft-ietf-curdle-pkix-04, section 7. */ | |||
/* Parameters must be empty. The key is a 32-byte value wrapped in an extra | |||
* OCTET STRING layer. */ | |||
CBS inner; | |||
if (CBS_len(params) != 0 || | |||
!CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || | |||
CBS_len(key) != 0 || | |||
CBS_len(&inner) != 32) { | |||
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); | |||
return 0; | |||
} | |||
/* The PKCS#8 encoding stores only the 32-byte seed, so we must recover the | |||
* full representation which we use from it. */ | |||
uint8_t pubkey[32], privkey[64]; | |||
ED25519_keypair_from_seed(pubkey, privkey, CBS_data(&inner)); | |||
return set_privkey(out, privkey); | |||
} | |||
static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { | |||
ED25519_KEY *key = pkey->pkey.ptr; | |||
if (!key->has_private) { | |||
OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); | |||
return 0; | |||
} | |||
/* See draft-ietf-curdle-pkix-04, section 7. */ | |||
CBB pkcs8, algorithm, oid, private_key, inner; | |||
if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || | |||
!CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || | |||
!CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || | |||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || | |||
!CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || | |||
!CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || | |||
!CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || | |||
/* The PKCS#8 encoding stores only the 32-byte seed which is the first 32 | |||
* bytes of the private key. */ | |||
!CBB_add_bytes(&inner, key->key.priv, 32) || | |||
!CBB_flush(out)) { | |||
OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); | |||
return 0; | |||
} | |||
return 1; | |||
} | |||
static int ed25519_size(const EVP_PKEY *pkey) { return 64; } | |||
static int ed25519_bits(const EVP_PKEY *pkey) { return 256; } | |||
const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { | |||
EVP_PKEY_ED25519, | |||
{0x2b, 0x65, 0x70}, | |||
3, | |||
ed25519_pub_decode, | |||
ed25519_pub_encode, | |||
ed25519_pub_cmp, | |||
ed25519_priv_decode, | |||
ed25519_priv_encode, | |||
NULL /* pkey_opaque */, | |||
ed25519_size, | |||
ed25519_bits, | |||
NULL /* param_missing */, | |||
NULL /* param_copy */, | |||
NULL /* param_cmp */, | |||
ed25519_free, | |||
}; | |||
EVP_PKEY *EVP_PKEY_new_ed25519_public(const uint8_t public_key[32]) { | |||
EVP_PKEY *ret = EVP_PKEY_new(); | |||
if (ret == NULL || | |||
!EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) || | |||
!set_pubkey(ret, public_key)) { | |||
EVP_PKEY_free(ret); | |||
return NULL; | |||
} | |||
return ret; | |||
} | |||
EVP_PKEY *EVP_PKEY_new_ed25519_private(const uint8_t private_key[64]) { | |||
EVP_PKEY *ret = EVP_PKEY_new(); | |||
if (ret == NULL || | |||
!EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) || | |||
!set_privkey(ret, private_key)) { | |||
EVP_PKEY_free(ret); | |||
return NULL; | |||
} | |||
return ret; | |||
} |
@@ -56,7 +56,7 @@ | |||
/* This file is generated by crypto/obj/objects.go. */ | |||
#define NUM_NID 949 | |||
#define NUM_NID 950 | |||
static const uint8_t kObjectData[] = { | |||
/* NID_rsadsi */ | |||
@@ -1811,6 +1811,8 @@ static const uint8_t kObjectData[] = { | |||
0x2b, 0x81, 0x04, 0x01, 0x0e, 0x02, | |||
/* NID_dhSinglePass_cofactorDH_sha512kdf_scheme */ | |||
0x2b, 0x81, 0x04, 0x01, 0x0e, 0x03, | |||
/* NID_Ed25519 */ | |||
0x2b, 0x65, 0x70, | |||
}; | |||
static const ASN1_OBJECT kObjects[NUM_NID] = { | |||
@@ -3440,6 +3442,7 @@ static const ASN1_OBJECT kObjects[NUM_NID] = { | |||
{"dh-std-kdf", "dh-std-kdf", NID_dh_std_kdf, 0, NULL, 0}, | |||
{"dh-cofactor-kdf", "dh-cofactor-kdf", NID_dh_cofactor_kdf, 0, NULL, 0}, | |||
{"X25519", "X25519", NID_X25519, 0, NULL, 0}, | |||
{"Ed25519", "Ed25519", NID_Ed25519, 3, &kObjectData[6175], 0}, | |||
}; | |||
static const unsigned kNIDsInShortNameOrder[] = { | |||
@@ -3528,6 +3531,7 @@ static const unsigned kNIDsInShortNameOrder[] = { | |||
70 /* DSA-SHA1-old */, | |||
67 /* DSA-old */, | |||
297 /* DVCS */, | |||
949 /* Ed25519 */, | |||
99 /* GN */, | |||
855 /* HMAC */, | |||
780 /* HMAC-MD5 */, | |||
@@ -4400,6 +4404,7 @@ static const unsigned kNIDsInLongNameOrder[] = { | |||
382 /* Directory */, | |||
392 /* Domain */, | |||
132 /* E-mail Protection */, | |||
949 /* Ed25519 */, | |||
389 /* Enterprises */, | |||
384 /* Experimental */, | |||
372 /* Extended OCSP Status */, | |||
@@ -5334,7 +5339,8 @@ static const unsigned kNIDsInOIDOrder[] = { | |||
378 /* 2.5.8 (OBJ_X500algorithms) */, 81 /* 2.5.29 (OBJ_id_ce) */, | |||
512 /* 2.23.42 (OBJ_id_set) */, 678 /* 2.23.43 (OBJ_wap) */, | |||
435 /* 0.9.2342 (OBJ_pss) */, 183 /* 1.2.840 (OBJ_ISO_US) */, | |||
381 /* 1.3.6.1 (OBJ_iana) */, 677 /* 1.3.132 (OBJ_certicom_arc) */, | |||
381 /* 1.3.6.1 (OBJ_iana) */, 949 /* 1.3.101.112 (OBJ_Ed25519) */, | |||
677 /* 1.3.132 (OBJ_certicom_arc) */, | |||
394 /* 2.5.1.5 (OBJ_selected_attribute_types) */, | |||
13 /* 2.5.4.3 (OBJ_commonName) */, 100 /* 2.5.4.4 (OBJ_surname) */, | |||
105 /* 2.5.4.5 (OBJ_serialNumber) */, 14 /* 2.5.4.6 (OBJ_countryName) */, | |||
@@ -937,3 +937,4 @@ dhSinglePass_cofactorDH_sha512kdf_scheme 945 | |||
dh_std_kdf 946 | |||
dh_cofactor_kdf 947 | |||
X25519 948 | |||
Ed25519 949 |
@@ -1333,3 +1333,6 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme | |||
# NID for X25519 (no corresponding OID). | |||
: X25519 | |||
# See draft-ietf-curdle-pkix-04. | |||
1 3 101 112 : Ed25519 |
@@ -157,10 +157,21 @@ OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); | |||
OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); | |||
OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); | |||
/* EVP_PKEY_new_ed25519_public returns a newly allocated |EVP_PKEY| wrapping an | |||
* Ed25519 public key, or NULL on allocation error. */ | |||
OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_public( | |||
const uint8_t public_key[32]); | |||
/* EVP_PKEY_new_ed25519_private returns a newly allocated |EVP_PKEY| wrapping an | |||
* Ed25519 private key, or NULL on allocation error. */ | |||
OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_private( | |||
const uint8_t private_key[64]); | |||
#define EVP_PKEY_NONE NID_undef | |||
#define EVP_PKEY_RSA NID_rsaEncryption | |||
#define EVP_PKEY_DSA NID_dsa | |||
#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey | |||
#define EVP_PKEY_ED25519 NID_Ed25519 | |||
/* EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of | |||
* the given type. The |type| argument should be one of the |EVP_PKEY_*| | |||
@@ -771,7 +782,7 @@ struct evp_pkey_st { | |||
int type; | |||
union { | |||
char *ptr; | |||
void *ptr; | |||
RSA *rsa; | |||
DSA *dsa; | |||
DH *dh; | |||
@@ -829,5 +840,6 @@ BORINGSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free) | |||
#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 127 | |||
#define EVP_R_UNSUPPORTED_ALGORITHM 128 | |||
#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 129 | |||
#define EVP_R_NOT_A_PRIVATE_KEY 130 | |||
#endif /* OPENSSL_HEADER_EVP_H */ |
@@ -4192,6 +4192,11 @@ extern "C" { | |||
#define SN_X25519 "X25519" | |||
#define NID_X25519 948 | |||
#define SN_Ed25519 "Ed25519" | |||
#define NID_Ed25519 949 | |||
#define OBJ_Ed25519 1L, 3L, 101L, 112L | |||
#if defined(__cplusplus) | |||
} /* extern C */ | |||
#endif | |||