All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] eapol: IP Allocation KDE support
@ 2020-09-14 13:51 Andrew Zaborowski
  2020-09-14 13:51 ` [PATCH 2/5] eapol: IP Allocation KDE support authenticator side Andrew Zaborowski
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Andrew Zaborowski @ 2020-09-14 13:51 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 6312 bytes --]

Support IP allocation during the 4-Way Handshake as defined in the P2P
spec.  This is the supplicant side implementation.

The API requires the user to set hs->support_ip_allocation true before
eapol_start().  On HANDSHAKE_EVENT_COMPLETE, if this same flag is still
set, we've received the IP lease, the netmask and the authenticator's
IP from the authenticator and there's no need to start DHCP.  If the
flag is cleared, the user needs to use DHCP.
---
I can split this into two flags if preferred.
---
 src/eapol.c     | 76 +++++++++++++++++++++++++++++++++++++++++++------
 src/handshake.h |  9 +++++-
 2 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/src/eapol.c b/src/eapol.c
index 977f720b..acf07c41 100644
--- a/src/eapol.c
+++ b/src/eapol.c
@@ -1088,7 +1088,7 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
 	const uint8_t *kck;
 	struct eapol_key *step2;
 	uint8_t mic[MIC_MAXLEN];
-	uint8_t *ies;
+	uint8_t ies[512];
 	size_t ies_len;
 	const uint8_t *own_ie = sm->handshake->supplicant_ie;
 	const uint8_t *pmkid;
@@ -1199,8 +1199,6 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
 		 * Rebuild the RSNE to include the PMKR1Name and append
 		 * MDE + FTE.
 		 */
-		ies = alloca(512);
-
 		rsn_info.num_pmkids = 1;
 		rsn_info.pmkids = sm->handshake->pmk_r1_name;
 
@@ -1214,7 +1212,16 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
 		ies_len += fte[1] + 2;
 	} else {
 		ies_len = own_ie[1] + 2;
-		ies = (uint8_t *) own_ie;
+		memcpy(ies, own_ie, ies_len);
+	}
+
+	if (sm->handshake->support_ip_allocation) {
+		/* Wi-Fi P2P Technical Specification v1.7 Table 58 */
+		ies[ies_len++] = IE_TYPE_VENDOR_SPECIFIC;
+		ies[ies_len++] = 4 + 1;
+		l_put_be32(HANDSHAKE_KDE_IP_ADDRESS_REQ, ies + ies_len);
+		ies_len += 4;
+		ies[ies_len++] = 0x01;
 	}
 
 	step2 = eapol_create_ptk_2_of_4(sm->protocol_version,
@@ -1381,7 +1388,8 @@ static const uint8_t *eapol_find_rsne(const uint8_t *data, size_t data_len,
 	return first;
 }
 
-static const uint8_t *eapol_find_osen(const uint8_t *data, size_t data_len)
+static const uint8_t *eapol_find_wfa_kde(const uint8_t *data, size_t data_len,
+					uint8_t oi_type)
 {
 	struct ie_tlv_iter iter;
 
@@ -1389,7 +1397,7 @@ static const uint8_t *eapol_find_osen(const uint8_t *data, size_t data_len)
 
 	while (ie_tlv_iter_next(&iter)) {
 		if (ie_tlv_iter_get_tag(&iter) == IE_TYPE_VENDOR_SPECIFIC) {
-			if (!is_ie_wfa_ie(iter.data, iter.len, IE_WFA_OI_OSEN))
+			if (!is_ie_wfa_ie(iter.data, iter.len, oi_type))
 				continue;
 		} else
 			continue;
@@ -1474,6 +1482,28 @@ static const uint8_t *eapol_find_wpa_ie(const uint8_t *data, size_t data_len)
 	return NULL;
 }
 
+static bool eapol_check_ip_mask(const uint8_t *mask,
+				const uint8_t *ip1, const uint8_t *ip2)
+{
+	uint32_t mask_uint = l_get_be32(mask);
+	uint32_t ip1_uint = l_get_be32(ip1);
+	uint32_t ip2_uint = l_get_be32(ip2);
+
+	return
+		/* Check IPs are in the same subnet */
+		((ip1_uint ^ ip2_uint) & mask_uint) == 0 &&
+		/* Check IPs are different */
+		ip1_uint != ip2_uint &&
+		/* Check IPs are not subnet addresses */
+		(ip1_uint & ~mask_uint) != 0 &&
+		(ip2_uint & ~mask_uint) != 0 &&
+		/* Check IPs are not broadcast addresses */
+		(ip1_uint | mask_uint) != 0xffffffff &&
+		(ip2_uint | mask_uint) != 0xffffffff &&
+		/* Check the 1s are at the start of the mask */
+		(uint32_t) (mask_uint << __builtin_popcountl(mask_uint)) == 0;
+}
+
 static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
 					const struct eapol_key *ek,
 					const uint8_t *decrypted_key_data,
@@ -1520,8 +1550,9 @@ static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
 		rsne = eapol_find_wpa_ie(decrypted_key_data,
 					decrypted_key_data_size);
 	else if (sm->handshake->osen_ie)
-		rsne = eapol_find_osen(decrypted_key_data,
-					decrypted_key_data_size);
+		rsne = eapol_find_wfa_kde(decrypted_key_data,
+					decrypted_key_data_size,
+					IE_WFA_OI_OSEN);
 	else
 		rsne = eapol_find_rsne(decrypted_key_data,
 					decrypted_key_data_size,
@@ -1667,6 +1698,35 @@ static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
 	} else
 		igtk = NULL;
 
+	if (sm->handshake->support_ip_allocation) {
+		const uint8_t *ip_alloc_kde =
+			eapol_find_wfa_kde(decrypted_key_data,
+					decrypted_key_data_size,
+					HANDSHAKE_KDE_IP_ADDRESS_ALLOC & 255);
+
+		if (ip_alloc_kde &&
+				(ip_alloc_kde[1] < 16 ||
+				 !eapol_check_ip_mask(ip_alloc_kde + 10,
+							ip_alloc_kde + 6,
+							ip_alloc_kde + 14))) {
+			l_debug("Invalid IP Allocation KDE in frame 3/4");
+			handshake_failed(sm, MMPDU_REASON_CODE_INVALID_IE);
+			return;
+		}
+
+		sm->handshake->support_ip_allocation = ip_alloc_kde != NULL;
+
+		if (ip_alloc_kde) {
+			sm->handshake->client_ip_addr =
+				l_get_be32(ip_alloc_kde + 6);
+			sm->handshake->subnet_mask =
+				l_get_be32(ip_alloc_kde + 10);
+			sm->handshake->go_ip_addr =
+				l_get_be32(ip_alloc_kde + 14);
+		} else
+			l_debug("Authenticator ignored our IP Address Request");
+	}
+
 retransmit:
 	/*
 	 * 802.11-2016, Section 12.7.6.4:
diff --git a/src/handshake.h b/src/handshake.h
index c88bb0d1..b738efd9 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -28,8 +28,8 @@
 struct handshake_state;
 enum crypto_cipher;
 
-/* 802.11-2016 Table 12-6 in section 12.7.2 */
 enum handshake_kde {
+	/* 802.11-2016 Table 12-6 in section 12.7.2 */
 	HANDSHAKE_KDE_GTK		= 0x000fac01,
 	HANDSHAKE_KDE_MAC_ADDRESS	= 0x000fac03,
 	HANDSHAKE_KDE_PMKID		= 0x000fac04,
@@ -41,6 +41,9 @@ enum handshake_kde {
 	HANDSHAKE_KDE_KEY_ID		= 0x000fac0a,
 	HANDSHAKE_KDE_MULTIBAND_GTK	= 0x000fac0b,
 	HANDSHAKE_KDE_MULTIBAND_KEY_ID	= 0x000fac0c,
+	/* Wi-Fi P2P Technical Specification v1.7 4.2.8 */
+	HANDSHAKE_KDE_IP_ADDRESS_REQ	= 0x506f9a04,
+	HANDSHAKE_KDE_IP_ADDRESS_ALLOC	= 0x506f9a05,
 };
 
 enum handshake_event {
@@ -124,6 +127,10 @@ struct handshake_state {
 	uint8_t proto_version : 2;
 	unsigned int gtk_index;
 	struct erp_cache_entry *erp_cache;
+	bool support_ip_allocation : 1;
+	uint32_t client_ip_addr;
+	uint32_t subnet_mask;
+	uint32_t go_ip_addr;
 	void *user_data;
 
 	void (*free)(struct handshake_state *s);
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] eapol: IP Allocation KDE support authenticator side
  2020-09-14 13:51 [PATCH 1/5] eapol: IP Allocation KDE support Andrew Zaborowski
@ 2020-09-14 13:51 ` Andrew Zaborowski
  2020-09-14 13:51 ` [PATCH 3/5] netconfig: Don't bswap IP netmasks for __builtin_popcountl Andrew Zaborowski
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Zaborowski @ 2020-09-14 13:51 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2234 bytes --]

Again the hs->support_ip_allocation flag is used for two purposes here,
first the user signals whether to support this mechanism through this
flag, then it reads the flag to find out if an IP was allocated.
---
 src/eapol.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/eapol.c b/src/eapol.c
index acf07c41..c42f1a05 100644
--- a/src/eapol.c
+++ b/src/eapol.c
@@ -1322,6 +1322,21 @@ static void eapol_send_ptk_3_of_4(struct eapol_sm *sm)
 		key_data_len += gtk_kde[1] + 2;
 	}
 
+	if (sm->handshake->support_ip_allocation) {
+		/* Wi-Fi P2P Technical Specification v1.7 Table 59 */
+		key_data_buf[key_data_len++] = IE_TYPE_VENDOR_SPECIFIC;
+		key_data_buf[key_data_len++] = 4 + 12;
+		l_put_be32(HANDSHAKE_KDE_IP_ADDRESS_ALLOC,
+				key_data_buf + key_data_len + 0);
+		l_put_be32(sm->handshake->client_ip_addr,
+				key_data_buf + key_data_len + 4);
+		l_put_be32(sm->handshake->subnet_mask,
+				key_data_buf + key_data_len + 8);
+		l_put_be32(sm->handshake->go_ip_addr,
+				key_data_buf + key_data_len + 12);
+		key_data_len += 4 + 12;
+	}
+
 	kek = handshake_state_get_kek(sm->handshake);
 	key_data_len = eapol_encrypt_key_data(kek, key_data_buf,
 						key_data_len, ek, sm->mic_len);
@@ -1450,11 +1465,26 @@ static void eapol_handle_ptk_2_of_4(struct eapol_sm *sm,
 	if (!rsne || rsne[1] != sm->handshake->supplicant_ie[1] ||
 			memcmp(rsne + 2, sm->handshake->supplicant_ie + 2,
 				rsne[1])) {
-
 		handshake_failed(sm, MMPDU_REASON_CODE_IE_DIFFERENT);
 		return;
 	}
 
+	if (sm->handshake->support_ip_allocation) {
+		const uint8_t *ip_req_kde =
+			eapol_find_wfa_kde(EAPOL_KEY_DATA(ek, sm->mic_len),
+					EAPOL_KEY_DATA_LEN(ek, sm->mic_len),
+					HANDSHAKE_KDE_IP_ADDRESS_REQ & 255);
+
+		if (ip_req_kde &&
+				(ip_req_kde[1] < 5 || ip_req_kde[6] != 0x01)) {
+			l_debug("Invalid IP Address Request KDE in frame 2/4");
+			handshake_failed(sm, MMPDU_REASON_CODE_INVALID_IE);
+			return;
+		}
+
+		sm->handshake->support_ip_allocation = ip_req_kde != NULL;
+	}
+
 	memcpy(sm->handshake->snonce, ek->key_nonce,
 			sizeof(sm->handshake->snonce));
 	sm->handshake->have_snonce = true;
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] netconfig: Don't bswap IP netmasks for __builtin_popcountl
  2020-09-14 13:51 [PATCH 1/5] eapol: IP Allocation KDE support Andrew Zaborowski
  2020-09-14 13:51 ` [PATCH 2/5] eapol: IP Allocation KDE support authenticator side Andrew Zaborowski
@ 2020-09-14 13:51 ` Andrew Zaborowski
  2020-09-14 13:51 ` [PATCH 4/5] p2p: Try IP allocation during 4-Way handshake on client Andrew Zaborowski
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Zaborowski @ 2020-09-14 13:51 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 897 bytes --]

The __builtin_popcountl() value shouldn't change with the endianness.
---
 src/netconfig.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/netconfig.c b/src/netconfig.c
index de526460..ca76f475 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -152,7 +152,7 @@ static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr(
 
 		if (netmask && inet_pton(AF_INET, netmask, &in_addr) > 0)
 			ifaddr->prefix_len = __builtin_popcountl(
-						L_BE32_TO_CPU(in_addr.s_addr));
+								in_addr.s_addr);
 		else
 			ifaddr->prefix_len = 24;
 
@@ -187,7 +187,7 @@ static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr(
 
 		if (netmask && inet_pton(AF_INET, netmask, &in_addr) > 0)
 			ifaddr->prefix_len = __builtin_popcountl(
-						L_BE32_TO_CPU(in_addr.s_addr));
+								in_addr.s_addr);
 		else
 			ifaddr->prefix_len = 24;
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] p2p: Try IP allocation during 4-Way handshake on client
  2020-09-14 13:51 [PATCH 1/5] eapol: IP Allocation KDE support Andrew Zaborowski
  2020-09-14 13:51 ` [PATCH 2/5] eapol: IP Allocation KDE support authenticator side Andrew Zaborowski
  2020-09-14 13:51 ` [PATCH 3/5] netconfig: Don't bswap IP netmasks for __builtin_popcountl Andrew Zaborowski
