Remove some unnecessary dependencies on EVP_PKEY_set_type

EVP_PKEY_set_type needs to pull in every supported EVP_PKEY type, but
most of our calls within the library already know what type they're
working with. Have them call evp_pkey_set_method directly.

Bug: 497
Change-Id: I17cb9a0dff0da55206686bce1d8e1df4773f6f4d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/67127
Reviewed-by: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
fips-20240407
David Benjamin 8 months ago committed by Boringssl LUCI CQ
parent b85a0d1ebe
commit fea4c97491
  1. 7
      crypto/evp/evp.c
  2. 25
      crypto/evp/evp_asn1.c
  3. 4
      crypto/evp/internal.h
  4. 5
      crypto/evp/p_ed25519.c
  5. 5
      crypto/evp/p_x25519.c

@ -149,9 +149,7 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
if (to->type == EVP_PKEY_NONE) {
if (!EVP_PKEY_set_type(to, from->type)) {
return 0;
}
evp_pkey_set_method(to, from->ameth);
} else if (to->type != from->type) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
return 0;
@ -225,8 +223,7 @@ static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) {
}
}
static void evp_pkey_set_method(EVP_PKEY *pkey,
const EVP_PKEY_ASN1_METHOD *method) {
void evp_pkey_set_method(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method) {
free_it(pkey);
pkey->ameth = method;
pkey->type = pkey->ameth->pkey_id;

@ -77,28 +77,26 @@ static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
&x25519_asn1_meth,
};
static int parse_key_type(CBS *cbs, int *out_type) {
static const EVP_PKEY_ASN1_METHOD *parse_key_type(CBS *cbs) {
CBS oid;
if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) {
return 0;
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) {
*out_type = method->pkey_id;
return 1;
return method;
}
}
return 0;
return NULL;
}
EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
// Parse the SubjectPublicKeyInfo.
CBS spki, algorithm, key;
int type;
uint8_t padding;
if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
@ -107,7 +105,8 @@ EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return NULL;
}
if (!parse_key_type(&algorithm, &type)) {
const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm);
if (method == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
return NULL;
}
@ -121,10 +120,10 @@ EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
// Set up an |EVP_PKEY| of the appropriate type.
EVP_PKEY *ret = EVP_PKEY_new();
if (ret == NULL ||
!EVP_PKEY_set_type(ret, type)) {
if (ret == NULL) {
goto err;
}
evp_pkey_set_method(ret, method);
// Call into the type-specific SPKI decoding function.
if (ret->ameth->pub_decode == NULL) {
@ -155,7 +154,6 @@ EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
// Parse the PrivateKeyInfo.
CBS pkcs8, algorithm, key;
uint64_t version;
int type;
if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1_uint64(&pkcs8, &version) ||
version != 0 ||
@ -164,7 +162,8 @@ EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return NULL;
}
if (!parse_key_type(&algorithm, &type)) {
const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm);
if (method == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
return NULL;
}
@ -173,10 +172,10 @@ EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
// Set up an |EVP_PKEY| of the appropriate type.
EVP_PKEY *ret = EVP_PKEY_new();
if (ret == NULL ||
!EVP_PKEY_set_type(ret, type)) {
if (ret == NULL) {
goto err;
}
evp_pkey_set_method(ret, method);
// Call into the type-specific PrivateKeyInfo decoding function.
if (ret->ameth->priv_decode == NULL) {

@ -295,6 +295,10 @@ extern const EVP_PKEY_METHOD ed25519_pkey_meth;
extern const EVP_PKEY_METHOD x25519_pkey_meth;
extern const EVP_PKEY_METHOD hkdf_pkey_meth;
// evp_pkey_set_method behaves like |EVP_PKEY_set_type|, but takes a pointer to
// a method table. This avoids depending on every |EVP_PKEY_ASN1_METHOD|.
void evp_pkey_set_method(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method);
#if defined(__cplusplus)
} // extern C

@ -30,10 +30,7 @@ static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
return 0;
}
if (!EVP_PKEY_set_type(pkey, EVP_PKEY_ED25519)) {
OPENSSL_free(key);
return 0;
}
evp_pkey_set_method(pkey, &ed25519_asn1_meth);
uint8_t pubkey_unused[32];
ED25519_keypair(pubkey_unused, key->key);

@ -30,10 +30,7 @@ static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
return 0;
}
if (!EVP_PKEY_set_type(pkey, EVP_PKEY_X25519)) {
OPENSSL_free(key);
return 0;
}
evp_pkey_set_method(pkey, &x25519_asn1_meth);
X25519_keypair(key->pub, key->priv);
key->has_private = 1;

Loading…
Cancel
Save