diff mbox series

[v3,24/25] P2P: Add support to get PASN PTK

Message ID 1722850403-8852-25-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
Signed-off-by: Shivani Baranwal <quic_shivbara@quicinc.com>
---
 src/common/wpa_common.c         |  2 ++
 src/common/wpa_common.h         |  1 +
 src/p2p/p2p.c                   | 54 +++++++++++++++++++++++++++++++++++++++--
 src/p2p/p2p.h                   |  8 ++++++
 src/p2p/p2p_i.h                 | 10 ++++++++
 wpa_supplicant/ctrl_iface.c     | 23 ++++++++++++++++++
 wpa_supplicant/p2p_supplicant.c | 11 +++++++++
 wpa_supplicant/p2p_supplicant.h |  8 ++++++
 8 files changed, 115 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 28f478c..ef8a0fa 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -582,6 +582,7 @@  int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
 	ptk->kek2_len = 0;
 	ptk->kck2_len = 0;
 
+	ptk->ptk_len = ptk_len;
 	os_memset(tmp, 0, sizeof(tmp));
 	os_memset(data, 0, data_len);
 	return 0;
@@ -1555,6 +1556,7 @@  int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
 				ptk->kdk, ptk->kdk_len);
 	}
 
+	ptk->ptk_len = ptk_len;
 	forced_memzero(tmp, sizeof(tmp));
 	ret = 0;
 err:
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index 8f77d38..63196bc 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -270,6 +270,7 @@  struct wpa_ptk {
 	size_t kck2_len;
 	size_t kek2_len;
 	size_t kdk_len;
+	size_t ptk_len;
 	size_t ltf_keyseed_len;
 	int installed; /* 1 if key has already been installed to driver */
 };
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 2c81ec5..59a15a8 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -3064,6 +3064,11 @@  void p2p_group_formation_failed(struct p2p_data *p2p)
 	p2p_clear_go_neg(p2p);
 }
 
+void p2p_set_store_pasn_ptk(struct p2p_data *p2p, u8 val)
+{
+	p2p->cfg->store_pasn_ptk = val;
+}
+
 
 bool is_p2p_6ghz_disabled(struct p2p_data *p2p)
 {
@@ -6875,6 +6880,7 @@  int p2p_handle_pasn_auth(struct p2p_data *p2p, struct p2p_device *dev,
 			p2p_dbg(p2p, "P2P PASN Responder: Handle PASN Auth3 failed");
 			return -1;
 		}
+		p2p_pasn_store_ptk(p2p, &pasn->ptk);
 		if (p2p_pasn_handle_action_wrapper(p2p, dev, mgmt, len, freq,
 						   auth_transaction)) {
 			p2p_dbg(p2p, "P2P PASN Responder: Handle Auth3 action wrapper failed");
@@ -6930,12 +6936,12 @@  int p2p_pasn_auth_rx(struct p2p_data *p2p, const struct ieee80211_mgmt *mgmt,
 			return -1;
 		}
 		ret = wpa_pasn_auth_rx(pasn, (const u8 *)mgmt, len, &pasn_data);
-		forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk));
-
 		if (ret < 0) {
 			p2p_dbg(p2p, "P2P PASN: wpa_pasn_auth_rx failed");
 			dev->role = P2P_ROLE_IDLE;
 		}
