[PATCH 07/21] dpp: move dpp_set_pubkey_point_group to crypto.h

Cedric Izoard cedric.izoard at ceva-dsp.com
Mon Jun 28 09:25:24 PDT 2021


From: Cedric Izoard <cedric.izoard at laposte.net>

Move code of dpp_set_pubkey_point_group into crypto.h API.
This function initializes an EC Public key using coordinates of the EC
point in binary format.

Signed-off-by: Cedric Izoard <cedric.izoard at ceva-dsp.com>
---
 src/common/dpp.c            | 15 ++----
 src/common/dpp_crypto.c     | 99 +++----------------------------------
 src/common/dpp_i.h          |  3 --
 src/crypto/crypto.h         | 19 +++++--
 src/crypto/crypto_openssl.c | 79 +++++++++++++++++++++++++++++
 5 files changed, 106 insertions(+), 109 deletions(-)

diff --git a/src/common/dpp.c b/src/common/dpp.c
index a2a686211..8fa662bf4 100644
--- a/src/common/dpp.c
+++ b/src/common/dpp.c
@@ -2166,8 +2166,7 @@ struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
 	struct json_token *token;
 	const struct dpp_curve_params *curve;
 	struct wpabuf *x = NULL, *y = NULL;
-	EC_GROUP *group;
-	struct crypto_ec_key *pkey = NULL;
+	struct crypto_ec_key *key = NULL;
 
 	token = json_get_member(jwk, "kty");
 	if (!token || token->type != JSON_STRING) {
@@ -2220,22 +2219,18 @@ struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
 		goto fail;
 	}
 
-	group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
-	if (!group) {
-		wpa_printf(MSG_DEBUG, "DPP: Could not prepare group for JWK");
+	key = crypto_ec_key_set_pub(curve->ike_group, wpabuf_head(x), wpabuf_head(y),
+				    wpabuf_len(x));
+	if (!key)
 		goto fail;
-	}
 
-	pkey = dpp_set_pubkey_point_group(group, wpabuf_head(x), wpabuf_head(y),
-					  wpabuf_len(x));
-	EC_GROUP_free(group);
 	*key_curve = curve;
 
 fail:
 	wpabuf_free(x);
 	wpabuf_free(y);
 
-	return pkey;
+	return key;
 }
 
 
diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c
index 5e7cd76ea..e274ee95f 100644
--- a/src/common/dpp_crypto.c
+++ b/src/common/dpp_crypto.c
@@ -375,100 +375,21 @@ int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len)
 }
 
 
-struct crypto_ec_key * dpp_set_pubkey_point_group(const EC_GROUP *group,
-						  const u8 *buf_x, const u8 *buf_y,
-						  size_t len)
-{
-	EC_KEY *eckey = NULL;
-	BN_CTX *ctx;
-	EC_POINT *point = NULL;
-	BIGNUM *x = NULL, *y = NULL;
-	EVP_PKEY *pkey = NULL;
-
-	ctx = BN_CTX_new();
-	if (!ctx) {
-		wpa_printf(MSG_ERROR, "DPP: Out of memory");
-		return NULL;
-	}
-
-	point = EC_POINT_new(group);
-	x = BN_bin2bn(buf_x, len, NULL);
-	y = BN_bin2bn(buf_y, len, NULL);
-	if (!point || !x || !y) {
-		wpa_printf(MSG_ERROR, "DPP: Out of memory");
-		goto fail;
-	}
-
-	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: OpenSSL: EC_POINT_set_affine_coordinates_GFp failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-
-	if (!EC_POINT_is_on_curve(group, point, ctx) ||
-	    EC_POINT_is_at_infinity(group, point)) {
-		wpa_printf(MSG_ERROR, "DPP: Invalid point");
-		goto fail;
-	}
-	dpp_debug_print_point("DPP: dpp_set_pubkey_point_group", group, point);
-
-	eckey = EC_KEY_new();
-	if (!eckey ||
-	    EC_KEY_set_group(eckey, group) != 1 ||
-	    EC_KEY_set_public_key(eckey, point) != 1) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Failed to set EC_KEY: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-	EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
-
-	pkey = EVP_PKEY_new();
-	if (!pkey || EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) {
-		wpa_printf(MSG_ERROR, "DPP: Could not create EVP_PKEY");
-		goto fail;
-	}
-
-out:
-	BN_free(x);
-	BN_free(y);
-	EC_KEY_free(eckey);
-	EC_POINT_free(point);
-	BN_CTX_free(ctx);
-	return (struct crypto_ec_key *)pkey;
-fail:
-	EVP_PKEY_free(pkey);
-	pkey = NULL;
-	goto out;
-}
-
-
 struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
 					    const u8 *buf, size_t len)
 {
-	const EC_KEY *eckey;
-	const EC_GROUP *group;
-	struct crypto_ec_key *pkey = NULL;
+	int ike_group = crypto_ec_key_group(group_key);
 
 	if (len & 1)
 		return NULL;
 
-	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)group_key);
-	if (!eckey) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Could not get EC_KEY from group_key");
+	if (ike_group == -1) {
+		wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
 		return NULL;
 	}
 
-	group = EC_KEY_get0_group(eckey);
-	if (group)
-		pkey = dpp_set_pubkey_point_group(group, buf, buf + len / 2,
-						  len / 2);
-	else
-		wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
-
-	return pkey;
+	return crypto_ec_key_set_pub(ike_group, buf, buf + len / 2,
+				     len / 2);
 }
 
 