@ 2020-09-14 13:51 ` Andrew Zaborowski
  2020-09-14 13:51 ` [PATCH 5/5] unit: Add two EAPOL IP allocation scenarios Andrew Zaborowski
  2020-09-14 16:46 ` [PATCH 1/5] eapol: IP Allocation KDE support Denis Kenzior
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Zaborowski @ 2020-09-14 13:51 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 5501 bytes --]

---
 src/p2p.c | 60 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/src/p2p.c b/src/p2p.c
index cf4d4bf3..5ee887d3 100644
--- a/src/p2p.c
+++ b/src/p2p.c
@@ -32,6 +32,8 @@
 #include <stdio.h>
 #include <time.h>
 #include <errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include <ell/ell.h>
 
@@ -97,7 +99,9 @@ struct p2p_device {
 	uint32_t conn_new_intf_cmd_id;
 	struct wsc_enrollee *conn_enrollee;
 	struct netconfig *conn_netconfig;
+	struct l_settings *conn_netconfig_settings;
 	struct l_timeout *conn_dhcp_timeout;
+	char *conn_peer_ip;
 	struct p2p_wfd_properties *conn_own_wfd;
 	uint8_t conn_psk[32];
 	int conn_retry_count;
@@ -109,6 +113,7 @@ struct p2p_device {
 	unsigned int conn_go_scan_retry;
 	uint32_t conn_go_oper_freq;
 	uint8_t conn_peer_interface_addr[6];
+	struct p2p_capability_attr conn_peer_capability;
 
 	struct p2p_group_id_attr go_group_id;
 	struct ap_state *group;
@@ -446,6 +451,9 @@ static void p2p_connection_reset(struct p2p_device *dev)
 	if (dev->conn_netconfig) {
 		netconfig_destroy(dev->conn_netconfig);
 		dev->conn_netconfig = NULL;
+		l_settings_free(dev->conn_netconfig_settings);
+		l_free(dev->conn_peer_ip);
+		dev->conn_peer_ip = NULL;
 	}
 
 	if (dev->conn_new_intf_cmd_id)
@@ -761,6 +769,11 @@ static void p2p_netconfig_event_handler(enum netconfig_event event,
 	switch (event) {
 	case NETCONFIG_EVENT_CONNECTED:
 		l_timeout_remove(dev->conn_dhcp_timeout);
+
+		if (!dev->conn_peer_ip)
+			dev->conn_peer_ip = netconfig_get_dhcp_server_ipv4(
+							dev->conn_netconfig);
+
 		p2p_peer_connect_done(dev);
 		break;
 	default:
@@ -786,10 +799,11 @@ static void p2p_dhcp_timeout_destroy(void *user_data)
 	dev->conn_dhcp_timeout = NULL;
 }
 
-static void p2p_start_dhcp_client(struct p2p_device *dev)
+static void p2p_start_client_netconfig(struct p2p_device *dev)
 {
 	uint32_t ifindex = netdev_get_ifindex(dev->conn_netdev);
 	unsigned int dhcp_timeout_val;
+	struct l_settings *settings;
 
 	if (!l_settings_get_uint(iwd_get_config(), "P2P", "DHCPTimeout",
 					&dhcp_timeout_val))
@@ -803,9 +817,9 @@ static void p2p_start_dhcp_client(struct p2p_device *dev)
 		}
 	}
 
-	netconfig_configure(dev->conn_netconfig, p2p_dhcp_settings,
-				dev->conn_addr, p2p_netconfig_event_handler,
-				dev);
+	settings = dev->conn_netconfig_settings ?: p2p_dhcp_settings;
+	netconfig_configure(dev->conn_netconfig, settings, dev->conn_addr,
+				p2p_netconfig_event_handler, dev);
 	dev->conn_dhcp_timeout = l_timeout_create(dhcp_timeout_val,
 						p2p_dhcp_timeout, dev,
 						p2p_dhcp_timeout_destroy);
@@ -827,7 +841,7 @@ static void p2p_netdev_connect_cb(struct netdev *netdev,
 
 	switch (result) {
 	case NETDEV_RESULT_OK:
-		p2p_start_dhcp_client(dev);
+		p2p_start_client_netconfig(dev);
 		break;
 	case NETDEV_RESULT_AUTHENTICATION_FAILED:
 	case NETDEV_RESULT_ASSOCIATION_FAILED:
@@ -916,6 +930,13 @@ static void p2p_netdev_event(struct netdev *netdev, enum netdev_event event,
 	};
 }
 
+static const char *p2p_ip_to_string(uint32_t addr)
+{
+	struct in_addr ia = { .s_addr = L_CPU_TO_BE32(addr) };
+
+	return inet_ntoa(ia);
+}
+
 static void p2p_handshake_event(struct handshake_state *hs,
 				enum handshake_event event, void *user_data,
 				...)
@@ -925,6 +946,24 @@ static void p2p_handshake_event(struct handshake_state *hs,
 	va_start(args, user_data);
 
 	switch (event) {
+	case HANDSHAKE_EVENT_COMPLETE:
+	{
+		struct p2p_device *dev = user_data;
+		struct l_settings *ip_config;
+
+		if (!hs->support_ip_allocation)
+			break;
+
+		ip_config = l_settings_new();
+		l_settings_set_string(ip_config, "IPv4", "Address",
+					p2p_ip_to_string(hs->client_ip_addr));
+		l_settings_set_string(ip_config, "IPv4", "Netmask",
+					p2p_ip_to_string(hs->subnet_mask));
+		dev->conn_netconfig_settings = ip_config;
+		dev->conn_peer_ip = l_strdup(p2p_ip_to_string(hs->go_ip_addr));
+
+		break;
+	}
 	case HANDSHAKE_EVENT_FAILED:
 		netdev_handshake_failed(hs, va_arg(args, int));
 		break;
@@ -993,6 +1032,9 @@ static void p2p_try_connect_group(struct p2p_device *dev)
 	handshake_state_set_ssid(hs, bss->ssid, bss->ssid_len);
 	handshake_state_set_pmk(hs, dev->conn_psk, 32);
 
+	if (dev->conn_peer_capability.group_caps & P2P_GROUP_CAP_IP_ALLOCATION)
+		hs->support_ip_allocation = true;
+
 	r = netdev_connect(dev->conn_netdev, bss, hs, ie_iov, ie_num,
 				p2p_netdev_event, p2p_netdev_connect_cb, dev);
 	if (r < 0) {
@@ -1393,6 +1435,7 @@ static bool p2p_provision_scan_notify(int err, struct l_queue *bss_list,
 		l_debug("GO found in the scan results");
 
 		dev->conn_wsc_bss = bss;
+		dev->conn_peer_capability = *capability;
 		p2p_device_interface_create(dev);
 		l_queue_remove(bss_list, bss);
 		l_queue_destroy(bss_list,
@@ -4405,14 +4448,11 @@ static bool p2p_peer_get_connected_ip(struct l_dbus *dbus,
 					void *user_data)
 {
 	struct p2p_peer *peer = user_data;
-	char *server_ip;
 
-	if (!p2p_peer_operational(peer))
+	if (!p2p_peer_operational(peer) || !peer->dev->conn_peer_ip)
 		return false;
 
-	server_ip = netconfig_get_dhcp_server_ipv4(peer->dev->conn_netconfig);
-	l_dbus_message_builder_append_basic(builder, 's', server_ip);
-	l_free(server_ip);
+	l_dbus_message_builder_append_basic(builder, 's', peer->dev->conn_peer_ip);
 	return true;
 }
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] unit: Add two EAPOL IP allocation scenarios
  2020-09-14 13:51 [PATCH 1/5] eapol: IP Allocation KDE support Andrew Zaborowski
                   ` (2 preceding siblings ...)
  2020-09-14 13:51 ` [PATCH 4/5] p2p: Try IP allocation during 4-Way handshake on client Andrew Zaborowski
@ 2020-09-14 13:51 ` Andrew Zaborowski
  2020-09-14 16:46 ` [PATCH 1/5] eapol: IP Allocation KDE support Denis Kenzior
  4 siblings, 0 replies; 6+ messages in thread
From: Andrew Zaborowski @ 2020-09-14 13:51 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 6711 bytes --]

---
 unit/test-eapol.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/unit/test-eapol.c b/unit/test-eapol.c
index 08740a8e..eba249ed 100644
--- a/unit/test-eapol.c
+++ b/unit/test-eapol.c
@@ -3769,6 +3769,137 @@ static void eapol_ap_sta_handshake_bad_psk_test(const void *data)
 	assert(s.to_ap_msg_cnt == 1 && s.to_sta_msg_cnt == 1);
 }
 
+static void eapol_ap_sta_handshake_ip_alloc_ok_test(const void *data)
+{
+	static const unsigned char ap_rsne[] = {
+		0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
+		0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
+		0x00, 0x0f, 0xac, 0x02, 0x81, 0x00 };
+	static const unsigned char sta_rsne[] = {
+		0x30, 0x12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
+		0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
+		0x00, 0x0f, 0xac, 0x02 };
+	static const char *ssid = "TestWPA2PSK";
+	static const uint8_t psk[32] = {	/* secretsecret */
+		0x6a, 0xa3, 0xf0, 0x0b, 0x68, 0xbd, 0x8b, 0x46,
+		0x69, 0x83, 0xa5, 0x29, 0xa3, 0xfa, 0x57, 0x1c,
+		0x6c, 0x7b, 0x72, 0x41, 0x1d, 0xce, 0x33, 0x02,
+		0xa2, 0x2d, 0xdf, 0x77, 0xd1, 0x93, 0xdb, 0x5f };
+	struct test_ap_sta_data s = {
+		.ap_hs = test_ap_sta_hs_new(&s, 1),
+		.sta_hs = test_ap_sta_hs_new(&s, 2),
+		.ap_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
+		.sta_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 },
+	};
+
+	__handshake_set_get_nonce_func(random_nonce);
+	__handshake_set_install_tk_func(test_ap_sta_install_tk);
+	__handshake_set_install_gtk_func(NULL);
+
+	handshake_state_set_authenticator(s.ap_hs, true);
+	handshake_state_set_event_func(s.ap_hs, test_ap_sta_hs_event, &s);
+	handshake_state_set_authenticator_address(s.ap_hs, s.ap_address);
+	handshake_state_set_supplicant_address(s.ap_hs, s.sta_address);
+	handshake_state_set_supplicant_ie(s.ap_hs, sta_rsne);
+	handshake_state_set_authenticator_ie(s.ap_hs, ap_rsne);
+	handshake_state_set_ssid(s.ap_hs, (void *) ssid, strlen(ssid));
+	handshake_state_set_pmk(s.ap_hs, psk, 32);
+	s.ap_hs->support_ip_allocation = true;
+	s.ap_hs->client_ip_addr = 0x01020304;
+	s.ap_hs->subnet_mask = 0xffff0000;
+	s.ap_hs->go_ip_addr = 0x01020305;
+
+	handshake_state_set_authenticator(s.sta_hs, false);
+	handshake_state_set_event_func(s.sta_hs, test_ap_sta_hs_event, &s);
+	handshake_state_set_authenticator_address(s.sta_hs, s.ap_address);
+	handshake_state_set_supplicant_address(s.sta_hs, s.sta_address);
+	handshake_state_set_supplicant_ie(s.sta_hs, sta_rsne);
+	handshake_state_set_authenticator_ie(s.sta_hs, ap_rsne);
+	handshake_state_set_ssid(s.sta_hs, (void *) ssid, strlen(ssid));
+	handshake_state_set_pmk(s.sta_hs, psk, 32);
+	s.sta_hs->support_ip_allocation = true;
+
+	test_ap_sta_run(&s);
+
+	assert(s.ap_hs->support_ip_allocation);
+	assert(s.sta_hs->support_ip_allocation);
+	assert(s.sta_hs->client_ip_addr == s.ap_hs->client_ip_addr);
+	assert(s.sta_hs->subnet_mask == s.ap_hs->subnet_mask);
+	assert(s.sta_hs->go_ip_addr == s.ap_hs->go_ip_addr);
+
+	handshake_state_free(s.ap_hs);
+	handshake_state_free(s.sta_hs);
+	__handshake_set_install_tk_func(NULL);
+
+	assert(s.ap_success && s.sta_success);
+	assert(s.to_ap_msg_cnt == 2 && s.to_sta_msg_cnt == 2);
+	assert(!memcmp(s.ap_tk, s.sta_tk, 16));
+}
+
+static void eapol_ap_sta_handshake_ip_alloc_no_req_test(const void *data)
+{
+	static const unsigned char ap_rsne[] = {
+		0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
+		0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
+		0x00, 0x0f, 0xac, 0x02, 0x81, 0x00 };
+	static const unsigned char sta_rsne[] = {
+		0x30, 0x12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
+		0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
+		0x00, 0x0f, 0xac, 0x02 };
+	static const char *ssid = "TestWPA2PSK";
+	static const uint8_t psk[32] = {	/* secretsecret */
+		0x6a, 0xa3, 0xf0, 0x0b, 0x68, 0xbd, 0x8b, 0x46,
+		0x69, 0x83, 0xa5, 0x29, 0xa3, 0xfa, 0x57, 0x1c,
+		0x6c, 0x7b, 0x72, 0x41, 0x1d, 0xce, 0x33, 0x02,
+		0xa2, 0x2d, 0xdf, 0x77, 0xd1, 0x93, 0xdb, 0x5f };
+	struct test_ap_sta_data s = {
+		.ap_hs = test_ap_sta_hs_new(&s, 1),
+		.sta_hs = test_ap_sta_hs_new(&s, 2),
+		.ap_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
+		.sta_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 },
+	};
+
+	__handshake_set_get_nonce_func(random_nonce);
+	__handshake_set_install_tk_func(test_ap_sta_install_tk);
+	__handshake_set_install_gtk_func(NULL);
+
+	handshake_state_set_authenticator(s.ap_hs, true);
+	handshake_state_set_event_func(s.ap_hs, test_ap_sta_hs_event, &s);
+	handshake_state_set_authenticator_address(s.ap_hs, s.ap_address);
+	handshake_state_set_supplicant_address(s.ap_hs, s.sta_address);
+	handshake_state_set_supplicant_ie(s.ap_hs, sta_rsne);
+	handshake_state_set_authenticator_ie(s.ap_hs, ap_rsne);
+	handshake_state_set_ssid(s.ap_hs, (void *) ssid, strlen(ssid));
+	handshake_state_set_pmk(s.ap_hs, psk, 32);
+	s.ap_hs->support_ip_allocation = true;
+	s.ap_hs->client_ip_addr = 0x01020304;
+	s.ap_hs->subnet_mask = 0xffff0000;
+	s.ap_hs->go_ip_addr = 0x01020305;
+
+	handshake_state_set_authenticator(s.sta_hs, false);
+	handshake_state_set_event_func(s.sta_hs, test_ap_sta_hs_event, &s);
+	handshake_state_set_authenticator_address(s.sta_hs, s.ap_address);
+	handshake_state_set_supplicant_address(s.sta_hs, s.sta_address);
+	handshake_state_set_supplicant_ie(s.sta_hs, sta_rsne);
+	handshake_state_set_authenticator_ie(s.sta_hs, ap_rsne);
+	handshake_state_set_ssid(s.sta_hs, (void *) ssid, strlen(ssid));
+	handshake_state_set_pmk(s.sta_hs, psk, 32);
+	s.ap_hs->support_ip_allocation = false;
+
+	test_ap_sta_run(&s);
+
+	assert(!s.ap_hs->support_ip_allocation);
+	assert(!s.sta_hs->support_ip_allocation);
+
+	handshake_state_free(s.ap_hs);
+	handshake_state_free(s.sta_hs);
+	__handshake_set_install_tk_func(NULL);
+
+	assert(s.ap_success && s.sta_success);
+	assert(s.to_ap_msg_cnt == 2 && s.to_sta_msg_cnt == 2);
+	assert(!memcmp(s.ap_tk, s.sta_tk, 16));
+}
+
 #define IS_ENABLED(config_macro) _IS_ENABLED1(config_macro)
 #define _IS_ENABLED1(config_macro) _IS_ENABLED2(_XXXX##config_macro)
 #define _XXXX1 _YYYY,
@@ -3913,6 +4044,10 @@ int main(int argc, char *argv[])
 			&eapol_ap_sta_handshake_test, NULL);
 	l_test_add("EAPoL/Supplicant+Authenticator 4-Way Handshake Bad PSK",
 			&eapol_ap_sta_handshake_bad_psk_test, NULL);
+	l_test_add("EAPoL/Supplicant+Authenticator IP Allocation OK",
+			&eapol_ap_sta_handshake_ip_alloc_ok_test, NULL);
+	l_test_add("EAPoL/Supplicant+Authenticator IP Allocation no request",
+			&eapol_ap_sta_handshake_ip_alloc_no_req_test, NULL);
 
 done:
 	return l_test_run();
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/5] eapol: IP Allocation KDE support
  2020-09-14 13:51 [PATCH 1/5] eapol: IP Allocation KDE support Andrew Zaborowski
                   ` (3 preceding siblings ...)
  2020-09-14 13:51 ` [PATCH 5/5] unit: Add two EAPOL IP allocation scenarios Andrew Zaborowski
@ 2020-09-14 16:46 ` Denis Kenzior
  4 siblings, 0 replies; 6+ messages in thread