+		p2p_pasn_store_ptk(p2p, &pasn->ptk);
+		forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk));
 
 	} else {
 		ret = p2p_handle_pasn_auth(p2p, dev, mgmt, len, freq);
@@ -6952,4 +6958,48 @@  void p2p_pasn_pmksa_set_pmk(struct p2p_data *p2p, const u8 *src, const u8 *dst,
 	pasn_responder_pmksa_cache_add(p2p->responder_pmksa, src, dst, pmk,
 				       pmk_len, pmkid);
 }
+
+
+void p2p_pasn_store_ptk(struct p2p_data *p2p, struct wpa_ptk *ptk)
+{
+	u8 *pos;
+
+	if (!p2p->cfg->store_pasn_ptk)
+		return;
+
+	if (ptk->ptk_len > sizeof(p2p->pasn_ptk)) {
+		p2p_dbg(p2p, "P2P PASN PTK exceeds: (len=%ld)", ptk->ptk_len);
+		return;
+	}
+
+	pos = p2p->pasn_ptk;
+	p2p->pasn_ptk_len = ptk->ptk_len;
+	if (ptk->kck_len) {
+		os_memcpy(pos, ptk->kck, ptk->kck_len);
+		pos += ptk->kck_len;
+	}
+	if (ptk->kek_len) {
+		os_memcpy(pos, ptk->kek, ptk->kek_len);
+		pos += ptk->kek_len;
+	}
+	if (ptk->tk_len) {
+		os_memcpy(pos, ptk->tk, ptk->tk_len);
+		pos += ptk->tk_len;
+	}
+	if (ptk->kdk_len) {
+		os_memcpy(pos, ptk->kdk, ptk->kdk_len);
+		pos += ptk->kdk_len;
+	}
+}
+
+
+int p2p_pasn_get_ptk(struct p2p_data *p2p, const u8 **buf, size_t *buf_len)
+{
+	if (!p2p || !p2p->cfg->store_pasn_ptk || !p2p->pasn_ptk_len)
+		return -1;
+
+	*buf_len = p2p->pasn_ptk_len;
+	*buf = p2p->pasn_ptk;
+	return 0;
+}
 #endif
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 6024370..5d798a0 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -752,6 +752,11 @@  struct p2p_config {
 	void *cb_ctx;
 
 	/**
+	 * store pasn ptk, Used for certification mode
+	 */
+	bool store_pasn_ptk;
+
+	/**
 	 * debug_print - Debug print
 	 * @ctx: Callback context from cb_ctx
 	 * @level: Debug verbosity level (MSG_*)
@@ -2716,4 +2721,7 @@  int p2p_pasn_auth_tx_status(struct p2p_data *p2p, const u8 *data,
 			    size_t data_len, u8 acked, bool verify);
 void p2p_pasn_pmksa_set_pmk(struct p2p_data *p2p, const u8 *src, const u8 *dst,
 			    u8 *pmk, u16 pmk_len, u8 *pmkid);
+void p2p_set_store_pasn_ptk(struct p2p_data *p2p, u8 val);
+void p2p_pasn_store_ptk(struct p2p_data *p2p, struct wpa_ptk *ptk);
+int p2p_pasn_get_ptk(struct p2p_data *p2p, const u8 **buf, size_t *buf_len);
 #endif /* P2P_H */
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 3e9119b..32a8421 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -681,6 +681,16 @@  struct p2p_data {
 	 * Indicate that auto go is enabled for this device
 	 */
 	u8 auto_go;
+
+	/**
+	 * pasn ptk of recent auth when store_pasn_ptk enabled
+	 */
+	u8 pasn_ptk[128];
+
+	/**
+	 * pasn ptk length
+	 */
+	size_t pasn_ptk_len;
 };
 
 /**
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 5a5b9e4..9c9e9a7 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -7748,6 +7748,11 @@  static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
 		return 0;
 	}
 
+	if (os_strcmp(cmd, "store_pasn_ptk") == 0) {
+		p2p_set_store_pasn_ptk(wpa_s->global->p2p, atoi(param));
+		return 0;
+	}
+
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
 		   cmd);
 
@@ -10905,6 +10910,20 @@  static void wpas_ctrl_iface_pmksa_flush(struct wpa_supplicant *wpa_s)
 #endif /* CONFIG_AP */
 }
 
+#ifdef CONFIG_PASN
+
+static int p2p_ctrl_get_pasn_ptk(struct wpa_supplicant *wpa_s, char *buf,
+				 size_t buflen)
+{
+	const u8 *ptk;
+	size_t ptk_len;
+
+	if (wpas_p2p_get_pasn_ptk(wpa_s, &ptk, &ptk_len))
+		return -1;
+	return wpa_snprintf_hex(buf, buflen, ptk, ptk_len);
+}
+
+#endif // CONFIG_PASN
 
 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
 
@@ -12918,6 +12937,10 @@  char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 			reply_len = -1;
 	} else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
 		reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
+#ifdef CONFIG_PASN
+	} else if (os_strcmp(buf, "P2P_GET_PASNPTK") == 0) {
+		reply_len = p2p_ctrl_get_pasn_ptk(wpa_s, reply, reply_size);
+#endif /* CONFIG_PASN */
 	} else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
 		reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
 						   reply_size);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 249390b..394beef 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -11159,4 +11159,15 @@  int wpas_p2p_pasn_auth_rx(struct wpa_supplicant *wpa_s,
 		return -2;
 	return p2p_pasn_auth_rx(p2p, mgmt, len, freq);
 }
+
+
+int wpas_p2p_get_pasn_ptk(struct wpa_supplicant *wpa_s, const u8 **ptk,
+			  size_t *ptk_len)
+{
+	struct p2p_data *p2p = wpa_s->global->p2p;
+
+	if (wpa_s->global->p2p_disabled || !p2p)
+		return -2;
+	return p2p_pasn_get_ptk(p2p, ptk, ptk_len);
+}
 #endif /* CONFIG_PASN */
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index c9e9c78..3dcc9e3 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -234,6 +234,8 @@  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);
+int wpas_p2p_get_pasn_ptk(struct wpa_supplicant *wpa_s, const u8 **ptk,
+			  size_t *ptk_len);
 #else /* CONFIG_P2P */
 
 static inline int
@@ -377,6 +379,12 @@  wpas_p2p_remove_all_identity(struct wpa_supplicant *wpa_s)
 	return 0;
 }
 
+static inline int wpas_p2p_get_pasn_ptk(struct wpa_supplicant *wpa_s,
+					const u8 **ptk, size_t *ptk_len)
+{
+	return 0;
+}
+
 #endif /* CONFIG_P2P */
 
 #endif /* P2P_SUPPLICANT_H */