[PATCH 11/21] dpp: Update pkex part to use crypto.h API

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


Rewrite EC point/bignum computation done in PKEX protocol using EC
point/bignum primitives already defined in crypto.h

Signed-off-by: Cedric Izoard <cedric.izoard at ceva-dsp.com>
---
 src/common/dpp_crypto.c     | 137 +++++++++-----------
 src/common/dpp_i.h          |  16 +--
 src/common/dpp_pkex.c       | 252 ++++++++++++++----------------------
 src/crypto/crypto.h         |  24 ++++
 src/crypto/crypto_openssl.c |  49 +++++++
 5 files changed, 236 insertions(+), 242 deletions(-)

diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c
index 2e4a9a27a..c1dffdb6f 100644
--- a/src/common/dpp_crypto.c
+++ b/src/common/dpp_crypto.c
@@ -1656,22 +1656,20 @@ static struct crypto_ec_key * dpp_pkex_get_role_elem(const struct dpp_curve_para
 }
 
 
-EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
-			      const u8 *mac_init, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group)
+struct crypto_ec_point * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
+					    const u8 *mac_init, const char *code,
+					    const char *identifier,
+					    struct crypto_ec **ret_ec)
 {
 	u8 hash[DPP_MAX_HASH_LEN];
 	const u8 *addr[3];
 	size_t len[3];
 	unsigned int num_elem = 0;
-	EC_POINT *Qi = NULL;
-	struct crypto_ec_key *Pi = NULL;
-	const EC_KEY *Pi_ec;
-	const EC_POINT *Pi_point;
-	BIGNUM *hash_bn = NULL;
-	const EC_GROUP *group = NULL;
-	EC_GROUP *group2 = NULL;
+	struct crypto_ec_point *Qi = NULL;
+	struct crypto_ec_key *Pi_key = NULL;
+	const struct crypto_ec_point *Pi = NULL;
+	struct crypto_bignum *hash_bn = NULL;
+	struct crypto_ec *ec = NULL;
 
 	/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
 
@@ -1695,66 +1693,58 @@ EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
 	wpa_hexdump_key(MSG_DEBUG,
 			"DPP: H(MAC-Initiator | [identifier |] code)",
 			hash, curve->hash_len);
-	Pi = dpp_pkex_get_role_elem(curve, 1);
-	if (!Pi)
+	Pi_key = dpp_pkex_get_role_elem(curve, 1);
+	if (!Pi_key)
 		goto fail;
-	dpp_debug_print_key("DPP: Pi", Pi);
-	Pi_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)Pi);
-	if (!Pi_ec)
-		goto fail;
-	Pi_point = EC_KEY_get0_public_key(Pi_ec);
+	dpp_debug_print_key("DPP: Pi", Pi_key);
 
-	group = EC_KEY_get0_group(Pi_ec);
-	if (!group)
+	ec = crypto_ec_init(curve->ike_group);
+	if (!ec)
 		goto fail;
-	group2 = EC_GROUP_dup(group);
-	if (!group2)
-		goto fail;
-	Qi = EC_POINT_new(group2);
-	if (!Qi) {
-		EC_GROUP_free(group2);
+
+	Pi = crypto_ec_key_get_public_key(Pi_key);
+	Qi = crypto_ec_point_init(ec);
+	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
+	if (!Pi || !Qi || !hash_bn)
 		goto fail;
-	}
-	hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
-	if (!hash_bn ||
-	    EC_POINT_mul(group2, Qi, NULL, Pi_point, hash_bn, bnctx) != 1)
+
+	if (crypto_ec_point_mul(ec, Pi, hash_bn, Qi))
 		goto fail;
