diff mbox series

[v3,23/25] P2P: Add support to store indentity key in conf file

Message ID 1722850403-8852-24-git-send-email-quic_shivbara@quicinc.com
State Deferred
Headers show
Series Add support for P2P2 | expand

Commit Message

Shivani Baranwal Aug. 5, 2024, 9:33 a.m. UTC
When persistent is enabled, store identity key in conf file which is needed
for pairing verification to invoke the persistent group.

Signed-off-by: Shivani Baranwal <quic_shivbara@quicinc.com>
---
 wpa_supplicant/ctrl_iface.c     |   3 +
 wpa_supplicant/p2p_supplicant.c | 161 +++++++++++++++++++++++++++++++++++++++-
 wpa_supplicant/p2p_supplicant.h |   7 ++
 3 files changed, 169 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index d00cfda..5a5b9e4 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -12984,6 +12984,9 @@  char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 	} else if (os_strcmp(buf, "P2P_LO_STOP") == 0) {
 		if (wpas_p2p_lo_stop(wpa_s))
 			reply_len = -1;
+	} else if (os_strcmp(buf, "P2P_REMOVE_IDENTITY") == 0) {
+		if (wpas_p2p_remove_all_identity(wpa_s))
+			reply_len = -1;
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_WIFI_DISPLAY
 	} else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) {
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 903aa42..249390b 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -167,6 +167,8 @@  wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s,
 static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx);
 static int wpas_p2p_disallowed_freq(struct wpa_global *global,
 				    unsigned int freq);
+static void wpas_p2p_store_go_identity(struct wpa_supplicant *wpa_s,
+				       const u8 *go_dev_addr, const u8 *bssid);
 #ifdef CONFIG_PASN
 static int wpas_p2p_initiate_pasn_auth(struct wpa_supplicant *wpa_s,
 				       const u8 *peer_addr, int freq);
@@ -1133,6 +1135,7 @@  static int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s,
 	struct wpabuf *p2p;
 	u8 group_capab;
 	const u8 *addr;
+	int persistent;
 
 	if (wpa_s->go_params)
 		bssid = wpa_s->go_params->peer_interface_addr;
@@ -1189,7 +1192,12 @@  static int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s,
 		   "go_dev_addr=" MACSTR,
 		   MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));
 
-	return !!(group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP);
+	persistent = !!(group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP);
+
+	if (persistent)
+		wpas_p2p_store_go_identity(wpa_s, go_dev_addr, bssid);
+
+	return persistent;
 }
 
 
@@ -3494,7 +3502,7 @@  static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
 
 	for (s = wpa_s->conf->ssid; s; s = s->next) {
 		if (s->disabled == 2 &&
-		    ether_addr_equal(s->bssid, go_dev_addr) &&
+		    //ether_addr_equal(s->bssid, go_dev_addr) &&
 		    s->ssid_len == ssid_len &&
 		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
 			break;
@@ -8568,6 +8576,107 @@  int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
 			  go_dev_addr, persistent, pref_freq, -1, 0);
 }
 
+int wpas_p2p_remove_all_identity(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_dev_ik *ik;
+
+	for (ik = wpa_s->conf->identity; ik; ik = ik->next)
+		wpa_config_remove_identity(wpa_s->conf, ik->id);
+
+	if (wpa_s->conf->update_config &&
+	    wpa_config_write(wpa_s->confname, wpa_s->conf)) {
+		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
+		return -1;
+	}
+	return 0;
+}
+
+static void wpas_p2p_store_identity(struct wpa_supplicant *wpa_s, u8 cipher,
+				    u8 *dik_data, u16 dik_len, u8 *pmk,
+				    u16 pmk_len, u8 *pmkid)
+{
+	u8 dik[64];
+	struct wpa_dev_ik *ik;
+
+	for (ik = wpa_s->conf->identity; ik; ik = ik->next) {
+		if (dik_len == ik->dik_len) {
+			hexstr2bin(ik->dik_data, dik, dik_len);
+			if (os_memcmp(dik_data, dik, dik_len) == 0) {
+				wpa_printf(MSG_DEBUG,
+					   "P2P: Remove previous entry of peer");
+				wpa_config_remove_identity(wpa_s->conf, ik->id);
+				break;
+			}
+		}
+	}
+
+	wpa_printf(MSG_DEBUG, "P2P: Create a new Device Identity entry");
+	ik = wpa_config_add_identity(wpa_s->conf);
+	if (ik == NULL)
+		return;
+
+	ik->dik_data = os_zalloc(dik_len * 2 + 1);
+	if (!ik->dik_data)
+		return;
+	ik->pmk = os_zalloc(pmk_len * 2 + 1);
+	if (!ik->pmk)
+		return;
+	ik->pmkid = os_zalloc(PMKID_LEN * 2 + 1);
+	if (!ik->pmkid)
+		return;
+
+	wpa_snprintf_hex(ik->dik_data, dik_len * 2 + 1, dik_data,
+			 dik_len);
+	ik->dik_len = dik_len;
+	ik->dik_cipher = cipher;
+
+	wpa_snprintf_hex(ik->pmk, pmk_len * 2 + 1, pmk, pmk_len);
+	ik->pmk_len = pmk_len;
+
+	wpa_snprintf_hex(ik->pmkid, PMKID_LEN * 2 + 1, pmkid, PMKID_LEN);
+
+	if (wpa_s->conf->update_config &&
+	    wpa_config_write(wpa_s->confname, wpa_s->conf))
+		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
+}
+
+
+static void wpas_p2p_store_go_identity(struct wpa_supplicant *wpa_s,
+				       const u8 *go_dev_addr, const u8 *bssid)
+{
+	int ret;
+	u8 cipher;
+	u16 dik_len, pmk_len;
+	u8 *dik_data, *pmk, *pmkid;
+	u8 iface_addr[ETH_ALEN];
+	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
+
+	if (!wpa_s->p2p2)
+		return;
+
+	ret = p2p_get_dev_identity_key(p2p_wpa_s->global->p2p, go_dev_addr,
+				       &dik_data, &dik_len, &cipher);
+	if (ret)
+		return;
+
+	ret = p2p_get_interface_addr(p2p_wpa_s->global->p2p, go_dev_addr,
+				     iface_addr);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "P2P: Fetch PMK from go bssid"
+			   "(bssid " MACSTR ")", MAC2STR(bssid));
+		memcpy(iface_addr, bssid, ETH_ALEN);
+	}
+	ret = wpa_sm_pmksa_get_pmk(wpa_s->wpa, iface_addr, &pmk, &pmk_len,
+				   &pmkid);
+	if (ret)
+		return;
+
+	wpa_printf(MSG_DEBUG, "P2P: Storing Device identity of "
+		   "client (Interface Addr " MACSTR ")", MAC2STR(iface_addr));
+	wpas_p2p_store_identity(p2p_wpa_s, cipher, dik_data, dik_len, pmk,
+				pmk_len, pmkid);
+}
+
 
 void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
 {
@@ -9393,6 +9502,52 @@  struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
 }
 
 
+static void wpas_p2p_store_client_identity(struct wpa_supplicant *wpa_s,
+					   const u8 *addr)
+{
+	int ret;
+	u8 cipher;
+	u16 dik_len, pmk_len;
+	u8 *dik_data, *pmk, *pmkid;
+	u8 iface_addr[ETH_ALEN];
+	struct hostapd_data *hapd;
+	struct wpa_supplicant *p2p_wpa_s = wpa_s->global->p2p_init_wpa_s;
+
+	if (!wpa_s->p2p2)
+		return;
+
+	hapd = wpa_s->ap_iface->bss[0];
+	if (!hapd)
+		return;
+
+	ret = p2p_get_dev_identity_key(p2p_wpa_s->global->p2p, addr,
+				       &dik_data, &dik_len, &cipher);
+	if (ret)
+		return;
+
+	wpa_printf(MSG_DEBUG, "P2P: Fetch PMK from client"
+		   "(Device Addr " MACSTR ")", MAC2STR(addr));
+	ret = wpa_auth_pmksa_get_pmk(hapd->wpa_auth, addr, &pmk, &pmk_len,
+				     &pmkid);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "P2P: Fetch PMK from client"
+			   "(Iface Addr " MACSTR ")", MAC2STR(iface_addr));
+		ret = p2p_get_interface_addr(p2p_wpa_s->global->p2p, addr,
+					     iface_addr);
+		if (ret)
+			return;
+		ret = wpa_auth_pmksa_get_pmk(hapd->wpa_auth, iface_addr, &pmk,
+					     &pmk_len, &pmkid);
+		if (ret)
+			return;
+	}
+
+	wpa_printf(MSG_DEBUG, "P2P: Storing Device identity of "
+		   "client (Device Addr " MACSTR ")", MAC2STR(addr));
+	wpas_p2p_store_identity(p2p_wpa_s, cipher, dik_data, dik_len, pmk,
+				pmk_len, pmkid);
+}
+
 void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
 				       const u8 *addr)
 {
@@ -9434,6 +9589,8 @@  void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
 	wpa_s->global->p2p_go_wait_client.sec = 0;
 	if (addr == NULL)
 		return;
+
+	wpas_p2p_store_client_identity(wpa_s, addr);
 	wpas_p2p_add_persistent_group_client(wpa_s, addr);
 }
 
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 1e5f77a..c9e9c78 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -233,6 +233,7 @@  struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s);
 int wpas_p2p_pasn_auth_rx(struct wpa_supplicant *wpa_s,
 			  const struct ieee80211_mgmt *mgmt, size_t len,
 			  int freq);
+int wpas_p2p_remove_all_identity(struct wpa_supplicant *wpa_s);
 #else /* CONFIG_P2P */
 
 static inline int
@@ -370,6 +371,12 @@  wpas_p2p_pasn_auth_rx(struct wpa_supplicant *wpa_s,
 	return 0;
 }
 
+static inline int
+wpas_p2p_remove_all_identity(struct wpa_supplicant *wpa_s)
+{
+	return 0;
+}
+
 #endif /* CONFIG_P2P */
 
 #endif /* P2P_SUPPLICANT_H */