@@ -1901,10 +1822,7 @@ static const u8 pkex_resp_y_bp_p512r1[64] = {
 static struct crypto_ec_key * dpp_pkex_get_role_elem(const struct dpp_curve_params *curve,
 						     int init)
 {
-	EC_GROUP *group;
-	size_t len = curve->prime_len;
 	const u8 *x, *y;
-	struct crypto_ec_key *res;
 
 	switch (curve->ike_group) {
 	case 19:
@@ -1935,12 +1853,7 @@ static struct crypto_ec_key * dpp_pkex_get_role_elem(const struct dpp_curve_para
 		return NULL;
 	}
 
-	group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
-	if (!group)
-		return NULL;
-	res = dpp_set_pubkey_point_group(group, x, y, len);
-	EC_GROUP_free(group);
-	return res;
+	return crypto_ec_key_set_pub(curve->ike_group, x, y, curve->prime_len);
 }
 
 
diff --git a/src/common/dpp_i.h b/src/common/dpp_i.h
index 6f9f489f2..06560a3d5 100644
--- a/src/common/dpp_i.h
+++ b/src/common/dpp_i.h
@@ -76,9 +76,6 @@ const struct dpp_curve_params * dpp_get_curve_nid(int nid);
 const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group);
 int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi,
 		       const u8 *data, size_t data_len);
-struct crypto_ec_key * dpp_set_pubkey_point_group(const EC_GROUP *group,
-						  const u8 *buf_x, const u8 *buf_y,
-						  size_t len);
 struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
 					    const u8 *buf, size_t len);
 int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len);
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index e5d40fb09..3473b3519 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -994,6 +994,19 @@ 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_set_pub - Initialize an EC Public Key from EC point coordinates
+ * @group: Identifying number for the ECC group
+ * @x: X coordinate of the Public key
+ * @y: Y coordinate of the Public key
+ * @len: Length of @x and @y buffer
+ * Returns: EC key or %NULL on failure
+ *
+ * This function initialize an EC Key from public key coordinates, in big endian
+ * byte order padded to the length of the prime defining the group.
+ */
+struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x, const u8 *y, size_t len);
+
 /**
  * crypto_ec_key_gen - Generate EC Key pair
  * @group: Identifying number for the ECC group
@@ -1009,7 +1022,7 @@ void crypto_ec_key_deinit(struct crypto_ec_key *key);
 
 /**
  * crypto_ec_key_get_subject_public_key - Get SubjectPublicKeyInfo ASN.1 for a EC key
- * @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen()
+ * @key: EC key from crypto_ec_key_parse/set_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);
@@ -1044,7 +1057,7 @@ struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
 
 /**
  * crypto_ec_key_verify_signature - Verify signature
- * @key: EC key from crypto_ec_key_parse_pub() or crypto_ec_key_gen()
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_gen()
  * @data: Data to signed
  * @len: Length of @data buffer
  * @sig: DER encoding of ASN.1 Ecdsa-Sig-Value
@@ -1056,7 +1069,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/priv() or crypto_ec_key_gen()
+ * @key: EC key from crypto_ec_key_parse/set_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 11aa4c744..c29a6e3a1 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -2256,6 +2256,85 @@ static int crypto_ec_group_2_nid(int group)
 }
 
 
+struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *buf_x, const u8 *buf_y, size_t len)
+{
+	EC_KEY *eckey = NULL;
+	EVP_PKEY *pkey = NULL;
+	EC_GROUP *ec_group = NULL;
+	BN_CTX *ctx = NULL;
+	EC_POINT *point = NULL;
+	BIGNUM *x = NULL, *y = NULL;
+	int nid;
+
+	if (!buf_x || !buf_y)
+		return NULL;
+
+	nid = crypto_ec_group_2_nid(group);
+	if (nid < 0) {
+		wpa_printf(MSG_ERROR, "Unsupported group %d", group);
+		return NULL;
+	}
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto fail;
+
+	ec_group = EC_GROUP_new_by_curve_name(nid);
+	if (!ec_group)
+		goto fail;
+
+	x = BN_bin2bn(buf_x, len, NULL);
+	y = BN_bin2bn(buf_y, len, NULL);
+	point = EC_POINT_new(ec_group);
+	if (!x || !y || !point)
+		goto fail;
+
+	if (!EC_POINT_set_affine_coordinates_GFp(ec_group, point, x, y, ctx)) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: EC_POINT_set_affine_coordinates_GFp failed: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto fail;
+	}
+
+	if (!EC_POINT_is_on_curve(ec_group, point, ctx) ||
+	    EC_POINT_is_at_infinity(ec_group, point)) {
+		wpa_printf(MSG_ERROR, "OpenSSL: Invalid point");
+		goto fail;
+	}
+
+	eckey = EC_KEY_new();
+	if (!eckey ||
+	    EC_KEY_set_group(eckey, ec_group) != 1 ||
+	    EC_KEY_set_public_key(eckey, point) != 1) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: Failed to set EC_KEY: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto fail;
+	}
+	EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
+
+	pkey = EVP_PKEY_new();
+	if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
+		wpa_printf(MSG_ERROR, "DPP: Could not create EVP_PKEY");
+		goto fail;
+	}
+
+out:
+	EC_GROUP_free(ec_group);
+	BN_free(x);
+	BN_free(y);
+	EC_POINT_free(point);
+	BN_CTX_free(ctx);
+	return (struct crypto_ec_key *)pkey;
+
+fail:
+	EC_KEY_free(eckey);
+	EVP_PKEY_free(pkey);
+	pkey = NULL;
+	goto out;
+}
+
+
 struct crypto_ec_key * crypto_ec_key_gen(int group)
 {
 	EVP_PKEY_CTX *kctx = NULL;
-- 
2.17.0




More information about the Hostap mailing list