]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Move dpp_set_pubkey_point_group() to crypto.h
authorCedric Izoard <cedric.izoard@laposte.net>
Mon, 28 Jun 2021 16:25:24 +0000 (18:25 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 26 Oct 2021 16:50:54 +0000 (19:50 +0300)
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@ceva-dsp.com>
src/common/dpp.c
src/common/dpp_crypto.c
src/common/dpp_i.h
src/crypto/crypto.h
src/crypto/crypto_openssl.c

index 2d944f08859b93d261ab761d3e3d87be85f49599..bb3b35db85e102a2de915ea13b3413f2de16585a 100644 (file)
@@ -2167,8 +2167,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) {
@@ -2221,22 +2220,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;
 }
 
 
index 8d68fc72d9b75286f14de310ba7c8362f9410c35..a2b63936d4f36a2f5fa571e472e2a7aff9f8936a 100644 (file)
@@ -374,101 +374,20 @@ 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 < 0) {
+               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);
 }
 
 
@@ -1914,10 +1833,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:
@@ -1948,12 +1864,7 @@ dpp_pkex_get_role_elem(const struct dpp_curve_params *curve, int init)
                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);
 }
 
 
index 03862bb7a241b8d3be2be5f2c1d483a6b6092953..87beade3d3bb6459e2d98c2e4eeb73de860d28b0 100644 (file)
@@ -78,10 +78,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);
index c51fded641ef26af886a3debb7dc7c4244887963..e98d1d816224372a0acb81d974e1819a985b55ee 100644 (file)
@@ -994,6 +994,20 @@ 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 +1023,7 @@ 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/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);
@@ -1046,7 +1060,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() or crypto_ec_key_gen()
+ * @key: EC key from crypto_ec_key_parse/set_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
@@ -1058,7 +1072,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);
index 3eb492dc1a217694714a3d56f2bd77bf537d8f53..c640b0fa9a3575f6ee088817337f555b453a72ac 100644 (file)
@@ -2242,6 +2242,86 @@ fail:
 }
 
 
+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;
+       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, "OpenSSL: 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, "OpenSSL: 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;