-	if (EC_POINT_is_at_infinity(group, Qi)) {
+
+	if (crypto_ec_point_is_at_infinity(ec, Qi)) {
 		wpa_printf(MSG_INFO, "DPP: Qi is the point-at-infinity");
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: Qi", group, Qi);
+	crypto_ec_point_debug_print(ec, Qi, "DPP: Qi");
 out:
-	crypto_ec_key_deinit(Pi);
-	BN_clear_free(hash_bn);
-	if (ret_group && Qi)
-		*ret_group = group2;
+	crypto_ec_key_deinit(Pi_key);
+	crypto_bignum_deinit(hash_bn, 1);
+	if (ret_ec && Qi)
+		*ret_ec = ec;
 	else
-		EC_GROUP_free(group2);
+		crypto_ec_deinit(ec);
 	return Qi;
 fail:
-	EC_POINT_free(Qi);
+	crypto_ec_point_deinit(Qi, 1);
 	Qi = NULL;
 	goto out;
 }
 
 
-EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
-			      const u8 *mac_resp, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group)
+struct crypto_ec_point * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
+					    const u8 *mac_resp, const char *code,
+					    const char *identifier,
+					    struct crypto_ec **ret_ec)
 {
 	u8 hash[DPP_MAX_HASH_LEN];
 	const u8 *addr[3];
 	size_t len[3];
 	unsigned int num_elem = 0;
-	EC_POINT *Qr = NULL;
-	struct crypto_ec_key *Pr = NULL;
-	const EC_KEY *Pr_ec;
-	const EC_POINT *Pr_point;
-	BIGNUM *hash_bn = NULL;
-	const EC_GROUP *group = NULL;
-	EC_GROUP *group2 = NULL;
+	struct crypto_ec_point *Qr = NULL;
+	struct crypto_ec_key *Pr_key = NULL;
+	const struct crypto_ec_point *Pr = NULL;
+	struct crypto_bignum *hash_bn = NULL;
+	struct crypto_ec *ec = NULL;
 
 	/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
 
@@ -1778,45 +1768,40 @@ EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
 	wpa_hexdump_key(MSG_DEBUG,
 			"DPP: H(MAC-Responder | [identifier |] code)",
 			hash, curve->hash_len);
-	Pr = dpp_pkex_get_role_elem(curve, 0);
-	if (!Pr)
-		goto fail;
-	dpp_debug_print_key("DPP: Pr", Pr);
-	Pr_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)Pr);
-	if (!Pr_ec)
+	Pr_key = dpp_pkex_get_role_elem(curve, 0);
+	if (!Pr_key)
 		goto fail;
-	Pr_point = EC_KEY_get0_public_key(Pr_ec);
+	dpp_debug_print_key("DPP: Pr", Pr_key);
 
-	group = EC_KEY_get0_group(Pr_ec);
-	if (!group)
-		goto fail;
-	group2 = EC_GROUP_dup(group);
-	if (!group2)
+	ec = crypto_ec_init(curve->ike_group);
+	if (!ec)
 		goto fail;
-	Qr = EC_POINT_new(group2);
-	if (!Qr) {
-		EC_GROUP_free(group2);
+
+	Pr = crypto_ec_key_get_public_key(Pr_key);
+	Qr = crypto_ec_point_init(ec);
+	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
+	if (!Pr || !Qr || !hash_bn)
 		goto fail;
-	}
-	hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
-	if (!hash_bn ||
-	    EC_POINT_mul(group2, Qr, NULL, Pr_point, hash_bn, bnctx) != 1)
+
+	if (crypto_ec_point_mul(ec, Pr, hash_bn, Qr))
 		goto fail;
-	if (EC_POINT_is_at_infinity(group, Qr)) {
+
+	if (crypto_ec_point_is_at_infinity(ec, Qr)) {
 		wpa_printf(MSG_INFO, "DPP: Qr is the point-at-infinity");
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: Qr", group, Qr);
+	crypto_ec_point_debug_print(ec, Qr, "DPP: Qr");
+
 out:
-	crypto_ec_key_deinit(Pr);
-	BN_clear_free(hash_bn);
-	if (ret_group && Qr)
-		*ret_group = group2;
+	crypto_ec_key_deinit(Pr_key);
+	crypto_bignum_deinit(hash_bn, 1);
+	if (ret_ec && Qr)
+		*ret_ec = ec;
 	else
-		EC_GROUP_free(group2);
+		crypto_ec_deinit(ec);
 	return Qr;
 fail:
-	EC_POINT_free(Qr);
+	crypto_ec_point_deinit(Qr, 1);
 	Qr = NULL;
 	goto out;
 }
diff --git a/src/common/dpp_i.h b/src/common/dpp_i.h
index 06560a3d5..4686fb02b 100644
--- a/src/common/dpp_i.h
+++ b/src/common/dpp_i.h
@@ -109,14 +109,14 @@ int dpp_auth_derive_l_initiator(struct dpp_authentication *auth);
 int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, unsigned int hash_len);
 int dpp_derive_pmkid(const struct dpp_curve_params *curve,
 		     struct crypto_ec_key *own_key, struct crypto_ec_key *peer_key, u8 *pmkid);
-EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
-			      const u8 *mac_init, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group);
-EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
-			      const u8 *mac_resp, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group);
+struct crypto_ec_point * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
+					    const u8 *mac_init, const char *code,
+					    const char *identifier,
+					    struct crypto_ec **ret_ec);
+struct crypto_ec_point * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
+					    const u8 *mac_resp, const char *code,
+					    const char *identifier,
+					    struct crypto_ec **ret_ec);
 int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
 		      const u8 *Mx, size_t Mx_len,
 		      const u8 *Nx, size_t Nx_len,
diff --git a/src/common/dpp_pkex.c b/src/common/dpp_pkex.c
index 24f7536a8..c6bfafaae 100644
--- a/src/common/dpp_pkex.c
+++ b/src/common/dpp_pkex.c
@@ -8,8 +8,6 @@
  */
 
 #include "utils/includes.h"
-#include <openssl/opensslv.h>
-#include <openssl/err.h>
 
 #include "utils/common.h"
 #include "common/wpa_ctrl.h"
@@ -27,30 +25,13 @@ u8 dpp_pkex_ephemeral_key_override[600];
 size_t dpp_pkex_ephemeral_key_override_len = 0;
 #endif /* CONFIG_TESTING_OPTIONS */
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
-	(defined(LIBRESSL_VERSION_NUMBER) && \
-	 LIBRESSL_VERSION_NUMBER < 0x20700000L)
-/* Compatibility wrappers for older versions. */
-
-static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
-{
-	if (pkey->type != EVP_PKEY_EC)
-		return NULL;
-	return pkey->pkey.ec;
-}
-
-#endif
-
 
 static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
 {
-	const EC_KEY *X_ec;
-	const EC_POINT *X_point;
-	BN_CTX *bnctx = NULL;
-	EC_GROUP *group = NULL;
-	EC_POINT *Qi = NULL, *M = NULL;
-	struct wpabuf *M_buf = NULL;
-	BIGNUM *Mx = NULL, *My = NULL;
+	struct crypto_ec *ec = NULL;
+	const struct crypto_ec_point *X = NULL;
+	struct crypto_ec_point *Qi = NULL, *M = NULL;
+	u8 *Mx, *My;
 	struct wpabuf *msg = NULL;
 	size_t attr_len;
 	const struct dpp_curve_params *curve = pkex->own_bi->curve;
@@ -58,11 +39,8 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
 	wpa_printf(MSG_DEBUG, "DPP: Build PKEX Exchange Request");
 
 	/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
-	bnctx = BN_CTX_new();
-	if (!bnctx)
-		goto fail;
 	Qi = dpp_pkex_derive_Qi(curve, pkex->own_mac, pkex->code,
-				pkex->identifier, bnctx, &group);
+				pkex->identifier, &ec);
 	if (!Qi)
 		goto fail;
 
@@ -86,21 +64,15 @@ static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
 		goto fail;
 
 	/* M = X + Qi */
-	X_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)pkex->x);
-	if (!X_ec)
+	X = crypto_ec_key_get_public_key(pkex->x);
+	M = crypto_ec_point_init(ec);
+	if (!X || !M)
 		goto fail;
-	X_point = EC_KEY_get0_public_key(X_ec);
-	if (!X_point)
-		goto fail;
-	dpp_debug_print_point("DPP: X", group, X_point);
-	M = EC_POINT_new(group);
-	Mx = BN_new();
-	My = BN_new();
-	if (!M || !Mx || !My ||
-	    EC_POINT_add(group, M, X_point, Qi, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1)
+	crypto_ec_point_debug_print(ec, X, "DPP: X");
+
+	if (crypto_ec_point_add(ec, X, Qi, M))
 		goto fail;
-	dpp_debug_print_point("DPP: M", group, M);
+	crypto_ec_point_debug_print(ec, M, "DPP: M");
 
 	/* Initiator -> Responder: group, [identifier,] M */
 	attr_len = 4 + 2;
@@ -154,21 +126,17 @@ skip_finite_cyclic_group:
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
-	if (dpp_bn2bin_pad(Mx, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(Mx, pkex->Mx, curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(My, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0)
+	Mx = wpabuf_put(msg, curve->prime_len);
+	My = wpabuf_put(msg, curve->prime_len);
+	if (crypto_ec_point_to_bin(ec, M, Mx, My))
 		goto fail;
 
+	os_memcpy(pkex->Mx, Mx, curve->prime_len);
+
 out:
-	wpabuf_free(M_buf);
-	EC_POINT_free(M);
-	EC_POINT_free(Qi);
-	BN_clear_free(Mx);
-	BN_clear_free(My);
-	BN_CTX_free(bnctx);
-	EC_GROUP_free(group);
+	crypto_ec_point_deinit(M, 1);
+	crypto_ec_point_deinit(Qi, 1);
+	crypto_ec_deinit(ec);
 	return msg;
 fail:
 	wpa_printf(MSG_INFO, "DPP: Failed to build PKEX Exchange Request");
@@ -227,7 +195,7 @@ fail:
 static struct wpabuf *
 dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex,
 			     enum dpp_status_error status,
-			     const BIGNUM *Nx, const BIGNUM *Ny)
+			     const u8 *Nx, const u8 *Ny)
 {
 	struct wpabuf *msg = NULL;
 	size_t attr_len;
@@ -291,12 +259,9 @@ skip_status:
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
-	if (dpp_bn2bin_pad(Nx, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(Nx, pkex->Nx, curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(Ny, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0)
-		goto fail;
+	os_memcpy(wpabuf_put(msg, curve->prime_len), Nx, curve->prime_len);
+	os_memcpy(wpabuf_put(msg, curve->prime_len), Ny, curve->prime_len);
+	os_memcpy(pkex->Nx, Nx, curve->prime_len);
 
 skip_encrypted_key:
 	if (status == DPP_STATUS_BAD_GROUP) {
@@ -352,14 +317,10 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
 	const struct dpp_curve_params *curve = bi->curve;
 	u16 ike_group;
 	struct dpp_pkex *pkex = NULL;
-	EC_POINT *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL, *N = NULL;
-	BN_CTX *bnctx = NULL;
-	EC_GROUP *group = NULL;
-	BIGNUM *Mx = NULL, *My = NULL;
-	const EC_KEY *Y_ec;
-	EC_KEY *X_ec = NULL;
-	const EC_POINT *Y_point;
-	BIGNUM *Nx = NULL, *Ny = NULL;
+	struct crypto_ec_point *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL, *N = NULL;
+	struct crypto_ec *ec = NULL;
+	const struct crypto_ec_point *Y = NULL;
+	u8 *x_coord = NULL, *y_coord = NULL;
 	u8 Kx[DPP_MAX_SHARED_SECRET_LEN];
 	size_t Kx_len;
 	int res;
@@ -424,34 +385,27 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
 	}
 
 	/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
-	bnctx = BN_CTX_new();
-	if (!bnctx)
-		goto fail;
-	Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, bnctx,
-				&group);
+	Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, &ec);
 	if (!Qi)
 		goto fail;
 
 	/* X' = M - Qi */
-	X = EC_POINT_new(group);
-	M = EC_POINT_new(group);
-	Mx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
-	My = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
-	if (!X || !M || !Mx || !My ||
-	    EC_POINT_set_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, M) ||
-	    !EC_POINT_is_on_curve(group, M, bnctx) ||
-	    EC_POINT_invert(group, Qi, bnctx) != 1 ||
-	    EC_POINT_add(group, X, M, Qi, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, X) ||
-	    !EC_POINT_is_on_curve(group, X, bnctx)) {
+	X = crypto_ec_point_init(ec);
+	M = crypto_ec_point_from_bin(ec, attr_key);
+	if (!X || !M ||
+	    crypto_ec_point_is_at_infinity(ec, M) ||
+	    !crypto_ec_point_is_on_curve(ec, M) ||
+	    crypto_ec_point_invert(ec, Qi) ||
+	    crypto_ec_point_add(ec, M, Qi, X) ||
+	    crypto_ec_point_is_at_infinity(ec, X) ||
+	    !crypto_ec_point_is_on_curve(ec, X)) {
 		wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
 			"Invalid Encrypted Key value");
 		bi->pkex_t++;
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: M", group, M);
-	dpp_debug_print_point("DPP: X'", group, X);
+	crypto_ec_point_debug_print(ec, M, "DPP: M");
+	crypto_ec_point_debug_print(ec, X, "DPP: X'");
 
 	pkex = os_zalloc(sizeof(*pkex));
 	if (!pkex)
@@ -472,18 +426,19 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
 
 	os_memcpy(pkex->Mx, attr_key, attr_key_len / 2);
 
-	X_ec = EC_KEY_new();
-	if (!X_ec ||
-	    EC_KEY_set_group(X_ec, group) != 1 ||
-	    EC_KEY_set_public_key(X_ec, X) != 1)
+	x_coord = os_malloc(curve->prime_len);
+	y_coord = os_malloc(curve->prime_len);
+	if (!x_coord || !y_coord ||
+	    crypto_ec_point_to_bin(ec, X, x_coord, y_coord))
 		goto fail;
-	pkex->x = (struct crypto_ec_key *)EVP_PKEY_new();
-	if (!pkex->x ||
-	    EVP_PKEY_set1_EC_KEY((EVP_PKEY *)pkex->x, X_ec) != 1)
+
+	pkex->x = crypto_ec_key_set_pub(curve->ike_group, x_coord,
+					y_coord, crypto_ec_prime_len(ec));
+	if (!pkex->x)
 		goto fail;
 
 	/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
-	Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, bnctx, NULL);
+	Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, NULL);
 	if (!Qr)
 		goto fail;
 
@@ -507,24 +462,20 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
 		goto fail;
 
 	/* N = Y + Qr */
-	Y_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)pkex->y);
-	if (!Y_ec)
+	Y = crypto_ec_key_get_public_key(pkex->y);
+	if (!Y)
 		goto fail;
-	Y_point = EC_KEY_get0_public_key(Y_ec);
-	if (!Y_point)
-		goto fail;
-	dpp_debug_print_point("DPP: Y", group, Y_point);
-	N = EC_POINT_new(group);
-	Nx = BN_new();
-	Ny = BN_new();
-	if (!N || !Nx || !Ny ||
-	    EC_POINT_add(group, N, Y_point, Qr, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1)
+	crypto_ec_point_debug_print(ec, Y, "DPP: Y");
+
+	N = crypto_ec_point_init(ec);
+	if (!N ||
+	    crypto_ec_point_add(ec, Y, Qr, N) ||
+	    crypto_ec_point_to_bin(ec, N, x_coord, y_coord))
 		goto fail;
-	dpp_debug_print_point("DPP: N", group, N);
+	crypto_ec_point_debug_print(ec, N, "DPP: N");
 
 	pkex->exchange_resp = dpp_pkex_build_exchange_resp(pkex, DPP_STATUS_OK,
-							   Nx, Ny);
+							   x_coord, y_coord);
 	if (!pkex->exchange_resp)
 		goto fail;
 
@@ -548,18 +499,14 @@ struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
 	pkex->exchange_done = 1;
 
 out:
-	BN_CTX_free(bnctx);
-	EC_POINT_free(Qi);
-	EC_POINT_free(Qr);
-	BN_free(Mx);
-	BN_free(My);
-	BN_free(Nx);
-	BN_free(Ny);
-	EC_POINT_free(M);
-	EC_POINT_free(N);
-	EC_POINT_free(X);
-	EC_KEY_free(X_ec);
-	EC_GROUP_free(group);
+	os_free(x_coord);
+	os_free(y_coord);
+	crypto_ec_point_deinit(Qi, 1);
+	crypto_ec_point_deinit(Qr, 1);
+	crypto_ec_point_deinit(M, 1);
+	crypto_ec_point_deinit(N, 1);
+	crypto_ec_point_deinit(X, 1);
+	crypto_ec_deinit(ec);
 	return pkex;
 fail:
 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request processing failed");
@@ -688,13 +635,11 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
 {
 	const u8 *attr_status, *attr_id, *attr_key, *attr_group;
 	u16 attr_status_len, attr_id_len, attr_key_len, attr_group_len;
-	EC_GROUP *group = NULL;
-	BN_CTX *bnctx = NULL;
+	struct crypto_ec *ec = NULL;
 	struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
 	const struct dpp_curve_params *curve = pkex->own_bi->curve;
-	EC_POINT *Qr = NULL, *Y = NULL, *N = NULL;
-	BIGNUM *Nx = NULL, *Ny = NULL;
-	EC_KEY *Y_ec = NULL;
+	struct crypto_ec_point *Qr = NULL, *Y = NULL, *N = NULL;
+	u8 *x_coord = NULL, *y_coord = NULL;
 	size_t Jx_len, Kx_len;
 	u8 Jx[DPP_MAX_SHARED_SECRET_LEN], Kx[DPP_MAX_SHARED_SECRET_LEN];
 	const u8 *addr[4];
@@ -765,45 +710,38 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
 	}
 
 	/* Qr = H(MAC-Responder | [identifier |] code) * Pr */
-	bnctx = BN_CTX_new();
-	if (!bnctx)
-		goto fail;
 	Qr = dpp_pkex_derive_Qr(curve, pkex->peer_mac, pkex->code,
-				pkex->identifier, bnctx, &group);
+				pkex->identifier, &ec);
 	if (!Qr)
 		goto fail;
 
 	/* Y' = N - Qr */
-	Y = EC_POINT_new(group);
-	N = EC_POINT_new(group);
-	Nx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
-	Ny = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
-	if (!Y || !N || !Nx || !Ny ||
-	    EC_POINT_set_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, N) ||
-	    !EC_POINT_is_on_curve(group, N, bnctx) ||
-	    EC_POINT_invert(group, Qr, bnctx) != 1 ||
-	    EC_POINT_add(group, Y, N, Qr, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, Y) ||
-	    !EC_POINT_is_on_curve(group, Y, bnctx)) {
+	Y = crypto_ec_point_init(ec);
+	N = crypto_ec_point_from_bin(ec, attr_key);
+	if (!Y || !N ||
+	    crypto_ec_point_is_at_infinity(ec, N) ||
+	    !crypto_ec_point_is_on_curve(ec, N) ||
+	    crypto_ec_point_invert(ec, Qr) ||
+	    crypto_ec_point_add(ec, N, Qr, Y) ||
+	    crypto_ec_point_is_at_infinity(ec, Y) ||
+	    !crypto_ec_point_is_on_curve(ec, Y)) {
 		dpp_pkex_fail(pkex, "Invalid Encrypted Key value");
 		pkex->t++;
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: N", group, N);
-	dpp_debug_print_point("DPP: Y'", group, Y);
+	crypto_ec_point_debug_print(ec, N, "DPP: N");
+	crypto_ec_point_debug_print(ec, Y, "DPP: Y'");
 
 	pkex->exchange_done = 1;
 
 	/* ECDH: J = a * Y' */
-	Y_ec = EC_KEY_new();
-	if (!Y_ec ||
-	    EC_KEY_set_group(Y_ec, group) != 1 ||
-	    EC_KEY_set_public_key(Y_ec, Y) != 1)
+	x_coord = os_malloc(curve->prime_len);
+	y_coord = os_malloc(curve->prime_len);
+	if (!x_coord || !y_coord || crypto_ec_point_to_bin(ec, Y, x_coord, y_coord))
 		goto fail;
-	pkex->y = (struct crypto_ec_key *)EVP_PKEY_new();
-	if (!pkex->y ||
-	    EVP_PKEY_set1_EC_KEY((EVP_PKEY *)pkex->y, Y_ec) != 1)
+	pkex->y = crypto_ec_key_set_pub(curve->ike_group, x_coord, y_coord,
+					curve->prime_len);
+	if (!pkex->y)
 		goto fail;
 	if (dpp_ecdh(pkex->own_bi->pubkey, pkex->y, Jx, &Jx_len) < 0)
 		goto fail;
@@ -855,14 +793,12 @@ out:
 	wpabuf_free(A_pub);
 	wpabuf_free(X_pub);
 	wpabuf_free(Y_pub);
-	EC_POINT_free(Qr);
-	EC_POINT_free(Y);
-	EC_POINT_free(N);
-	BN_free(Nx);
-	BN_free(Ny);
-	EC_KEY_free(Y_ec);
-	BN_CTX_free(bnctx);
-	EC_GROUP_free(group);
+	os_free(x_coord);
+	os_free(y_coord);
+	crypto_ec_point_deinit(Qr, 1);
+	crypto_ec_point_deinit(Y, 1);
+	crypto_ec_point_deinit(N, 1);
+	crypto_ec_deinit(ec);
 	return msg;
 fail:
 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response processing failed");
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 3473b3519..7c2bc82e2 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -920,6 +920,16 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
 			const struct crypto_ec_point *a,
 			const struct crypto_ec_point *b);
 
+/**
+ * crypto_ec_point_debug_print - Dump EC point
+ * @e: EC context from crypto_ec_init()
+ * @p: EC point
+ * @title: Name of the EC point in the trace
+ */
+void crypto_ec_point_debug_print(const struct crypto_ec *e,
+				 const struct crypto_ec_point *p,
+				 const char *title);
+
 /**
  * struct crypto_ecdh - Elliptic Curve Diffie–Hellman context
  *
@@ -1045,6 +1055,20 @@ struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
  */
 struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, int prefix);
 
