diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c index af78d5420..8d9fc5a59 100644 --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c @@ -524,51 +524,15 @@ struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key, struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) { - EVP_PKEY_CTX *kctx = NULL; - EC_KEY *ec_params = NULL; - EVP_PKEY *params = NULL, *key = NULL; - int nid; + struct crypto_ec_key *key; wpa_printf(MSG_DEBUG, "DPP: Generating a keypair"); - nid = OBJ_txt2nid(curve->name); - if (nid == NID_undef) { - wpa_printf(MSG_INFO, "DPP: Unsupported curve %s", curve->name); - return NULL; - } + key = crypto_ec_key_gen(curve->ike_group); + if (key && wpa_debug_show_keys) + dpp_debug_print_key("Own generated key", key); - ec_params = EC_KEY_new_by_curve_name(nid); - if (!ec_params) { - wpa_printf(MSG_ERROR, - "DPP: Failed to generate EC_KEY parameters"); - goto fail; - } - EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE); - params = EVP_PKEY_new(); - if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) { - wpa_printf(MSG_ERROR, - "DPP: Failed to generate EVP_PKEY parameters"); - goto fail; - } - - kctx = EVP_PKEY_CTX_new(params, NULL); - if (!kctx || - EVP_PKEY_keygen_init(kctx) != 1 || - EVP_PKEY_keygen(kctx, &key) != 1) { - wpa_printf(MSG_ERROR, "DPP: Failed to generate EC key"); - key = NULL; - goto fail; - } - - if (wpa_debug_show_keys) - dpp_debug_print_key("Own generated key", - (struct crypto_ec_key *) key); - -fail: - EC_KEY_free(ec_params); - EVP_PKEY_free(params); - EVP_PKEY_CTX_free(kctx); - return (struct crypto_ec_key *) key; + return key; } diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index b34ad043b..449b11525 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -994,22 +994,29 @@ struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len); */ struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len); +/** + * crypto_ec_key_gen - Generate EC key pair + * @group: Identifying number for the ECC group + * Returns: EC key or %NULL on failure + */ +struct crypto_ec_key * crypto_ec_key_gen(int group); + /** * crypto_ec_key_deinit - Free EC key - * @key: EC key from crypto_ec_key_parse_pub() or crypto_ec_key_parse_priv() + * @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen() */ void crypto_ec_key_deinit(struct crypto_ec_key *key); /** * crypto_ec_key_get_subject_public_key - Get SubjectPublicKeyInfo ASN.1 for an EC key - * @key: EC key from crypto_ec_key_parse_pub() or crypto_ec_key_parse_priv() + * @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen() * Returns: Buffer with DER encoding of ASN.1 SubjectPublicKeyInfo or %NULL on failure */ struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key); /** * crypto_ec_key_sign - Sign a buffer with an EC key - * @key: EC key from crypto_ec_key_parse_priv() + * @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen() * @data: Data to sign * @len: Length of @data buffer * Returns: Buffer with DER encoding of ASN.1 Ecdsa-Sig-Value or %NULL on failure @@ -1019,7 +1026,7 @@ struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, /** * crypto_ec_key_verify_signature - Verify ECDSA signature - * @key: EC key from crypto_ec_key_parse_pub() + * @key: EC key from crypto_ec_key_parse_pub() or crypto_ec_key_gen() * @data: Data to be signed * @len: Length of @data buffer * @sig: DER encoding of ASN.1 Ecdsa-Sig-Value @@ -1031,7 +1038,7 @@ int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, /** * crypto_ec_key_group - Get IANA group identifier for an EC key - * @key: EC key from crypto_ec_key_parse_pub() or crypto_ec_key_parse_priv() + * @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen() * Returns: IANA group identifier and -1 on failure */ int crypto_ec_key_group(struct crypto_ec_key *key); diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index 6e2afe229..9ba7fc50c 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -1640,51 +1640,51 @@ struct crypto_ec { BIGNUM *b; }; + +static int crypto_ec_group_2_nid(int group) +{ + /* Map from IANA registry for IKE D-H groups to OpenSSL NID */ + switch (group) { + case 19: + return NID_X9_62_prime256v1; + case 20: + return NID_secp384r1; + case 21: + return NID_secp521r1; + case 25: + return NID_X9_62_prime192v1; + case 26: + return NID_secp224r1; +#ifdef NID_brainpoolP224r1 + case 27: + return NID_brainpoolP224r1; +#endif /* NID_brainpoolP224r1 */ +#ifdef NID_brainpoolP256r1 + case 28: + return NID_brainpoolP256r1; +#endif /* NID_brainpoolP256r1 */ +#ifdef NID_brainpoolP384r1 + case 29: + return NID_brainpoolP384r1; +#endif /* NID_brainpoolP384r1 */ +#ifdef NID_brainpoolP512r1 + case 30: + return NID_brainpoolP512r1; +#endif /* NID_brainpoolP512r1 */ + default: + return -1; + } +} + + struct crypto_ec * crypto_ec_init(int group) { struct crypto_ec *e; int nid; - /* Map from IANA registry for IKE D-H groups to OpenSSL NID */ - switch (group) { - case 19: - nid = NID_X9_62_prime256v1; - break; - case 20: - nid = NID_secp384r1; - break; - case 21: - nid = NID_secp521r1; - break; - case 25: - nid = NID_X9_62_prime192v1; - break; - case 26: - nid = NID_secp224r1; - break; -#ifdef NID_brainpoolP224r1 - case 27: - nid = NID_brainpoolP224r1; - break; -#endif /* NID_brainpoolP224r1 */ -#ifdef NID_brainpoolP256r1 - case 28: - nid = NID_brainpoolP256r1; - break; -#endif /* NID_brainpoolP256r1 */ -#ifdef NID_brainpoolP384r1 - case 29: - nid = NID_brainpoolP384r1; - break; -#endif /* NID_brainpoolP384r1 */ -#ifdef NID_brainpoolP512r1 - case 30: - nid = NID_brainpoolP512r1; - break; -#endif /* NID_brainpoolP512r1 */ - default: + nid = crypto_ec_group_2_nid(group); + if (nid < 0) return NULL; - } e = os_zalloc(sizeof(*e)); if (e == NULL) @@ -2242,6 +2242,50 @@ fail: } +struct crypto_ec_key * crypto_ec_key_gen(int group) +{ + EVP_PKEY_CTX *kctx = NULL; + EC_KEY *ec_params = NULL; + EVP_PKEY *params = NULL, *key = NULL; + int nid; + + nid = crypto_ec_group_2_nid(group); + if (nid < 0) { + wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group); + return NULL; + } + + ec_params = EC_KEY_new_by_curve_name(nid); + if (!ec_params) { + wpa_printf(MSG_ERROR, + "OpenSSL: Failed to generate EC_KEY parameters"); + goto fail; + } + EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE); + params = EVP_PKEY_new(); + if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) { + wpa_printf(MSG_ERROR, + "OpenSSL: Failed to generate EVP_PKEY parameters"); + goto fail; + } + + kctx = EVP_PKEY_CTX_new(params, NULL); + if (!kctx || + EVP_PKEY_keygen_init(kctx) != 1 || + EVP_PKEY_keygen(kctx, &key) != 1) { + wpa_printf(MSG_ERROR, "OpenSSL: Failed to generate EC key"); + key = NULL; + goto fail; + } + +fail: + EC_KEY_free(ec_params); + EVP_PKEY_free(params); + EVP_PKEY_CTX_free(kctx); + return (struct crypto_ec_key *) key; +} + + void crypto_ec_key_deinit(struct crypto_ec_key *key) { EVP_PKEY_free((EVP_PKEY *) key);