From: Denis Kenzior @ 2020-09-14 16:46 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

Hi Andrew,

On 9/14/20 8:51 AM, Andrew Zaborowski wrote:
> Support IP allocation during the 4-Way Handshake as defined in the P2P
> spec.  This is the supplicant side implementation.
> 
> The API requires the user to set hs->support_ip_allocation true before
> eapol_start().  On HANDSHAKE_EVENT_COMPLETE, if this same flag is still
> set, we've received the IP lease, the netmask and the authenticator's
> IP from the authenticator and there's no need to start DHCP.  If the
> flag is cleared, the user needs to use DHCP.
> ---
> I can split this into two flags if preferred.
> ---
>   src/eapol.c     | 76 +++++++++++++++++++++++++++++++++++++++++++------
>   src/handshake.h |  9 +++++-
>   2 files changed, 76 insertions(+), 9 deletions(-)
> 

Patches 1-3, 5 applied.  4 Doesn't apply.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-09-14 16:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-09-14 13:51 [PATCH 1/5] eapol: IP Allocation KDE support Andrew Zaborowski
2020-09-14 13:51 ` [PATCH 2/5] eapol: IP Allocation KDE support authenticator side Andrew Zaborowski
2020-09-14 13:51 ` [PATCH 3/5] netconfig: Don't bswap IP netmasks for __builtin_popcountl Andrew Zaborowski
2020-09-14 13:51 ` [PATCH 4/5] p2p: Try IP allocation during 4-Way handshake on client Andrew Zaborowski
2020-09-14 13:51 ` [PATCH 5/5] unit: Add two EAPOL IP allocation scenarios Andrew Zaborowski
2020-09-14 16:46 ` [PATCH 1/5] eapol: IP Allocation KDE support Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.