+/**
+ * crypto_ec_key_get_public_key - Get EC Public Key as an EC point
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
+ * Returns: Public key a an EC point and %NULL on failure
+ */
+const struct crypto_ec_point *crypto_ec_key_get_public_key(struct crypto_ec_key *key);
+
+/**
+ * crypto_ec_key_get_private_key - Get EC Private Key as a bignum
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
+ * Returns: private key as a bignum and %NULL on failure
+ */
+const struct crypto_bignum *crypto_ec_key_get_private_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() or crypto_ec_key_gen()
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 275ec6252..308bab908 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -1951,6 +1951,33 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
 }
 
 
+void crypto_ec_point_debug_print(const struct crypto_ec *e,
+				 const struct crypto_ec_point *p,
+				 const char *title)
+{
+	BIGNUM *x, *y;
+	char *x_str = NULL, *y_str = NULL;
+
+	x = BN_new();
+	y = BN_new();
+	if (!x || !y ||
+	    EC_POINT_get_affine_coordinates_GFp(e->group, (const EC_POINT *) p, x, y, e->bnctx) != 1)
+		goto fail;
+
+	x_str = BN_bn2hex(x);
+	y_str = BN_bn2hex(y);
+	if (!x_str || !y_str)
+		goto fail;
+
+	wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x_str, y_str);
+
+fail:
+	OPENSSL_free(x_str);
+	OPENSSL_free(y_str);
+	BN_free(x);
+	BN_free(y);
+}
+
 struct crypto_ecdh {
 	struct crypto_ec *ec;
 	EVP_PKEY *pkey;
@@ -2494,6 +2521,28 @@ struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, int pr
 }
 
 
+const struct crypto_ec_point *crypto_ec_key_get_public_key(struct crypto_ec_key *key)
+{
+	EC_KEY *eckey;
+
+	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)key);
+	if (!eckey)
+		return NULL;
+	return (const struct crypto_ec_point *)EC_KEY_get0_public_key(eckey);
+}
+
+
+const struct crypto_bignum *crypto_ec_key_get_private_key(struct crypto_ec_key *key)
+{
+	EC_KEY *eckey;
+
+	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)key);
+	if (!eckey)
+		return NULL;
+	return (const struct crypto_bignum *)EC_KEY_get0_private_key(eckey);
+}
+
+
 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
 				   size_t len)
 {
-- 
2.17.0




More information about the Hostap mailing list