Introduce EVP_PKEY_ALG
This adds new SPKI and PKCS#8 parser entrypoints that pass in the list
of allowed algorithms. Algorithms are expressed as EVP_PKEY_ALG
functions and roughly things that can create EVP_PKEYs in various ways.
(Right now just SPKI and PKCS#8 parsers, but I'm imagining that they'll
also be the handle for the "raw" public/private key parsers and things
like the list of curves for ECPrivateKey or X9.62 points.)
The immediate motivation is to give a handle for opting into
EVP_PKEY_RSA_PSS (we don't want most applications to be exposed to
those), but I'm hoping this can also:
- Let us add legacy or experimental algorithms for one caller without
worrying about exposing all callers to them.
- Let size-constrained applications use EVP without worrying about
binary size.
- Reduce the need for people to check the key type after parsing keys. I
would like to it eliminate the need, but RSA having a continuum of
sizes makes things tricky. For now, EVP_pkey_rsa() just accepts all
supported RSA sizes (512 through 8192, but hopefully we can clamp it
down).
While we're here, correct what, in hindsight, were I think some missteps
in the EVP_parse_public_key convention:
- Not saying the name of the format in the function name. Since I expect
we'll add EVP_PKEY_from_ec_private_key, EVP_PKEY_from_rsa_private_key,
etc., functions to start filling out EVP, having the name of the
format would have been nice.
- Taking an in/out CBS parameter. As an in/out parameter, we don't check
trailing data and just pass it to the caller to check. This optimized
for parsing an SPKI inside a structure, rather than standalone. In
practice, folks forget to check trailing data.
In comparison to OpenSSL 3.x, I think an EVP_PKEY_ALG is roughly an
OSSL_KEYMGMT, but that's a very confusing name. Maybe also with bits of
the OSSL_DECODER in there. Mostly I don't understand their very
complicated (and apparently quadratic-time) decoder system.
OpenSSL 3.x also has an OSSL_LIB_CTX which has been threaded into a
bunch of objects. Having BoringSSL's OSSL_LIB_CTX carry a list of these
things would be plausible, but different call sites within a single
application may support different algorithms, so let's start with the
explicit list approach and see where we go from there.
Bug: 42290364
Change-Id: I342603efdc167c8f587357d17800d7ad545d5908
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81651
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/evp/evp_asn1.cc b/crypto/evp/evp_asn1.cc
index 7fca9b8..1f5216f 100644
--- a/crypto/evp/evp_asn1.cc
+++ b/crypto/evp/evp_asn1.cc
@@ -16,72 +16,68 @@
#include <string.h>
+#include <array>
+
#include <openssl/bytestring.h>
#include <openssl/dsa.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
+#include <openssl/span.h>
#include "internal.h"
#include "../bytestring/internal.h"
#include "../internal.h"
-// We intentionally omit |dh_asn1_meth| from this list. It is not serializable.
-static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
- &rsa_asn1_meth,
- &ec_asn1_meth,
- &dsa_asn1_meth,
- &ed25519_asn1_meth,
- &x25519_asn1_meth,
-};
-
-static const EVP_PKEY_ASN1_METHOD *parse_key_type(CBS *cbs) {
- CBS oid;
- if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) {
- return NULL;
- }
-
- 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) {
- return method;
- }
- }
-
- return NULL;
-}
-
-EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
+EVP_PKEY *EVP_PKEY_from_subject_public_key_info(const uint8_t *in, size_t len,
+ const EVP_PKEY_ALG *const *algs,
+ size_t num_algs) {
// Parse the SubjectPublicKeyInfo.
- CBS spki, algorithm, key;
- uint8_t padding;
- if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) ||
+ CBS cbs, spki, algorithm, oid, key;
+ CBS_init(&cbs, in, len);
+ if (!CBS_get_asn1(&cbs, &spki, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
- CBS_len(&spki) != 0) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return nullptr;
- }
- const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm);
- if (method == nullptr || method->pub_decode == nullptr) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
- return nullptr;
- }
- // Every key type defined encodes the key as a byte string with the same
- // conversion to BIT STRING, so perform that common conversion ahead of time.
- if (!CBS_get_u8(&key, &padding) || padding != 0) {
+ CBS_len(&spki) != 0 || //
+ CBS_len(&cbs) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return nullptr;
}
bssl::UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
- if (ret == nullptr || !method->pub_decode(ret.get(), &algorithm, &key)) {
+ if (ret == nullptr) {
return nullptr;
}
+ for (const EVP_PKEY_ALG *alg : bssl::Span(algs, num_algs)) {
+ if (alg->method->pub_decode == nullptr ||
+ bssl::Span(alg->method->oid, alg->method->oid_len) != oid) {
+ continue;
+ }
+ // Every key type we support encodes the key as a byte string with the same
+ // conversion to BIT STRING, so perform that common conversion ahead of
+ // time, but only after the OID is recognized as supported.
+ CBS key_bytes = key;
+ uint8_t padding;
+ if (!CBS_get_u8(&key_bytes, &padding) || padding != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return nullptr;
+ }
+ CBS params = algorithm;
+ switch (alg->method->pub_decode(alg, ret.get(), ¶ms, &key_bytes)) {
+ case evp_decode_error:
+ return nullptr;
+ case evp_decode_ok:
+ return ret.release();
+ case evp_decode_unsupported:
+ // Continue trying other algorithms.
+ break;
+ }
+ }
- return ret.release();
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+ return nullptr;
}
int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) {
@@ -93,33 +89,47 @@
return key->ameth->pub_encode(cbb, key);
}
-EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
+EVP_PKEY *EVP_PKEY_from_private_key_info(const uint8_t *in, size_t len,
+ const EVP_PKEY_ALG *const *algs,
+ size_t num_algs) {
// Parse the PrivateKeyInfo.
- CBS pkcs8, algorithm, key;
+ CBS cbs, pkcs8, oid, algorithm, key;
uint64_t version;
- if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
- !CBS_get_asn1_uint64(&pkcs8, &version) ||
- version != 0 ||
+ CBS_init(&cbs, in, len);
+ if (!CBS_get_asn1(&cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&pkcs8, &version) || version != 0 ||
!CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
- !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) {
+ !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+ !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING) ||
+ // A PrivateKeyInfo ends with a SET of Attributes which we ignore.
+ CBS_len(&cbs) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return nullptr;
}
- const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm);
- if (method == nullptr || method->priv_decode == nullptr) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
- return nullptr;
- }
- // A PrivateKeyInfo ends with a SET of Attributes which we ignore.
-
- // Set up an |EVP_PKEY| of the appropriate type.
bssl::UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
- if (ret == nullptr || !method->priv_decode(ret.get(), &algorithm, &key)) {
+ if (ret == nullptr) {
return nullptr;
}
+ for (const EVP_PKEY_ALG *alg : bssl::Span(algs, num_algs)) {
+ if (alg->method->priv_decode == nullptr ||
+ bssl::Span(alg->method->oid, alg->method->oid_len) != oid) {
+ continue;
+ }
+ CBS params = algorithm, key_copy = key;
+ switch (alg->method->priv_decode(alg, ret.get(), ¶ms, &key_copy)) {
+ case evp_decode_error:
+ return nullptr;
+ case evp_decode_ok:
+ return ret.release();
+ case evp_decode_unsupported:
+ // Continue trying other algorithms.
+ break;
+ }
+ }
- return ret.release();
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+ return nullptr;
}
int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) {
@@ -131,6 +141,47 @@
return key->ameth->priv_encode(cbb, key);
}
+static auto get_default_algs() {
+ // A set of algorithms to use by default in |EVP_parse_public_key| and
+ // |EVP_parse_private_key|.
+ return std::array{
+ EVP_pkey_ec_p224(),
+ EVP_pkey_ec_p256(),
+ EVP_pkey_ec_p384(),
+ EVP_pkey_ec_p521(),
+ EVP_pkey_ed25519(),
+ EVP_pkey_rsa(),
+ EVP_pkey_x25519(),
+ // TODO(crbug.com/438761503): Remove DSA from this set, after callers that
+ // need DSA pass in |EVP_pkey_dsa| explicitly.
+ EVP_pkey_dsa(),
+ };
+}
+
+EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
+ CBS elem;
+ if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return nullptr;
+ }
+
+ auto algs = get_default_algs();
+ return EVP_PKEY_from_subject_public_key_info(CBS_data(&elem), CBS_len(&elem),
+ algs.data(), algs.size());
+}
+
+EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
+ CBS elem;
+ if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return nullptr;
+ }
+
+ auto algs = get_default_algs();
+ return EVP_PKEY_from_private_key_info(CBS_data(&elem), CBS_len(&elem),
+ algs.data(), algs.size());
+}
+
static bssl::UniquePtr<EVP_PKEY> old_priv_decode(CBS *cbs, int type) {
bssl::UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
if (ret == nullptr) {
diff --git a/crypto/evp/evp_extra_test.cc b/crypto/evp/evp_extra_test.cc
index f69ccbe..bd0b648 100644
--- a/crypto/evp/evp_extra_test.cc
+++ b/crypto/evp/evp_extra_test.cc
@@ -1271,3 +1271,31 @@
EXPECT_FALSE(EVP_PKEY_set1_DSA(pkey.get(), nullptr));
EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
}
+
+// Test that parsers correctly handle trailing data.
+TEST(EVPExtraTest, TrailingData) {
+ bssl::UniquePtr<EVP_PKEY> pkey = LoadExampleRSAKey();
+ ASSERT_TRUE(pkey);
+ bssl::ScopedCBB cbb;
+ ASSERT_TRUE(CBB_init(cbb.get(), 64));
+ ASSERT_TRUE(EVP_marshal_public_key(cbb.get(), pkey.get()));
+
+ std::vector<uint8_t> spki(CBB_data(cbb.get()),
+ CBB_data(cbb.get()) + CBB_len(cbb.get()));
+ spki.push_back('a');
+
+ // |EVP_parse_public_key| should accept trailing data and return the
+ // remainder.
+ CBS cbs(spki);
+ pkey.reset(EVP_parse_public_key(&cbs));
+ EXPECT_TRUE(pkey);
+ EXPECT_EQ(Bytes(cbs), Bytes("a"));
+
+ // |EVP_PKEY_from_subject_public_key_info| should not.
+ const EVP_PKEY_ALG *alg = EVP_pkey_rsa();
+ pkey.reset(EVP_PKEY_from_subject_public_key_info(spki.data(), spki.size(),
+ &alg, 1u));
+ EXPECT_FALSE(pkey);
+ EXPECT_TRUE(
+ ErrorEquals(ERR_peek_last_error(), ERR_LIB_EVP, EVP_R_DECODE_ERROR));
+}
diff --git a/crypto/evp/evp_test.cc b/crypto/evp/evp_test.cc
index 2df9cc4..25af7ed 100644
--- a/crypto/evp/evp_test.cc
+++ b/crypto/evp/evp_test.cc
@@ -68,26 +68,6 @@
return nullptr;
}
-static int GetKeyType(std::string_view name) {
- if (name == "RSA") {
- return EVP_PKEY_RSA;
- }
- if (name == "EC") {
- return EVP_PKEY_EC;
- }
- if (name == "DSA") {
- return EVP_PKEY_DSA;
- }
- if (name == "Ed25519") {
- return EVP_PKEY_ED25519;
- }
- if (name == "X25519") {
- return EVP_PKEY_X25519;
- }
- ADD_FAILURE() << "Unknown key type: " << name;
- return EVP_PKEY_NONE;
-}
-
static std::optional<int> GetRSAPadding(std::string_view name) {
if (name == "PKCS1") {
return RSA_PKCS1_PADDING;
@@ -105,6 +85,23 @@
return std::nullopt;
}
+struct AlgorithmInfo {
+ const EVP_PKEY_ALG *alg;
+ int pkey_id;
+ bool is_default;
+};
+
+static const std::map<std::string, AlgorithmInfo> kAllAlgorithms = {
+ {"RSA", {EVP_pkey_rsa(), EVP_PKEY_RSA, true}},
+ {"EC-P-224", {EVP_pkey_ec_p224(), EVP_PKEY_EC, true}},
+ {"EC-P-256", {EVP_pkey_ec_p256(), EVP_PKEY_EC, true}},
+ {"EC-P-384", {EVP_pkey_ec_p384(), EVP_PKEY_EC, true}},
+ {"EC-P-521", {EVP_pkey_ec_p521(), EVP_PKEY_EC, true}},
+ {"X25519", {EVP_pkey_x25519(), EVP_PKEY_X25519, true}},
+ {"Ed25519", {EVP_pkey_ed25519(), EVP_PKEY_ED25519, true}},
+ {"DSA", {EVP_pkey_dsa(), EVP_PKEY_DSA, true}},
+};
+
using KeyMap = std::map<std::string, bssl::UniquePtr<EVP_PKEY>>;
enum class KeyRole { kPublic, kPrivate };
@@ -132,8 +129,11 @@
}
static bool ImportKey(FileTest *t, KeyMap *key_map, KeyRole key_role) {
- auto format_name = key_role == KeyRole::kPublic ? "spki" : "pkcs8";
- auto parse_func = key_role == KeyRole::kPublic ? &EVP_parse_public_key
+ std::string format_name = key_role == KeyRole::kPublic ? "spki" : "pkcs8";
+ auto parse_func = key_role == KeyRole::kPublic
+ ? &EVP_PKEY_from_subject_public_key_info
+ : &EVP_PKEY_from_private_key_info;
+ auto parse_default_func = key_role == KeyRole::kPublic ? &EVP_parse_public_key
: &EVP_parse_private_key;
auto marshal_func = key_role == KeyRole::kPublic ? &EVP_marshal_public_key
: &EVP_marshal_private_key;
@@ -147,19 +147,66 @@
if (!t->GetBytes(&input, "Input")) {
return false;
}
- CBS cbs;
- CBS_init(&cbs, input.data(), input.size());
- bssl::UniquePtr<EVP_PKEY> new_key(parse_func(&cbs));
- if (new_key == nullptr || CBS_len(&cbs) != 0) {
- return false;
- }
- keys.emplace_back(format_name, std::move(new_key));
- std::string key_type_str;
- if (!t->GetAttribute(&key_type_str, "Type")) {
+ // First, parse the key with all algorithms active. Check this before
+ // specifying an individual algorithm, so that error cases do not need to
+ // specify an Algorithm key.
+ std::vector<const EVP_PKEY_ALG *> algs;
+ for (const auto &[name, info] : kAllAlgorithms) {
+ algs.push_back(info.alg);
+ }
+ bssl::UniquePtr<EVP_PKEY> new_key(
+ parse_func(input.data(), input.size(), algs.data(), algs.size()));
+ if (new_key == nullptr) {
return false;
}
- int key_type = GetKeyType(key_type_str);
+ keys.emplace_back(format_name + " - all algs", std::move(new_key));
+
+ // Parse with just the specific algorithm.
+ std::string alg_name;
+ if (!t->GetAttribute(&alg_name, "Algorithm")) {
+ return false;
+ }
+ auto it = kAllAlgorithms.find(alg_name);
+ if (it == kAllAlgorithms.end()) {
+ ADD_FAILURE() << "Unknown algorithm: " << alg_name;
+ return false;
+ }
+ const AlgorithmInfo &alg_info = it->second;
+ new_key.reset(parse_func(input.data(), input.size(), &alg_info.alg, 1));
+ if (new_key == nullptr) {
+ return false;
+ }
+ keys.emplace_back(format_name + " - " + alg_name + " only",
+ std::move(new_key));
+
+ // Parsing with all other algorithms should fail. This currently assumes each
+ // key can only be parsed by one algorithm. Make the field a list of
+ // algorithms if this ever changes.
+ algs.clear();
+ for (const auto &[name, info] : kAllAlgorithms) {
+ if (name != alg_name) {
+ algs.push_back(info.alg);
+ }
+ }
+ new_key.reset(
+ parse_func(input.data(), input.size(), algs.data(), algs.size()));
+ EXPECT_FALSE(new_key);
+ ERR_clear_error();
+
+ // Parse with the default parser.
+ CBS cbs(input);
+ new_key.reset(parse_default_func(&cbs));
+ if (alg_info.is_default) {
+ if (new_key == nullptr) {
+ return false;
+ }
+ keys.emplace_back(format_name + " - default algorithms",
+ std::move(new_key));
+ } else {
+ EXPECT_FALSE(new_key);
+ ERR_clear_error();
+ }
// Import as a raw key.
if (key_role == KeyRole::kPublic && t->HasAttribute("RawPublic")) {
@@ -167,8 +214,8 @@
if (!t->GetBytes(&raw, "RawPublic")) {
return false;
}
- new_key.reset(
- EVP_PKEY_new_raw_public_key(key_type, nullptr, raw.data(), raw.size()));
+ new_key.reset(EVP_PKEY_new_raw_public_key(alg_info.pkey_id, nullptr,
+ raw.data(), raw.size()));
if (new_key == nullptr) {
return false;
}
@@ -179,8 +226,8 @@
if (!t->GetBytes(&raw, "RawPrivate")) {
return false;
}
- new_key.reset(EVP_PKEY_new_raw_private_key(key_type, nullptr, raw.data(),
- raw.size()));
+ new_key.reset(EVP_PKEY_new_raw_private_key(alg_info.pkey_id, nullptr,
+ raw.data(), raw.size()));
if (new_key == nullptr) {
return false;
}
@@ -188,7 +235,7 @@
}
// Import RSA key from parameters.
- if (key_type == EVP_PKEY_RSA) {
+ if (alg_info.pkey_id == EVP_PKEY_RSA) {
if (key_role == KeyRole::kPublic && t->HasAttribute("RSAParamN") &&
t->HasAttribute("RSAParamE")) {
bssl::UniquePtr<BIGNUM> n =
@@ -246,7 +293,7 @@
for (const auto &[name, pkey] : keys) {
SCOPED_TRACE(name);
- EXPECT_EQ(key_type, EVP_PKEY_id(pkey.get()));
+ EXPECT_EQ(alg_info.pkey_id, EVP_PKEY_id(pkey.get()));
if (t->HasAttribute("Bits")) {
EXPECT_EQ(EVP_PKEY_bits(pkey.get()),
diff --git a/crypto/evp/internal.h b/crypto/evp/internal.h
index ff6ead3..9ceb6f7 100644
--- a/crypto/evp/internal.h
+++ b/crypto/evp/internal.h
@@ -17,7 +17,7 @@
#include <openssl/base.h>
-#include <openssl/rsa.h>
+#include <openssl/span.h>
#include "../internal.h"
@@ -29,6 +29,21 @@
typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
typedef struct evp_pkey_ctx_method_st EVP_PKEY_CTX_METHOD;
+struct evp_pkey_alg_st {
+ // method implements operations for this |EVP_PKEY_ALG|.
+ const EVP_PKEY_ASN1_METHOD *method;
+
+ // ec_group returns the |EC_GROUP| for this algorithm, if |method| is for
+ // |EVP_PKEY_EC|.
+ const EC_GROUP *(*ec_group)();
+};
+
+enum evp_decode_result_t {
+ evp_decode_error = 0,
+ evp_decode_ok = 1,
+ evp_decode_unsupported = 2,
+};
+
struct evp_pkey_asn1_method_st {
// pkey_id contains one of the |EVP_PKEY_*| values and corresponds to the OID
// in the key type's AlgorithmIdentifier.
@@ -39,13 +54,19 @@
const EVP_PKEY_CTX_METHOD *pkey_method;
// pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo
- // and writes the result into |out|. It returns one on success and zero on
- // error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER
- // type field, and |key| is the contents of the subjectPublicKey with the
- // leading padding byte checked and removed. Although X.509 uses BIT STRINGs
- // to represent SubjectPublicKeyInfo, every key type defined encodes the key
- // as a byte string with the same conversion to BIT STRING.
- int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key);
+ // and writes the result into |out|. It returns |evp_decode_ok| on success,
+ // and |evp_decode_error| on error, and |evp_decode_unsupported| if the input
+ // was not supported by this |EVP_PKEY_ALG|. In case of
+ // |evp_decode_unsupported|, it does not add an error to the error queue. May
+ // modify |params| and |key|. Callers must make a copy if calling in a loop.
+ //
+ // |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER type field,
+ // and |key| is the contents of the subjectPublicKey with the leading padding
+ // byte checked and removed. Although X.509 uses BIT STRINGs to represent
+ // SubjectPublicKeyInfo, every key type defined encodes the key as a byte
+ // string with the same conversion to BIT STRING.
+ evp_decode_result_t (*pub_decode)(const EVP_PKEY_ALG *alg, EVP_PKEY *out,
+ CBS *params, CBS *key);
// pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result
// to |out|. It returns one on success and zero on error.
@@ -54,10 +75,16 @@
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
// priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the
- // result into |out|. It returns one on success and zero on error. |params| is
- // the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key|
- // is the contents of the OCTET STRING privateKey field.
- int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key);
+ // result into |out|. It returns |evp_decode_ok| on success, and
+ // |evp_decode_error| on error, and |evp_decode_unsupported| if the key type
+ // was not supported by this |EVP_PKEY_ALG|. In case of
+ // |evp_decode_unsupported|, it does not add an error to the error queue. May
+ // modify |params| and |key|. Callers must make a copy if calling in a loop.
+ //
+ // |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER type field,
+ // and |key| is the contents of the OCTET STRING privateKey field.
+ evp_decode_result_t (*priv_decode)(const EVP_PKEY_ALG *alg, EVP_PKEY *out,
+ CBS *params, CBS *key);
// priv_encode encodes |key| as a PrivateKeyInfo and appends the result to
// |out|. It returns one on success and zero on error.
diff --git a/crypto/evp/p_dsa_asn1.cc b/crypto/evp/p_dsa_asn1.cc
index 237b34b..04c21fe 100644
--- a/crypto/evp/p_dsa_asn1.cc
+++ b/crypto/evp/p_dsa_asn1.cc
@@ -24,7 +24,9 @@
#include "internal.h"
-static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t dsa_pub_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 3279, section 2.3.2.
// Decode parameters. RFC 3279 permits DSA parameters to be omitted, in which
@@ -33,21 +35,21 @@
bssl::UniquePtr<DSA> dsa(DSA_parse_parameters(params));
if (dsa == nullptr || CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
dsa->pub_key = BN_new();
if (dsa->pub_key == nullptr) {
- return 0;
+ return evp_decode_error;
}
if (!BN_parse_asn1_unsigned(key, dsa->pub_key) || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
EVP_PKEY_assign_DSA(out, dsa.release());
- return 1;
+ return evp_decode_ok;
}
static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) {
@@ -72,23 +74,25 @@
return 1;
}
-static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t dsa_priv_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See PKCS#11, v2.40, section 2.5.
// Decode parameters.
bssl::UniquePtr<DSA> dsa(DSA_parse_parameters(params));
if (dsa == nullptr || CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
dsa->priv_key = BN_new();
if (dsa->priv_key == nullptr) {
- return 0;
+ return evp_decode_error;
}
if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
// To avoid DoS attacks when importing private keys, check bounds on |dsa|.
@@ -96,7 +100,7 @@
// width.
if (!dsa_check_key(dsa.get())) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
// Calculate the public key.
@@ -105,11 +109,11 @@
if (ctx == nullptr || dsa->pub_key == nullptr ||
!BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p,
ctx.get(), nullptr)) {
- return 0;
+ return evp_decode_error;
}
EVP_PKEY_assign_DSA(out, dsa.release());
- return 1;
+ return evp_decode_ok;
}
static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) {
@@ -230,6 +234,14 @@
int_dsa_free,
};
+const EVP_PKEY_ALG *EVP_pkey_dsa(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&dsa_asn1_meth,
+ /*ec_group=*/nullptr,
+ };
+ return &kAlg;
+}
+
int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) {
// BoringSSL does not support DSA in |EVP_PKEY_CTX|.
OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
diff --git a/crypto/evp/p_ec_asn1.cc b/crypto/evp/p_ec_asn1.cc
index 10bde92..c5a24fa 100644
--- a/crypto/evp/p_ec_asn1.cc
+++ b/crypto/evp/p_ec_asn1.cc
@@ -21,7 +21,9 @@
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/nid.h>
+#include <openssl/span.h>
+#include "../ec/internal.h"
#include "internal.h"
@@ -49,25 +51,35 @@
return 1;
}
-static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t eckey_pub_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 5480, section 2.
- // The parameters are a named curve.
- const EC_GROUP *group = EC_KEY_parse_curve_name(params);
- if (group == NULL || CBS_len(params) != 0) {
+ // Check that |params| matches |alg|. Only the namedCurve form is allowed.
+ const EC_GROUP *group = alg->ec_group();
+ if (ec_key_parse_curve_name(params, bssl::Span(&group, 1)) == nullptr) {
+ if (ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) {
+ ERR_clear_error();
+ return evp_decode_unsupported;
+ }
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
+ }
+ if (CBS_len(params) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return evp_decode_error;
}
bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new());
if (eckey == nullptr || //
!EC_KEY_set_group(eckey.get(), group) ||
!EC_KEY_oct2key(eckey.get(), CBS_data(key), CBS_len(key), nullptr)) {
- return 0;
+ return evp_decode_error;
}
EVP_PKEY_assign_EC_KEY(out, eckey.release());
- return 1;
+ return evp_decode_ok;
}
static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
@@ -86,23 +98,32 @@
}
}
-static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t eckey_priv_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 5915.
- const EC_GROUP *group = EC_KEY_parse_parameters(params);
- if (group == NULL || CBS_len(params) != 0) {
+ const EC_GROUP *group = alg->ec_group();
+ if (ec_key_parse_parameters(params, bssl::Span(&group, 1)) == nullptr) {
+ if (ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) {
+ ERR_clear_error();
+ return evp_decode_unsupported;
+ }
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
+ }
+ if (CBS_len(params) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ return evp_decode_error;
}
- EC_KEY *ec_key = EC_KEY_parse_private_key(key, group);
- if (ec_key == NULL || CBS_len(key) != 0) {
+ bssl::UniquePtr<EC_KEY> ec_key(ec_key_parse_private_key(key, group, {}));
+ if (ec_key == nullptr || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- EC_KEY_free(ec_key);
- return 0;
+ return evp_decode_error;
}
- EVP_PKEY_assign_EC_KEY(out, ec_key);
- return 1;
+ EVP_PKEY_assign_EC_KEY(out, ec_key.release());
+ return evp_decode_ok;
}
static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) {
@@ -256,6 +277,39 @@
int_ec_free,
};
+const EVP_PKEY_ALG *EVP_pkey_ec_p224(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&ec_asn1_meth,
+ /*ec_group=*/&EC_group_p224,
+ };
+ return &kAlg;
+}
+
+const EVP_PKEY_ALG *EVP_pkey_ec_p256(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&ec_asn1_meth,
+ /*ec_group=*/&EC_group_p256,
+ };
+ return &kAlg;
+}
+
+const EVP_PKEY_ALG *EVP_pkey_ec_p384(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&ec_asn1_meth,
+ /*ec_group=*/&EC_group_p384,
+ };
+ return &kAlg;
+}
+
+const EVP_PKEY_ALG *EVP_pkey_ec_p521(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&ec_asn1_meth,
+ /*ec_group=*/&EC_group_p521,
+ };
+ return &kAlg;
+}
+
+
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
if (EVP_PKEY_assign_EC_KEY(pkey, key)) {
EC_KEY_up_ref(key);
diff --git a/crypto/evp/p_ed25519_asn1.cc b/crypto/evp/p_ed25519_asn1.cc
index 6f1f572..cdd05ba 100644
--- a/crypto/evp/p_ed25519_asn1.cc
+++ b/crypto/evp/p_ed25519_asn1.cc
@@ -109,16 +109,20 @@
return 1;
}
-static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t ed25519_pub_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 8410, section 4.
// The parameters must be omitted. Public keys have length 32.
if (CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
- return ed25519_set_pub_raw(out, CBS_data(key), CBS_len(key));
+ return ed25519_set_pub_raw(out, CBS_data(key), CBS_len(key))
+ ? evp_decode_ok
+ : evp_decode_error;
}
static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) {
@@ -149,7 +153,9 @@
b_key->key + ED25519_PUBLIC_KEY_OFFSET, 32) == 0;
}
-static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t ed25519_priv_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 8410, section 7.
// Parameters must be empty. The key is a 32-byte value wrapped in an extra
@@ -158,10 +164,12 @@
if (CBS_len(params) != 0 ||
!CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
- return ed25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner));
+ return ed25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner))
+ ? evp_decode_ok
+ : evp_decode_error;
}
static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) {
@@ -219,3 +227,11 @@
/*param_cmp=*/NULL,
ed25519_free,
};
+
+const EVP_PKEY_ALG *EVP_pkey_ed25519(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&ed25519_asn1_meth,
+ /*ec_group=*/nullptr,
+ };
+ return &kAlg;
+}
diff --git a/crypto/evp/p_rsa_asn1.cc b/crypto/evp/p_rsa_asn1.cc
index ab23508..6a64d39 100644
--- a/crypto/evp/p_rsa_asn1.cc
+++ b/crypto/evp/p_rsa_asn1.cc
@@ -45,7 +45,9 @@
return 1;
}
-static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t rsa_pub_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 3279, section 2.3.1.
// The parameters must be NULL.
@@ -53,18 +55,18 @@
if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || CBS_len(&null) != 0 ||
CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
RSA *rsa = RSA_parse_public_key(key);
- if (rsa == NULL || CBS_len(key) != 0) {
+ if (rsa == nullptr || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
RSA_free(rsa);
- return 0;
+ return evp_decode_error;
}
EVP_PKEY_assign_RSA(out, rsa);
- return 1;
+ return evp_decode_ok;
}
static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
@@ -93,24 +95,26 @@
return 1;
}
-static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t rsa_priv_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// Per RFC 3447, A.1, the parameters have type NULL.
CBS null;
if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || CBS_len(&null) != 0 ||
CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
RSA *rsa = RSA_parse_private_key(key);
- if (rsa == NULL || CBS_len(key) != 0) {
+ if (rsa == nullptr || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
RSA_free(rsa);
- return 0;
+ return evp_decode_error;
}
EVP_PKEY_assign_RSA(out, rsa);
- return 1;
+ return evp_decode_ok;
}
static int rsa_opaque(const EVP_PKEY *pkey) {
@@ -167,6 +171,14 @@
int_rsa_free,
};
+const EVP_PKEY_ALG *EVP_pkey_rsa(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&rsa_asn1_meth,
+ /*ec_group=*/nullptr,
+ };
+ return &kAlg;
+}
+
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) {
if (EVP_PKEY_assign_RSA(pkey, key)) {
RSA_up_ref(key);
diff --git a/crypto/evp/p_x25519_asn1.cc b/crypto/evp/p_x25519_asn1.cc
index f37111c..49e65ef 100644
--- a/crypto/evp/p_x25519_asn1.cc
+++ b/crypto/evp/p_x25519_asn1.cc
@@ -125,16 +125,20 @@
return *out_ptr == NULL ? 0 : 32;
}
-static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t x25519_pub_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 8410, section 4.
// The parameters must be omitted. Public keys have length 32.
if (CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
- return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key));
+ return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key))
+ ? evp_decode_ok
+ : evp_decode_error;
}
static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) {
@@ -163,7 +167,9 @@
return OPENSSL_memcmp(a_key->pub, b_key->pub, 32) == 0;
}
-static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
+static evp_decode_result_t x25519_priv_decode(const EVP_PKEY_ALG *alg,
+ EVP_PKEY *out, CBS *params,
+ CBS *key) {
// See RFC 8410, section 7.
// Parameters must be empty. The key is a 32-byte value wrapped in an extra
@@ -172,10 +178,12 @@
if (CBS_len(params) != 0 ||
!CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || CBS_len(key) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
- return 0;
+ return evp_decode_error;
}
- return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner));
+ return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner))
+ ? evp_decode_ok
+ : evp_decode_error;
}
static int x25519_priv_encode(CBB *out, const EVP_PKEY *pkey) {
@@ -233,3 +241,11 @@
/*param_cmp=*/NULL,
x25519_free,
};
+
+const EVP_PKEY_ALG *EVP_pkey_x25519(void) {
+ static const EVP_PKEY_ALG kAlg = {
+ /*method=*/&x25519_asn1_meth,
+ /*ec_group=*/nullptr,
+ };
+ return &kAlg;
+}
diff --git a/crypto/evp/test/ec_tests.txt b/crypto/evp/test/ec_tests.txt
index b15fda5..78b49b7 100644
--- a/crypto/evp/test/ec_tests.txt
+++ b/crypto/evp/test/ec_tests.txt
@@ -2,21 +2,21 @@
# EC P-256 key
PrivateKey = P-256
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
# The same key as above with the optional public key omitted.
PrivateKey = P-256-MissingPublic
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725
# The same key as above with redundant parameters.
PrivateKey = P-256-ExtraParameters
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00a06082a8648ce3d030107a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
@@ -30,7 +30,7 @@
# The same key, but with the curve spelled explicitly.
PrivateKey = P-256-ExplicitParameters
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
@@ -38,7 +38,7 @@
# The same as above, but with the optional cofactor omitted.
PrivateKey = P-256-ExplicitParameters-NoCofactor
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 3082015e0201003081e906072a8648ce3d02013081dd020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
@@ -47,12 +47,12 @@
# The same as above, but the cofactor is zero instead of one.
PrivateKey = P-256-ExplicitParameters-CofactorZero
Input = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020100046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
-Error = UNKNOWN_GROUP
+Error = UNSUPPORTED_ALGORITHM
# The same as above, but the cofactor is two instead of one.
PrivateKey = P-256-ExplicitParameters-CofactorTwo
Input = 308201610201003081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020102046d306b02010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
-Error = UNKNOWN_GROUP
+Error = UNSUPPORTED_ALGORITHM
# A zero ECDSA key, with the optional public key encoded.
PrivateKey = P-256-Zero
@@ -66,7 +66,7 @@
# The public half of the same key encoded as a PublicKey.
PublicKey = P-256-SPKI
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 3059301306072a8648ce3d020106082a8648ce3d030107034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
@@ -83,21 +83,21 @@
PrivateKey = P-224-ExplicitParameters
Input = 308201540201003081eb06072a8648ce3d02013081df020101302806072a8648ce3d0101021d00ffffffffffffffffffffffffffffffff0000000000000000000000013053041cfffffffffffffffffffffffffffffffefffffffffffffffffffffffe041cb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4031500bd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5043904b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34021d00ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d0201010461305f020101041caa17cf0a0c8064bf6b509c212e48293d61e0d97acc85f8dea5c99166a13c033a00041a95d8c8d08635ad7fa0facd3a9fe56f8f42451b58ea8a29f7d28b0fb214690b1149a69f016f644cdb3320b78a381027835d6091903f0513
-Type = EC
+Algorithm = EC-P-224
Bits = 224
ECCurve = secp224r1
Output = 3078020100301006072a8648ce3d020106052b810400210461305f020101041caa17cf0a0c8064bf6b509c212e48293d61e0d97acc85f8dea5c99166a13c033a00041a95d8c8d08635ad7fa0facd3a9fe56f8f42451b58ea8a29f7d28b0fb214690b1149a69f016f644cdb3320b78a381027835d6091903f0513
PrivateKey = P-384-ExplicitParameters
Input = 3082020c0201003082016406072a8648ce3d020130820157020101303c06072a8648ce3d0101023100fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff307b0430fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc0430b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef031500a335926aa319a27a1d00896a6773a4827acdac73046104aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab73617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f023100ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5297302010104819e30819b0201010430a29991b86091401328e62ec8caadd0482f887ff0936910e42a56c19f48cbe87331037a4e2b36f1091dd4a26ee2d2b01fa16403620004826b3df548ad2e0b96436cb13508e88745a33b4b06cf485ad8350824b4dfe01ee66a5e1d1aaebfebcaa6337a1f33c338afc0d59b7ce7e389f73f66c9c4a44bbfcf570aec5cc52e7b6608c9061ab4d72de933448c39dd9238177917d398c22c5e
-Type = EC
+Algorithm = EC-P-384
Bits = 384
ECCurve = secp384r1
Output = 3081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a29991b86091401328e62ec8caadd0482f887ff0936910e42a56c19f48cbe87331037a4e2b36f1091dd4a26ee2d2b01fa16403620004826b3df548ad2e0b96436cb13508e88745a33b4b06cf485ad8350824b4dfe01ee66a5e1d1aaebfebcaa6337a1f33c338afc0d59b7ce7e389f73f66c9c4a44bbfcf570aec5cc52e7b6608c9061ab4d72de933448c39dd9238177917d398c22c5e
PrivateKey = P-521-ExplicitParameters
Input = 308202b0020100308201d006072a8648ce3d0201308201c3020101304d06072a8648ce3d0101024201ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff30819f044201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc04420051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00031500d09e8800291cb85396cc6717393284aaa0da64ba0481850400c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650024201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913864090201010481d63081d30201010442002eeee9c16b9b4d2dee606f443cf3b41d2899a4734ff7555b54c735afb34a6912f81c68a89ea9b427c69a1026d98ef1d7f9c683aec5c5103d9a4c21e403c638412fa18189038186000400f58adcbe5c07f6b500fadd3209487e38f9567f97c2204435a4eb140739905c201407e2530a6667216aad01fb849bcbefa3862b2f187f13c9a87923d378a0a184df017b4bb93f4766531785878458da6aaa525724e10dfb1f35cfbe55c56fc705714295ea74b6c3e714152ad78e929f5415683aed9bc7c68f0329934177829d715f03f2
-Type = EC
+Algorithm = EC-P-521
Bits = 521
ECCurve = secp521r1
Output = 3081ee020100301006072a8648ce3d020106052b810400230481d63081d30201010442002eeee9c16b9b4d2dee606f443cf3b41d2899a4734ff7555b54c735afb34a6912f81c68a89ea9b427c69a1026d98ef1d7f9c683aec5c5103d9a4c21e403c638412fa18189038186000400f58adcbe5c07f6b500fadd3209487e38f9567f97c2204435a4eb140739905c201407e2530a6667216aad01fb849bcbefa3862b2f187f13c9a87923d378a0a184df017b4bb93f4766531785878458da6aaa525724e10dfb1f35cfbe55c56fc705714295ea74b6c3e714152ad78e929f5415683aed9bc7c68f0329934177829d715f03f2
@@ -167,13 +167,13 @@
# ECDH tests
PrivateKey = ECDH-P256-Private
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 3041020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104207d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534
PublicKey = ECDH-P256-Peer
-Type = EC
+Algorithm = EC-P-256
Bits = 256
ECCurve = prime256v1
Input = 3059301306072a8648ce3d020106082a8648ce3d03010703420004700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac
diff --git a/crypto/evp/test/ed25519_tests.txt b/crypto/evp/test/ed25519_tests.txt
index 5b0b216..56b23ab 100644
--- a/crypto/evp/test/ed25519_tests.txt
+++ b/crypto/evp/test/ed25519_tests.txt
@@ -2,58 +2,58 @@
# Private keys from RFC 8032.
PrivateKey = Ed25519
-Type = Ed25519
+Algorithm = Ed25519
Input = 302e020100300506032b6570042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
RawPrivate = 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
RawPublic = d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
PrivateKey = Ed25519-2
-Type = Ed25519
+Algorithm = Ed25519
Input = 302e020100300506032b6570042204204ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb
RawPrivate = 4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb
RawPublic = 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c
PrivateKey = Ed25519-3
-Type = Ed25519
+Algorithm = Ed25519
Input = 302e020100300506032b657004220420c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7
RawPrivate = c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7
RawPublic = fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025
PrivateKey = Ed25519-4
-Type = Ed25519
+Algorithm = Ed25519
Input = 302e020100300506032b657004220420f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5
RawPrivate = f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5
RawPublic = 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
PrivateKey = Ed25519-5
-Type = Ed25519
+Algorithm = Ed25519
Input = 302e020100300506032b657004220420833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42
RawPrivate = 833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42
RawPublic = ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf
# Public keys from RFC 8032.
PublicKey = Ed25519-SPKI
-Type = Ed25519
+Algorithm = Ed25519
Input = 302a300506032b6570032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
RawPublic = d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
PublicKey = Ed25519-SPKI-2
-Type = Ed25519
+Algorithm = Ed25519
Input = 302a300506032b65700321003d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c
RawPublic = 3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c
PublicKey = Ed25519-SPKI-3
-Type = Ed25519
+Algorithm = Ed25519
Input = 302a300506032b6570032100fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025
RawPublic = fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025
PublicKey = Ed25519-SPKI-4
-Type = Ed25519
+Algorithm = Ed25519
Input = 302a300506032b6570032100278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
RawPublic = 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
PublicKey = Ed25519-SPKI-5
-Type = Ed25519
+Algorithm = Ed25519
Input = 302a300506032b6570032100ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf
RawPublic = ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf
@@ -68,13 +68,13 @@
# Sample public key from RFC 8410.
PublicKey = Ed25519-SPKI-Spec
-Type = Ed25519
+Algorithm = Ed25519
Input = 302a300506032b657003210019bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1
RawPublic = 19bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1
# Sample private key from RFC 8410.
PrivateKey = Ed25519-Spec
-Type = Ed25519
+Algorithm = Ed25519
Input = 302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842
RawPublic = 19bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1
RawPrivate = d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842
diff --git a/crypto/evp/test/evp_tests.txt b/crypto/evp/test/evp_tests.txt
index 820f1d8..f6b15b8 100644
--- a/crypto/evp/test/evp_tests.txt
+++ b/crypto/evp/test/evp_tests.txt
@@ -20,7 +20,7 @@
# A DSA private key.
PrivateKey = DSA-2048
-Type = DSA
+Algorithm = DSA
Bits = 2048
Input = 308202650201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ffbc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610423022100b0c768702743bc51242993a971a52889795444f7c6452203d0ce84fe6117d46e
@@ -31,7 +31,7 @@
# A DSA public key.
PublicKey = DSA-1024-SPKI
-Type = DSA
+Algorithm = DSA
Bits = 1024
Input = 308201b73082012c06072a8648ce3804013082011f02818100b3429b8b128c9079f9b72e86857e98d265e5d91661ed8b5f4cc56e5eed1e571da30186983a9dd76297eab73ee13a1db841f8800d04a7cab478af6cde2ea4a2868531af169a24858c6268efa39ceb7ed0d4227eb5bbb01124a2a5a26038c7bcfb8cc827f68f5202345166e4718596799b65c9def82828ce44e62e38e41a0d24b1021500c5a56c81ddd87f47e676546c56d05706421624cf0281810094de40d27314fe929e47ff9b1ac65cfc73ef38c4d381c890be6217b15039ae18190e6b421af8c0bda35a5cfd050f58ae2644adce83e68c8e5ba11729df56bbb21e227a60b816cc033fa799a38fe1ba5b4aa1801b6f841ce3df99feb3b4fb96950c960af13fa2ce920aabc12dd24ad2044a35063ea0e25f67f560f4cfbdc5598303818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a
diff --git a/crypto/evp/test/rsa_tests.txt b/crypto/evp/test/rsa_tests.txt
index 4e28c86..902db0f 100644
--- a/crypto/evp/test/rsa_tests.txt
+++ b/crypto/evp/test/rsa_tests.txt
@@ -2,7 +2,7 @@
# RSA 2048 bit key.
PrivateKey = RSA-2048
-Type = RSA
+Algorithm = RSA
Bits = 2048
Input = 308204bc020100300d06092a864886f70d0101010500048204a6308204a20201000282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f02030100010282010060297ac7991b167a06d6b24758b8cbe208beb9b2d9ec9738bd80f90a2e35005dd7ce292d9e29ba885bd316fef1f20913bc0ac90d6b0808b2414d82104441d8624a33ce0233c8f780a48b375aff02d76712228a702484db3f9ebecccfbbee1709dba182800d949e9e4216e0bff3558388f8bd90da373a1d82743ec3fbdd1427fd16825a657a316912e8695365117ca2f845c909405fcac55f895fc15d20386c26ee78c9e99075029a178a6c1e4cf0c200e8a9cfb27e9d156f86e6c2adc22b1a84a1cd5ca5b2790875d79407c84b352395cb81cc3fed5bb043b69ede0c07204550025cee8c5f440170b6120bb48e0f747bcd8f522110850df043c428dfd187053102818100f6f961b47cbc035d3aedebc7de850a956b65ecdb9cf60764063f15aa48553c58d972fe6675056e35ddfdc37bf3b9f2f622ee271337256849c9bef2176fe8f7c3f8bb91ba374dd53baf3dec814d2bdec10c1fdc88cdd16876f26b1edfa3f094197edf4d42ff1fb2971103b898ca859c427287086a842ab410bb69cf2d35af6be302818100d47e724a7ff41048b270c2524a4101878b73159bb73d3dbc187b220e635b3534f96e243a184d93f860b6bfbb6b71c1ed9a1e1f458583023c301e96a692c1a08b53d0ec9ca910100d80451e3b7dc6a01bac4aecef8df798846bc235a08cbba2cf4c06804cc11219e95608c714e3f1430d491fadbba32a5751a04f97745834c9a502818021f2452bb9b95dfd028c914bf799f1ca77e89a95d50d3c16d384f8455f8bd7af9eb3dfa3d591d9842def235f7630a8e48c088ff6642e101794535a933e1e976fa8509fc728b2da0c4a1a08d7fcf37abaae1ff3001aca1dc1bbb05d9dffbaa1a09f7fb1eef38237d9ebccc722b9338436dde7119112798c26809c1a8dec4320610281801f7510aa62c2d8de4a3c53282781f41e02d0e8b402ae78432e449c48110161a11403f02d01880a8dcc938152d79721a4711a607ac4471ebf964810f95be47a45e60499e29f4c9773c83773404f606637728c2d0351bb03c326c8bb73a721e7fa5440ea2172bba1465fcc30dcb0d9f89930e815aa1f7f9729a857e00e0338dd590281804d1f0d756fe77e01099a652f50a88b7b685dc5bf00981d5d2376fd0c6fe29cd5b638734479305a73ad3c1599d39eae3bae035fbd6fed07c28de705933879a06e48e6a603686ed8e2560a5f6af1f2c24faf4aa960e382186f15eedce9a2491ae730680dd4cf778b70faa86826ab3223477cc91377b19a6d5a2eaea219760beed5
RSAParamN = cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f
@@ -16,7 +16,7 @@
# The public half of the same key encoded as a SubjectPublicKeyInfo.
PublicKey = RSA-2048-SPKI
-Type = RSA
+Algorithm = RSA
Bits = 2048
Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f0203010001
RSAParamN = cd0081ea7b2ae1ea06d59f7c73d9ffb94a09615c2e4ba7c636cef08dd3533ec3185525b015c769b99a77d6725bf9c3532a9b6e5f6627d5fb85160768d3dda9cbd35974511717dc3d309d2fc47ee41f97e32adb7f9dd864a1c4767a666ecd71bc1aacf5e7517f4b38594fea9b05e42d5ada9912008013e45316a4d9bb8ed086b88d28758bacaf922d46a868b485d239c9baeb0e2b64592710f42b2d1ea0a4b4802c0becab328f8a68b0073bdb546feea9809d2849912b390c1532bc7e29c7658f8175fae46f34332ff87bcab3e40649b98577869da0ea718353f0722754886913648760d122be676e0fc483dd20ffc31bda96a31966c9aa2e75ad03de47e1c44f
@@ -44,13 +44,13 @@
# RSA 512 bit key.
PrivateKey = RSA-512
-Type = RSA
+Algorithm = RSA
Bits = 512
Input = 30820154020100300d06092a864886f70d01010105000482013e3082013a020100024100dd20403d976a38c9d79152d87b5c8e9f05033eadd7b7de709bf5b0c4a5182a97d18483526b02362b992e154a9f37faa396ca2685cdab8fec09877ebe705f4dd70203010001024055bebcca655d7e39de8a6eaa9d636db682161907064039544755c53eeb99ec618c03a210dbc61471eaba10c5c365c9726d6b7a96f54d455f7d168d49367270e1022100f21a05d9fd6817301ce49ce10448f9bdd44f5ef5b7557cd7d83155db46382ae7022100e9d1f7157783db2feab1936954ddc4e83aa365695868144cda1be6813b61d791022100d6001eb0040920860ce41fafdf23ca6dfbdf74e6e9f98cf3164cf5c16f9e727d02206f6f73f4b52b10517be6f9bc5f87fa0a3bb817e2e711636b651f9af1c85d4f21022063eff2e57f5b4ca20342cfe793e25526624e3692f192461f9e1ce7f13f2d72c8
# RSA 515 bit key.
PrivateKey = RSA-515
-Type = RSA
+Algorithm = RSA
Bits = 515
Input = 30820157020100300d06092a864886f70d0101010500048201413082013d0201000241054fa166e205e658bbe8a2dc35311c0c2b75b7e4569fd9642c8bae809279271fc824f26baa1166ea46298ca63379ea76adbada2b61e5066820a35beaec1aca227f020301000102410266c972be0d30e53ac2acb1aa13b4bd0401cccf212452a66b4615f7e943831f67b4ca48560582d0ca886044aaaaf87945252a848c1947944186e6eb83969bf91102210309e631761842cc8a2ccfd372c20a9cba21de1a199c30ab440bc6b51079f4e825022101bf715c1db432627ca7c29a293b9210f2eff1e92d12f306ebaa5334f8ee03dcd30221018ac58a765f2b8f37d434081fe5ff92b81735ead2f263f4968ccf63d61fbe3d0d0221015b247a1159a2d5a25d0db049593c6405f77f3a278c521d066e290c2a2d8fb59d0221026224aa31fd95c14d24fd03b8a195bba4cc88df7c37f5370a5ab19f882f1404d6
@@ -463,7 +463,7 @@
# Though we will never generate such a key, test that RSA keys where p < q work
# properly.
PrivateKey = RSA-Swapped
-Type = RSA
+Algorithm = RSA
Input = 30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100ab28f98747934779011417d5bbb4095eae6f48ed09e13081616cf390aac75b10a206a98953d402647dfef7fa363be2765a303b05ec388bd9a1d75123a1205b4ecb43c33f2e37d3e30842181d694a3acfc39afc52554946e699d97d97066596a46725ce6dea322623afcafecbd2884d9a0c5eae9c4d7da8874c29c19edb762e1902030100010281800d637ea568e169f15ab6be288f6ec55edd29425c9c6dbb941b5160fa1b89cda34ef15378b5107c016d63b0f52721e71497f876dd7f3d6b1f228c4bc20c3c12384644200e91130c9195660d1e706f55b2accf00c5e2174a1d9ee289f0e763ee58860485ec97d19d7fa2df38af5b5910b1fa52087768d288e6ec4c8d5eca23c8d3024100be757a24dc2c923692d964693b2d71ca33ccb2f946f9e5232d2090b715a97dca554068fab8876105bc9ed6dccfd0917c5e0b80339306535c3eeb787e89397bc7024100e60f5c9e52434da079b8c641791a81a96daa4d9921a07e5b48292a9fce230df7c9fc2b97b5e38834ed5caaa387a0bca35c474e989a68dd65b79a6f691a74471f0240438ccf017bc5a3260ff76291a01782204136fcd344c524ebd0f997da17a8c1a09d93f6a7d602cdfa86e79f3539cfb389f4a1079b432e1f2abc762f8a51893dc9024046604ca4e1e554c9d27283b363a888219c3a8ca25b770d303f52d8872a37eefdedfc0619d2ba57e058fc0ff71676453e73ec1c4ef26d41ccebed824754a05d6102404445374d8450e753e0a42085b56b0d6d500b3e3518536dc8f12ec8fd77aa75491835327ac0e12d73b5c3f1b09d03f6a24fe63b9c551dee6559b625435ec92429
Sign = RSA-Swapped
@@ -484,7 +484,7 @@
# Though we will never generate such a key, test that RSA keys where p and q are
# different sizes work properly.
PrivateKey = RSA-PrimeMismatch
-Type = RSA
+Algorithm = RSA
Input = 30820295020100300d06092a864886f70d01010105000482027f3082027b02010002818100c766f4fef89f5e9a8e13ed500fb38523ea94d7f8be066900eee58c913b4c6fdcb13d63d39b9108feabcefd1ffd04776403dc58f968ae817977d0809e567d8af512d604a0e9cb448fa5e402204ee519712a5ebbfd002faf8169495a782f54366b4665aac0d968bfec63c5446b6f9b13061c7f3d1f3f1b6bede8fff881b410a66f0203010001028180528c062f49485c771a0b18ca747d8a47f8941ea63c305626cb3f1f067e6861c4441c432687dbd08d484aac3b01f3ffdc3b762c719167f7cb22e565aa6acd597306ef6f7828b9720e9d440816186d940c4c5a9720dddf71fe0b59483f02a751515c8c27e43c575d6725d55f5bb77e0f977773b00afc058cfab6617ec90d0b62a9026100cb8f97c37b4fbc298b645bc3dc0526f8a4274e9a193b33c3acb76499b5b96330e4b586cbaa56368ffc12644952322253bc669496d572c0980f125fd7273739cf790d24401052b13732114d397c8c16a44716dc62d2320fb1ced99290dfd53e07022100fac51ac653609cdaba53280c6b6f209052e270be0c3c68fe8b37d6bf05fbba59026038dff2f04c58d7e2e7ae6fb1469d2de954bc22cb0d77ac1be4fb0ca1a1d39d7240c4b357de4cde4bd68b30f8077e38771af1b25c7e60e48cd7d1337402e1fc460ab57046720918b8aa4589452196669119c7ba65e602d4bdc264a9fdce7c5f2b0220773af0180bdc8bb7938fa6230191bcb1e236b7d4248d347e9242e25fc0c0874102605c4894cde334889f5b52ed8f86a2ee9c1fbe4166287e24ce44f3093bff383962f08043842f6ff3e6002104b0e29442c4a4483c5d06e2254fbe5e3930de3d0e28af10e96c6e341a4b8859382dbba24536a38ae71118e3e22413a93f298a7f744c
Sign = RSA-PrimeMismatch
@@ -497,7 +497,7 @@
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
PublicKey = RSA-PSS-1
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d0030818902818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a21370203010001
Verify = RSA-PSS-1
@@ -537,7 +537,7 @@
Output = 2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af987fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b75f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa278982543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58
PublicKey = RSA-PSS-2
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d0030818902818101d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c90203010001
Verify = RSA-PSS-2
@@ -577,7 +577,7 @@
Output = 00475b1648f814a8dc0abdc37b5527f543b666bb6e39d30e5b49d3b876dccc58eac14e32a2d55c2616014456ad2f246fc8e3d560da3ddf379a1c0bd200f10221df078c219a151bc8d4ec9d2fc2564467811014ef15d8ea01c2ebbff8c2c8efab38096e55fcbe3285c7aa558851254faffa92c1c72b78758663ef4582843139d7a6
PublicKey = RSA-PSS-3
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d0030818902818102f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db674e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d98170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a4430203010001
Verify = RSA-PSS-3
@@ -617,7 +617,7 @@
Output = 012fafec862f56e9e92f60ab0c77824f4299a0ca734ed26e0644d5d222c7f0bde03964f8e70a5cb65ed44e44d56ae0edf1ff86ca032cc5dd4404dbb76ab854586c44eed8336d08d457ce6c03693b45c0f1efef93624b95b8ec169c616d20e5538ebc0b6737a6f82b4bc0570924fc6b35759a3348426279f8b3d7744e2d222426ce
PublicKey = RSA-PSS-4
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d00308189028181054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c37050203010001
Verify = RSA-PSS-4
@@ -657,7 +657,7 @@
Output = 00938dcb6d583046065f69c78da7a1f1757066a7fa75125a9d2929f0b79a60b627b082f11f5b196f28eb9daa6f21c05e5140f6aef1737d2023075c05ecf04a028c686a2ab3e7d5a0664f295ce12995e890908b6ad21f0839eb65b70393a7b5afd9871de0caa0cedec5b819626756209d13ab1e7bb9546a26ff37e9a51af9fd562e
PublicKey = RSA-PSS-5
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d003081890281810d10f661f29940f5ed39aa260966deb47843679d2b6fb25b3de370f3ac7c19916391fd25fb527ebfa6a4b4df45a1759d996c4bb4ebd18828c44fc52d0191871740525f47a4b0cc8da325ed8aa676b0d0f626e0a77f07692170acac8082f42faa7dc7cd123e730e31a87985204cabcbe6670d43a2dd2b2ddef5e05392fc213bc5070203010001
Verify = RSA-PSS-5
@@ -697,7 +697,7 @@
Output = 02802dccfa8dfaf5279bf0b4a29ba1b157611faeaaf419b8919d15941900c1339e7e92e6fae562c53e6cc8e84104b110bce03ad18525e3c49a0eadad5d3f28f244a8ed89edbafbb686277cfa8ae909714d6b28f4bf8e293aa04c41efe7c0a81266d5c061e2575be032aa464674ff71626219bd74cc45f0e7ed4e3ff96eee758e8f
PublicKey = RSA-PSS-6
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d00308189028181164ca31cff609f3a0e7101b039f2e4fe6dd37519ab98598d179e174996598071f47d3a04559158d7be373cf1aa53f0aa6ef09039e5678c2a4c63900514c8c4f8aaed5de12a5f10b09c311af8c0ffb5b7a297f2efc63b8d6b0510931f0b98e48bf5fc6ec4e7b8db1ffaeb08c38e02adb8f03a48229c99e969431f61cb8c4dc698d10203010001
Verify = RSA-PSS-6
@@ -737,7 +737,7 @@
Output = 0a40a16e2fe2b38d1df90546167cf9469c9e3c3681a3442b4b2c2f581deb385ce99fc6188bb02a841d56e76d301891e24560550fcc2a26b55f4ccb26d837d350a154bcaca8392d98fa67959e9727b78cad03269f56968fc56b68bd679926d83cc9cb215550645ccda31c760ff35888943d2d8a1d351e81e5d07b86182e751081ef
PublicKey = RSA-PSS-7
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d0030818902818137c9da4a66c8c408b8da27d0c9d79f8ccb1eafc1d2fe48746d940b7c4ef5dee18ad12647cefaa0c4b3188b221c515386759b93f02024b25ab9242f8357d8f3fd49640ee5e643eaf6c64deefa7089727c8ff03993333915c6ef21bf5975b6e50d118b51008ec33e9f01a0a545a10a836a43ddbca9d8b5c5d3548022d7064ea29ab30203010001
Verify = RSA-PSS-7
@@ -777,7 +777,7 @@
Output = 18da3cdcfe79bfb77fd9c32f377ad399146f0a8e810620233271a6e3ed3248903f5cdc92dc79b55d3e11615aa056a795853792a3998c349ca5c457e8ca7d29d796aa24f83491709befcfb1510ea513c92829a3f00b104f655634f320752e130ec0ccf6754ff893db302932bb025eb60e87822598fc619e0e981737a9a4c4152d33
PublicKey = RSA-PSS-8
-Type = RSA
+Algorithm = RSA
Input = 30819f300d06092a864886f70d010101050003818d00308189028181495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f0203010001
Verify = RSA-PSS-8
@@ -817,7 +817,7 @@
Output = 1ed1d848fb1edb44129bd9b354795af97a069a7a00d0151048593e0c72c3517ff9ff2a41d0cb5a0ac860d736a199704f7cb6a53986a88bbd8abcc0076a2ce847880031525d449da2ac78356374c536e343faa7cba42a5aaa6506087791c06a8e989335aed19bfab2d5e67e27fb0c2875af896c21b6e8e7309d04e4f6727e69463e
PublicKey = RSA-PSS-9
-Type = RSA
+Algorithm = RSA
Input = 3081df300d06092a864886f70d01010105000381cd003081c90281c100e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b0203010001
Verify = RSA-PSS-9
@@ -857,7 +857,7 @@
Output = a7fdb0d259165ca2c88d00bbf1028a867d337699d061193b17a9648e14ccbbaadeacaacdec815e7571294ebb8a117af205fa078b47b0712c199e3ad05135c504c24b81705115740802487992ffd511d4afc6b854491eb3f0dd523139542ff15c3101ee85543517c6a3c79417c67e2dd9aa741e9a29b06dcb593c2336b3670ae3afbac7c3e76e215473e866e338ca244de00b62624d6b9426822ceae9f8cc460895f41250073fd45c5a1e7b425c204a423a699159f6903e710b37a7bb2bc8049f
PublicKey = RSA-PSS-10
-Type = RSA
+Algorithm = RSA
Input = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a5dd867ac4cb02f90b9457d48c14a770ef991c56c39c0ec65fd11afa8937cea57b9be7ac73b45c0017615b82d622e318753b6027c0fd157be12f8090fee2a7adcd0eef759f88ba4997c7a42d58c9aa12cb99ae001fe521c13bb5431445a8d5ae4f5e4c7e948ac227d3604071f20e577e905fbeb15dfaf06d1de5ae6253d63a6a2120b31a5da5dabc9550600e20f27d3739e2627925fea3cc509f21dff04e6eea4549c540d6809ff9307eede91fff58733d8385a237d6d3705a33e391900992070df7adf1357cf7e3700ce3667de83f17b8df1778db381dce09cb4ad058a511001a738198ee27cf55a13b754539906582ec8b174bd58d5d1f3d767c613721ae050203010001
Verify = RSA-PSS-10
@@ -897,7 +897,7 @@
Output = 6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd818ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343ef34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c64088c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f
PrivateKey = RSA-OAEP-1
-Type = RSA
+Algorithm = RSA
Input = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb020301000102818053339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1024100d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d024100cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d7702400e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c102410095297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d7158302404f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1
Decrypt = RSA-OAEP-1
@@ -937,7 +937,7 @@
Output = 26521050844271
PrivateKey = RSA-OAEP-2
-Type = RSA
+Algorithm = RSA
Input = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818101947c7fce90425f47279e70851f25d5e62316fe8a1df19371e3e628e260543e4901ef6081f68c0b8141190d2ae8daba7d1250ec6db636e944ec3722877c7c1d0a67f14b1694c5f0379451a43e49a32dde83670b73da91a1c99bc23b436a60055c610f0baf99c1a079565b95a3f1526632d1d4da60f20eda25e653c4f002766f4502030100010281800823f20fadb5da89088a9d00893e21fa4a1b11fbc93c64a3be0baaea97fb3b93c3ff713704c19c963c1d107aae99054739f79e02e186de86f87a6ddefea6d8ccd1d3c81a47bfa7255be20601a4a4b2f08a167b5e279d715b1b455bdd7eab245941d9768b9acefb3ccda5952da3cee72525b4501663a8ee15c9e992d92462fe3902410159dbde04a33ef06fb608b80b190f4d3e22bcc13ac8e4a081033abfa416edb0b338aa08b57309ea5a5240e7dc6e54378c69414c31d97ddb1f406db3769cc41a430241012b652f30403b38b40995fd6ff41a1acc8ada70373236b7202d39b2ee30cfb46db09511f6f307cc61cc21606c18a75b8a62f822df031ba0df0dafd5506f568bd70240436ef508de736519c2da4c580d98c82cb7452a3fb5efadc3b9c7789a1bc6584f795addbbd32439c74686552ecb6c2c307a4d3af7f539eec157248c7b31f1a2550241012b15a89f3dfb2b39073e73f02bdd0c1a7b379dd435f05cdde2eff9e462948b7cec62ee9050d5e0816e0785a856b49108dcb75f3683874d1ca6329a19013066ff02400270db17d5914b018d76118b24389a7350ec836b0063a21721236fd8edb6d89b51e7eeb87b611b7132cb7ea7356c23151c1e7751507c786d9ee1794170a8c8e8
Decrypt = RSA-OAEP-2
@@ -977,7 +977,7 @@
Output = 8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0
PrivateKey = RSA-OAEP-3
-Type = RSA
+Algorithm = RSA
Input = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818102b58fec039a860700a4d7b6462f93e6cdd491161ddd74f4e810b40e3c1652006a5c277b2774c11305a4cbab5a78efa57e17a86df7a3fa36fc4b1d2249f22ec7c2dd6a463232accea906d66ebe80b5704b10729da6f833234abb5efdd4a292cbfad33b4d33fa7a14b8c397b56e3acd21203428b77cdfa33a6da706b3d8b0fc43e9020301000102818015b48a5b5683a94670e23b5718f814fa0e13f85038f50711182cba61510581f3d22c7e232ef937e22e551d68b86e2f8cb1aad8be2e488f5df7efd279e3f568d4eaf36f80cf7141ace60fcc9113fb6c4a841fd50bbc7c512ffcbeff21487aa811eb3ca8c62005346a86de86bfa1d8a948fd3f348c22eaadf333c3ce6ce13208fd024101bf01d216d73595cf0270c2beb78d40a0d8447d31da919a983f7eea781b77d85fe371b3e9373e7b69217d3150a02d8958de7fad9d555160958b4454127e0e7eaf0241018d3399658166db3829816d7b295416759e9c91987f5b2d8aecd63b04b48bd7b2fcf229bb7f8a6dc88ba13dd2e39ad55b6d1a06160708f9700be80b8fd3744ce7024006c0a249d20a6f2ee75c88b494d53f6aae99aa427c88c28b163a769445e5f390cf40c274fd6ea6329a5ce7c7ce03a2158396ee2a7845786e09e2885a9728e4e5024100d1d27c29fedd92d86c348edd0ccbfac14f746e051ce1d1811df35d61f2ee1c97d4bf2804802f6427187ba8e90a8af44243b4079b03445e602e29fa5193e64fe90241008cb2f756bd8941b1d3b770e5ad31ee373b28acda69ff9b6f40fe578b9f1afb85836f9627d37acff73c2779e634bb26011c2c8f7f3361ae2a9ea65ed689e3639a
Decrypt = RSA-OAEP-3
@@ -1017,7 +1017,7 @@
Output = 3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1
PrivateKey = RSA-OAEP-4
-Type = RSA
+Algorithm = RSA
Input = 30820277020100300d06092a864886f70d0101010500048202613082025d020100028181051240b6cc0004fa48d0134671c078c7c8dec3b3e2f25bc2564467339db38853d06b85eea5b2de353bff42ac2e46bc97fae6ac9618da9537a5c8f553c1e357625991d6108dcd7885fb3a25413f53efcad948cb35cd9b9ae9c1c67626d113d57dde4c5bea76bb5bb7de96c00d07372e9685a6d75cf9d239fa148d70931b5f3fb03902030100010281800411ffca3b7ca5e9e9be7fe38a85105e353896db05c5796aecd2a725161eb3651c8629a9b862b904d7b0c7b37f8cb5a1c2b54001018a00a1eb2cafe4ee4e9492c348bc2bedab4b9ebbf064e8eff322b9009f8eec653905f40df88a3cdc49d4567f75627d41aca624129b46a0b7c698e5e65f2b7ba102c749a10135b6540d04010241027458c19ec1636919e736c9af25d609a51b8f561d19c6bf6943dd1ee1ab8a4a3f232100bd40b88decc6ba235548b6ef792a11c9de823d0a7922c7095b6eba570102410210ee9b33ab61716e27d251bd465f4b35a1a232e2da00901c294bf22350ce490d099f642b5375612db63ba1f20386492bf04d34b3c22bceb909d13441b53b5139024039fa028b826e88c1121b750a8b242fa9a35c5b66bdfd1fa637d3cc48a84a4f457a194e7727e49f7bcc6e5a5a412657fc470c7322ebc37416ef458c307a8c09010241015d99a84195943979fa9e1be2c3c1b69f432f46fd03e47d5befbbbfd6b1d1371d83efb330a3e020942b2fed115e5d02be24fd92c9019d1cecd6dd4cf1e54cc899024101f0b7015170b3f5e42223ba30301c41a6d87cbb70e30cb7d3c67d25473db1f6cbf03e3f9126e3e97968279a865b2c2b426524cfc52a683d31ed30eb984be412ba
Decrypt = RSA-OAEP-4
@@ -1057,7 +1057,7 @@
Output = f22242751ec6b1
PrivateKey = RSA-OAEP-5
-Type = RSA
+Algorithm = RSA
Input = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281810aadf3f9c125e5d891f31ac448e993defe580f802b45f9d7f22ba5021e9c47576b5a1e68031ba9db4e6dabe4d96a1d6f3d267268cff408005f118efcadb99888d1c234467166b2a2b849a05a889c060ac0da0c5fae8b55f309ba62e703742fa0326f2d10b011021489ff497770190d895fd39f52293c39efd73a698bdab9f10ed902030100010281810256eb4cba7067f2d2be540dcdff4582a36b7d31d1c9099bb214b79848466a268f80f58a49ac04c0e3648934a0206c04537c19b236643a6082732144df75fa217588f794682be89168276dc726c5c0cbdb84d31bbf26d0a43af495717f7d528acfee341561f6ff3cae05c578f8470d9682f9c0d072f9f6068b56d5880f682be2c5024103b0d3962f6d17549cbfca11294348dcf0e7e39f8c2bc6824f2164b606d687860dae1e632393cfedf513228229069e2f60e4acd7e633a436063f82385f48993707024102e4c32e2f517269b7072309f00c0e31365f7ce28b236b82912df239abf39572cf0ed604b02982e53564c52d6a05397de5c052a2fddc141ef7189836346aeb331f024101e84b119d25161fa67b00256a5bd9b645d2b232ecb05b015180029a88622adc3f09b3aeacde6161ab7cde22c2ad26e7797df54e072cbd3b2673800b3e4338dbd5024100eb90aa1a40135b4cea07197cedc8819be1e7cbff2547662116f465a4a9f487ab12f3ba4fef13822265a65297d98b7bded9372e3ffe81a38b3e9600fed055754f0241012f7f8138f9404062eb85a42924520b38f5bb886a0196f48bb8dcea60fd92cc027f18e78158a34a5c5d5f860a0f6c04071a7d01312c065062f1eb48b79d1c83cb
Decrypt = RSA-OAEP-5
@@ -1097,7 +1097,7 @@
Output = 541e37b68b6c8872b84c02
PrivateKey = RSA-OAEP-6
-Type = RSA
+Algorithm = RSA
Input = 30820279020100300d06092a864886f70d0101010500048202633082025f02010002818112b17f6dad2ecd19ff46dc13f7860f09e0e0cfb677b38a52592305ceaf022c166db90d04ac29e33f7dd12d9faf66e0816bb63ead267cc7d46c17c37be214bca2a22d723a64e44407436b6fc965729aefc2554f376cd5dcea68293780a62bf39d0029485a160bbb9e5dc0972d21a504f52e5ee028aa416332f510b2e9cff5f722af02030100010281810295eca3560618369559cecd303aa9cfdafc1d9f06959df75ffef929aa896961bcd190dc6997eda7f5963e724d07b4dc11f3065e5ae97d96835112280b9084bb14f2a21ebd4e889d41b9c4132ec1956fcab8bb2fed0575884936522c5ff7d33261904824e7cadee4e0bb372d2457cf78e2bd1286228ff83f10731ce63c90cff3f9024104a6ce8b7358dfa69bdcf742617005afb5385f5f3a58a24ef74a22a8c05cb7cc38ebd4cc9d9a9d789a62cd0f60f0cb941d3423c9692efa4fe3adff290c4749a38b02410404c9a803371fedb4c5be39f3c00b009e5e08a63be1e40035cdaca5011cc701cf7eebcb99f0ffe17cfd0a4bf7befd2dd536ac946db797fdbc4abe8f29349b91ed024103961c8f760aa2bd5154c7aafd77225b3bacd0139ae7b5948ea3311fccd86fb95c75afa767284b9b2de559572f15d8d044c7eb83a1be5fadf2cc377c0d8475294b0241022197e066742196aabc03fa2feeb4e70b15cb787d617acd31bb75c7bc234ad706f7c48d2182d1f0ff9c228dcf41967b6c0ba6d2c0ad110a1b857831ec245e2cb102410401c4c0c53d45dbdb5e9d96d0fecf4275df0974bc4a0736b4a74c3269053efb686ace2406e22c9e058ddb4ae540627ae2fdb08261e8e7e4bcbc994daafa305c45
Decrypt = RSA-OAEP-6
@@ -1137,7 +1137,7 @@
Output = 50ba14be8462720279c306ba
PrivateKey = RSA-OAEP-7
-Type = RSA
+Algorithm = RSA
Input = 30820278020100300d06092a864886f70d0101010500048202623082025e020100028181311179f0bcfc9b9d3ca315d00ef30d7bdd3a2cfae9911bfedcb948b3a4782d0732b6ab44aa4bf03741a644dc01bec3e69b01a033e675d8acd7c4925c6b1aec3119051dfd89762d215d45475ffcb59f908148623f37177156f6ae86dd7a7c5f43dc1e1f908254058a284a5f06c0021793a87f1ac5feff7dcaee69c5e51a3789e3730203010001028181070cfcff2feb8276e27432c45dfee48f49b7917d6530e1f0ca3460f32e0276174487c56e22a45d2500d7775495219d7d165a9cf3bd92c32af9a98d8dc9cc296800adc94a0a54fb40f34291bf84ee8ea12b6f109359c6d3542a50f9c767f5cfff05a681c2e656fb77caaadb4be9468d8abcd4df98f58e86d2053fa1349f748e21b102410749262c111cd470ec2566e6b3732fc09329469aa19071d3b9c01906514c6f1d26baa14beab0971c8b7e611a4f79009d6fea776928ca25285b0de3643d1a3f8c71024106bc1e50e96c02bf636e9eea8b899bbebf7651de77dd474c3e9bc23bad8182b61904c7d97dfbebfb1e00108878b6e67e415391d67942c2b2bf9b4435f88b0cb023024103bc7ea7f0aab143abc6ce8b97118636a30172e4cfe02c8fa0dda3b7baaf90f8092982985525f488bdfcb4bd726e22639ac64a3092ab7ffcbf1d5334cfa50b5bf102410262a6aa29c2a3c67dc5346c06381afd987aa3cc93cfbfecf54fdd9f9d787d7f59a523d398979da137a2f6381fe94801f7c94da21518dc34cb40870c4697994ad90240649d4c17b6ee1721e772d0389a559c3d3cdf9550d457c46b037b74641b1d52166af8a213c8396206cdfba4422f18d6f61dbcb5d214c971bf482aeb976a7370c2
Decrypt = RSA-OAEP-7
@@ -1177,7 +1177,7 @@
Output = 2184827095d35c3f86f600e8e59754013296
PrivateKey = RSA-OAEP-8
-Type = RSA
+Algorithm = RSA
Input = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281815bdf0e30d321dda5147f882408fa69195480df8f80d3f6e8bf5818504f36427ca9b1f5540b9c65a8f6974cf8447a244d9280201bb49fcbbe6378d1944cd227e230f96e3d10f819dcef276c64a00b2a4b6701e7d01de5fabde3b1e9a0df82f4631359cd22669647fbb1717246134ed7b497cfffbdc42b59c73a96ed90166212dff702030100010281810f7d1e9e5aaa25fd13e4a0663ae144e0d15f5cd18bcdb09df2cc7e64e3c5e915ad62645304161d098c715bb7ab8bd01d07eaf3fed7c7ed08af2a8a62ef44ab16b320e14af72a48f96afe262a0ae4cf65e635e910790cd4ee5cea768a4b2639f7e6f677b3f0bb6be32b75747d8909036f0264f58d401cdba131716157a75ecf633102410a02ef8448d9fad8bbd0d004c8c2aa9751ef9721c1b0d03236a54b0df947cbaed5a255ee9e8e20d491ea1723fe094704a9762e88afd16ebb5994412ca966dc4f9f0241092d362e7ed3a0bfd9e9fd0e6c0301b6df29159cf50cc83b9b0cf4d6eea71a61e002b46e0ae9f2de62d25b5d7452d498b81c9ac6fc58593d4c3fb4f5d72dfbb0a9024107c71410af103962db367404e37ae850baa4e9c29dd92145815294a67c7d1c6ded263aa030a9b633ae50303e14035d1af014123eba687820308d8ebc85b6957d7d024100ae2c75380c02c016ad05891b3301de881f28ae1171182b6b2c83bea7c515eca9ca298c7b1cab5817a597068fc85060de4da8a016378aae43c7f967bcc37904b902410598d1059e3ada4f6320752c09d805ff7d1f1ae0d017aeeee9cefa0d7dd7ff775e44b578322f6405d6211da19519666aa87fdc4cd8c88f6b6e3d67e961dcbba3d0
Decrypt = RSA-OAEP-8
@@ -1217,7 +1217,7 @@
Output = 8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be
PrivateKey = RSA-OAEP-9
-Type = RSA
+Algorithm = RSA
Input = 30820397020100300d06092a864886f70d0101010500048203813082037d0201000281c100cf2cd41e34ca3a728ea5cb8aff64c36d27bdef5364e336fd68d3123c5a196a8c287013e853d5156d58d151954520fb4f6d7b17abb6817765909c576119659d902b1906ed8a2b10c155c24d124528dab9eeae379beac66e4a411786dcb8fd0062ebc030de1219a04c2a8c1b7dd3131e4d6b6caee2e31a5ed41ac1509b2ef1ee2ab18364be568ca941c25ecc84ff9d643b5ec1aaae102a20d73f479b780fd6da91075212d9eac03a0674d899eba2e431f4c44b615b6ba2232bd4b33baed73d625d02030100010281c0198c141e23715a92bccf6a119a5bc11389468d2811f548d727e17b4ab0eb986d6f211efb53b71f7ccbea87ee69c75ee615008c5332deb52bf390abdfbfe37d7205368159b2638c1de326e21d22251f0fb5848b3bf15005d2a74330f0afe916ee62ccc1344d1d83a709e60676273840f7f377424a5e0a4da75f01b31ff76819cf9cbfdd215243c3917c03ef38199312e567b3bf7aed3ab457f371ef8a1423f45b68c6e282ec111bba2833b987fd69fad83bc1b8c613c5e1ea16c11ed125ea7ec1026100fc8d6c04bec4eb9a8192ca7900cbe536e2e8b519decf33b2459798c6909df4f176db7d23190fc72b8865a718af895f1bcd9145298027423b605e70a47cf58390a8c3e88fc8c48e8b32e3da210dfbe3e881ea5674b6a348c21e93f9e55ea65efd026100d200d45e788aacea606a401d0460f87dd5c1027e12dc1a0d7586e8939d9cf789b40f51ac0442961de7d21cc21e05c83155c1f2aa9193387cfdf956cb48d153ba270406f9bbba537d4987d9e2f9942d7a14cbfffea74fecdda928d23e259f5ee1026100db16802f79a2f0d45f358d69fd33e44b81fae828622e93a54253e997d01b0743759da0e812b4aa4e6c8beab2328d5431955a418a67ff26a8c5c807a5da354e05ef31cc8cf758f463732950b03e265726fb94e39d6a572a26244ab08db75752ad026100a0a317cfe7df1423f87a6dee8451f4e2b4a67e5497f29b4f1e4e830b9fadd9401167026f5596e5a39c97817e0f5f16e27e19ec9902e01d7ea6fb9aa3c760afee1e381b69de6ac9c07585a06ad9c4ba00bf75c8ad2fa898a479e80ae294fed2a102600b21f335c353342eb44c3aa24445780c2d655b940174cae38c7c8a4e6493c0ba9fd303748267b083b9a7a6cb61e42db362b8c9896db7064e02ad5ae61587da15b4649c90594909feb37dbcb654beb7268ec801e5a8b4aa3911bebd88542f05be
Decrypt = RSA-OAEP-9
@@ -1257,7 +1257,7 @@
Output = b6b28ea2198d0c1008bc64
PrivateKey = RSA-OAEP-10
-Type = RSA
+Algorithm = RSA
Input = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb020301000102820100056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e7902818100ecf5aecd1e5515fffacbd75a2816c6ebf49018cdfb4638e185d66a7396b6f8090f8018c7fd95cc34b857dc17f0cc6516bb1346ab4d582cadad7b4103352387b70338d084047c9d9539b6496204b3dd6ea442499207bec01f964287ff6336c3984658336846f56e46861881c10233d2176bf15a5e96ddc780bc868aa77d3ce76902818100bc46c464fc6ac4ca783b0eb08a3c841b772f7e9b2f28babd588ae885e1a0c61e4858a0fb25ac299990f35be85164c259ba1175cdd7192707135184992b6c29b746dd0d2cabe142835f7d148cc161524b4a09946d48b828473f1ce76b6cb6886c345c03e05f41d51b5c3a90a3f24073c7d74a4fe25d9cf21c75960f3fc386318302818100c73564571d00fb15d08a3de9957a50915d7126e9442dacf42bc82e862e5673ff6a008ed4d2e374617df89f17a160b43b7fda9cb6b6b74218609815f7d45ca263c159aa32d272d127faf4bc8ca2d77378e8aeb19b0ad7da3cb3de0ae7314980f62b6d4b0a875d1df03c1bae39ccd833ef6cd7e2d9528bf084d1f969e794e9f6c10281802658b37f6df9c1030be1db68117fa9d87e39ea2b693b7e6d3a2f70947413eec6142e18fb8dfcb6ac545d7c86a0ad48f8457170f0efb26bc48126c53efd1d16920198dc2a1107dc282db6a80cd3062360ba3fa13f70e4312ff1a6cd6b8fc4cd9c5c3db17c6d6a57212f73ae29f619327bad59b153858585ba4e28b60a62a45e490281806f38526b3925085534ef3e415a836ede8b86158a2c7cbfeccb0bd834304fec683ba8d4f479c433d43416e63269623cea100776d85aff401d3fff610ee65411ce3b1363d63a9709eede42647cea561493d54570a879c18682cd97710b96205ec31117d73b5f36223fadd6e8ba90dd7c0ee61d44e163251e20c7f66eb305117cb8
Decrypt = RSA-OAEP-10
diff --git a/crypto/evp/test/x25519_tests.txt b/crypto/evp/test/x25519_tests.txt
index 9e9690a..96dbbf7 100644
--- a/crypto/evp/test/x25519_tests.txt
+++ b/crypto/evp/test/x25519_tests.txt
@@ -1,18 +1,18 @@
# EVP X25519 tests
PrivateKey = X25519-Private
-Type = X25519
+Algorithm = X25519
Input = 302e020100300506032b656e04220420a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4
RawPublic = 1c9fd88f45606d932a80c71824ae151d15d73e77de38e8e000852e614fae7019
RawPrivate = a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4
PublicKey = X25519-Peer
-Type = X25519
+Algorithm = X25519
Input = 302a300506032b656e032100e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c
RawPublic = e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c
PublicKey = X25519-SmallOrderPeer
-Type = X25519
+Algorithm = X25519
RawPublic = e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800
Input = 302a300506032b656e032100e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800
diff --git a/include/openssl/base.h b/include/openssl/base.h
index 95cc15d..ae422d5 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -330,6 +330,7 @@
typedef struct evp_hpke_kdf_st EVP_HPKE_KDF;
typedef struct evp_hpke_kem_st EVP_HPKE_KEM;
typedef struct evp_hpke_key_st EVP_HPKE_KEY;
+typedef struct evp_pkey_alg_st EVP_PKEY_ALG;
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
typedef struct evp_pkey_st EVP_PKEY;
typedef struct hmac_ctx_st HMAC_CTX;
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 260db82..73ca73f 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -76,6 +76,13 @@
// parameters or zero if not, or if the algorithm doesn't take parameters.
OPENSSL_EXPORT int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns
+// one if they match, zero if not, or a negative number on error.
+//
+// WARNING: the return value differs from the usual return value convention.
+OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a,
+ const EVP_PKEY *b);
+
// EVP_PKEY_size returns the maximum size, in bytes, of a signature signed by
// |pkey|. For an RSA key, this returns the number of bytes needed to represent
// the modulus. For an EC key, this returns the maximum size of a DER-encoded
@@ -87,11 +94,85 @@
// length of the group order.
OPENSSL_EXPORT int EVP_PKEY_bits(const EVP_PKEY *pkey);
+// The following constants are returned by |EVP_PKEY_id| and specify the type of
+// key.
+#define EVP_PKEY_NONE NID_undef
+#define EVP_PKEY_RSA NID_rsaEncryption
+#define EVP_PKEY_RSA_PSS NID_rsassaPss
+#define EVP_PKEY_DSA NID_dsa
+#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
+#define EVP_PKEY_ED25519 NID_ED25519
+#define EVP_PKEY_X25519 NID_X25519
+#define EVP_PKEY_HKDF NID_hkdf
+#define EVP_PKEY_DH NID_dhKeyAgreement
+
// EVP_PKEY_id returns the type of |pkey|, which is one of the |EVP_PKEY_*|
-// values.
+// values above. These type values generally corresond to the algorithm OID, but
+// not the parameters, of a SubjectPublicKeyInfo (RFC 5280) or PrivateKeyInfo
+// (RFC 5208) AlgorithmIdentifier. Algorithm parameters can be inspected with
+// algorithm-specific accessors, e.g. |EVP_PKEY_get_ec_curve_nid|.
OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey);
+// Algorithms.
+//
+// An |EVP_PKEY| may carry a key from one of several algorithms, represented by
+// |EVP_PKEY_ALG|. |EVP_PKEY_ALG|s are used by functions that construct
+// |EVP_PKEY|s, such as parsing, so that callers can specify the algorithm(s) to
+// use.
+//
+// Each |EVP_PKEY_ALG| generally corresponds to the AlgorithmIdentifier of a
+// SubjectPublicKeyInfo (RFC 5280) or PrivateKeyInfo (RFC 5208), but some may
+// support multiple sets of AlgorithmIdentifier parameters, while others may be
+// specific to one parameter.
+
+// EVP_pkey_rsa implements RSA keys (RFC 8017), encoded as rsaEncryption (RFC
+// 3279, Section 2.3.1). The rsaEncryption encoding is confusingly named: these
+// keys are used for all RSA operations, including signing. The |EVP_PKEY_id|
+// value is |EVP_PKEY_RSA|.
+//
+// WARNING: This |EVP_PKEY_ALG| accepts all RSA key sizes supported by
+// BoringSSL. When parsing RSA keys, callers should check the size is within
+// their desired bounds with |EVP_PKEY_bits|. RSA public key operations scale
+// quadratically and RSA private key operations scale cubicly, so key sizes may
+// be a DoS vector.
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_rsa(void);
+
+// EVP_pkey_ec_* implement EC keys, encoded as id-ecPublicKey (RFC 5480,
+// Section 2.1.1). The id-ecPublicKey encoding is confusingly named: it is also
+// used for private keys (RFC 5915). The |EVP_PKEY_id| value is |EVP_PKEY_EC|.
+//
+// Each function only supports the specified curve, but curves are not reflected
+// in |EVP_PKEY_id|. The curve can be inspected with
+// |EVP_PKEY_get_ec_curve_nid|.
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p224(void);
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p256(void);
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p384(void);
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p521(void);
+
+// EVP_pkey_x25519 implements X25519 keys (RFC 7748), encoded as in RFC 8410.
+// The |EVP_PKEY_id| value is |EVP_PKEY_X25519|.
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_x25519(void);
+
+// EVP_pkey_ed25519 implements Ed25519 keys (RFC 8032), encoded as in RFC 8410.
+// The |EVP_PKEY_id| value is |EVP_PKEY_ED25519|.
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ed25519(void);
+
+// EVP_pkey_dsa implements DSA keys, encoded as in RFC 3279, Section 2.3.2. The
+// |EVP_PKEY_id| value is |EVP_PKEY_DSA|. This |EVP_PKEY_ALG| accepts all DSA
+// parameters supported by BoringSSL.
+//
+// Keys of this type are not usable with any operations, though the underlying
+// |DSA| object can be extracted with |EVP_PKEY_get0_DSA|. This key type is
+// deprecated and only implemented for compatibility with legacy applications.
+//
+// TODO(crbug.com/42290364): We didn't wire up |EVP_PKEY_sign| and
+// |EVP_PKEY_verify| just so it was auditable which callers used DSA. Once DSA
+// is removed from the default SPKI and PKCS#8 parser and DSA users explicitly
+// request |EVP_pkey_dsa|, we could change that.
+OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_dsa(void);
+
+
// Getting and setting concrete key types.
//
// The following functions get and set the underlying key representation in an
@@ -127,34 +208,36 @@
OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey);
-#define EVP_PKEY_NONE NID_undef
-#define EVP_PKEY_RSA NID_rsaEncryption
-#define EVP_PKEY_RSA_PSS NID_rsassaPss
-#define EVP_PKEY_DSA NID_dsa
-#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
-#define EVP_PKEY_ED25519 NID_ED25519
-#define EVP_PKEY_X25519 NID_X25519
-#define EVP_PKEY_HKDF NID_hkdf
-#define EVP_PKEY_DH NID_dhKeyAgreement
-
-// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns
-// one if they match, zero if not, or a negative number of on error.
-//
-// WARNING: the return value differs from the usual return value convention.
-OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a,
- const EVP_PKEY *b);
-
// ASN.1 functions
+// EVP_PKEY_from_subject_public_key_info decodes a DER-encoded
+// SubjectPublicKeyInfo structure (RFC 5280) from |in|. It returns a
+// newly-allocated |EVP_PKEY| or NULL on error. Only the |num_algs| algorithms
+// in |algs| will be considered when parsing.
+OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_subject_public_key_info(
+ const uint8_t *in, size_t len, const EVP_PKEY_ALG *const *algs,
+ size_t num_algs);
+
// EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure
// (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated
-// |EVP_PKEY| or NULL on error. If the key is an EC key, the curve is guaranteed
-// to be set.
+// |EVP_PKEY| or NULL on error.
//
-// The caller must check the type of the parsed public key to ensure it is
-// suitable and validate other desired key properties such as RSA modulus size
-// or EC curve.
+// Prefer |EVP_PKEY_from_subject_public_key_info| instead. This function has
+// several pitfalls:
+//
+// Callers are expected to handle trailing data retuned from |cbs|, making more
+// common cases error-prone.
+//
+// There is also no way to pass in supported algorithms. This function instead
+// supports some default set of algorithms. Future versions of BoringSSL may add
+// to this list, based on the needs of the other callers. Conversely, some
+// algorithms may be intentionally omitted, if they cause too much risk to
+// existing callers.
+//
+// This means callers must check the type of the parsed public key to ensure it
+// is suitable and validate other desired key properties such as RSA modulus
+// size or EC curve.
OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs);
// EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo
@@ -162,19 +245,41 @@
// success and zero on error.
OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key);
+// EVP_PKEY_from_private_key_info decodes a DER-encoded PrivateKeyInfo structure
+// (RFC 5208) from |in|. It returns a newly-allocated |EVP_PKEY| or NULL on
+// error. Only the |num_algs| algorithms in |algs| will be considered when
+// parsing.
+//
+// A PrivateKeyInfo ends with an optional set of attributes. These are silently
+// ignored.
+OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_private_key_info(
+ const uint8_t *in, size_t len, const EVP_PKEY_ALG *const *algs,
+ size_t num_algs);
+
// EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC
// 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY|
// or NULL on error.
//
-// The caller must check the type of the parsed private key to ensure it is
-// suitable and validate other desired key properties such as RSA modulus size
-// or EC curve. In particular, RSA private key operations scale cubicly, so
+// Prefer |EVP_PKEY_from_private_key_info| instead. This function has
+// several pitfalls:
+//
+// Callers are expected to handle trailing data retuned from |cbs|, making more
+// common cases error-prone.
+//
+// There is also no way to pass in supported algorithms. This function instead
+// supports some default set of algorithms. Future versions of BoringSSL may add
+// to this list, based on the needs of the other callers. Conversely, some
+// algorithms may be intentionally omitted, if they cause too much risk to
+// existing callers.
+//
+// This means the caller must check the type of the parsed private key to ensure
+// it is suitable and validate other desired key properties such as RSA modulus
+// size or EC curve. In particular, RSA private key operations scale cubicly, so
// applications accepting RSA private keys from external sources may need to
// bound key sizes (use |EVP_PKEY_bits| or |RSA_bits|) to avoid a DoS vector.
//
-// A PrivateKeyInfo ends with an optional set of attributes. These are not
-// processed and so this function will silently ignore any trailing data in the
-// structure.
+// A PrivateKeyInfo ends with an optional set of attributes. These are silently
+// ignored.
OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs);
// EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo