[PATCH 81/92] NAN: Add NAN-PAIRING-REQUEST notification

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Apr 22 05:24:12 PDT 2026


When PASN pairing authentication message is received and the peer wasn't
authorized to pair yet, store the frame and notify upper layers. Upon
NAN_PAIR authorization, process the stored frame.
This is needed, as otherwise the responder side may not know that it
should authorize pairing with the peer.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/common/wpa_ctrl.h           |  1 +
 src/nan/nan.h                   | 11 +++++++++
 src/nan/nan_i.h                 |  2 ++
 src/nan/nan_pairing.c           | 41 +++++++++++++++++++++++++++++++--
 wpa_supplicant/nan_supplicant.c | 10 ++++++++
 wpa_supplicant/notify.c         | 10 ++++++++
 wpa_supplicant/notify.h         |  3 +++
 7 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index afb207b509..628b64cf7d 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -255,6 +255,7 @@ extern "C" {
 #define NAN_BOOTSTRAP_SUCCESS "NAN-BOOTSTRAP-SUCCESS "
 #define NAN_BOOTSTRAP_FAILURE "NAN-BOOTSTRAP-FAILURE "
 #define NAN_NIK_RECEIVED "NAN-NIK-RECEIVED "
+#define NAN_PAIRING_REQUEST "NAN-PAIRING-REQUEST "
 
 /* NAN Pairing status
  * addr=<peer address> akmp=<SAE|PASN> cipher=<CCMP|GCMP-256> status=<success|failure> [nd_pmk=<hex>]
diff --git a/src/nan/nan.h b/src/nan/nan.h
index ab89fc6599..36b9b4acfc 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -663,6 +663,17 @@ struct nan_config {
 	const struct wpabuf *(*get_npk_akmp)(void *ctx, const u8 *peer_nmi,
 					     const u8 *nonce, const u8 *tag,
 					     int *akmp);
+
+
+	/**
+	 * pairing_request - Notify about received pairing request
+	 *
+	 * @ctx: Callback context from cb_ctx
+	 * @peer_nmi: Peer NMI address
+	 * @csid: Cipher suite ID requested by the peer
+	 * @instance_id: Service instance ID for which the pairing is requested
+	 */
+	void (*pairing_request)(void *ctx, const u8 *peer_nmi, u8 csid, u8 instance_id);
 };
 
 struct nan_data * nan_init(const struct nan_config *cfg);
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 598b552e81..c2257f56fb 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -488,6 +488,7 @@ enum nan_pairing_role {
  * @nonce: Nonce from peer's NIRA attribute
  * @tag: Tag from peer's NIRA attribute
  * @flags: Bitmap of pairing flags. See NAN_PAIRING_FLAG_*
+ * @pending_auth1: Pending PASN Authentication frame 1 to be processed
  */
 struct nan_pairing_peer_data {
 	struct nan_pairing_cfg pairing_cfg;
@@ -499,6 +500,7 @@ struct nan_pairing_peer_data {
 	u8 nonce[NAN_NIRA_NONCE_LEN];
 	u8 tag[NAN_NIRA_TAG_LEN];
 	u32 flags;
+	struct wpabuf *pending_auth1;
 };
 
 /**
diff --git a/src/nan/nan_pairing.c b/src/nan/nan_pairing.c
index b468de3bb4..43b59e154f 100644
--- a/src/nan/nan_pairing.c
+++ b/src/nan/nan_pairing.c
@@ -85,6 +85,9 @@ int nan_pairing_add_attrs(struct nan_data *nan, struct wpabuf *buf)
 
 void nan_pairing_deinit_peer(struct nan_peer *peer)
 {
+	wpabuf_free(peer->pairing.pending_auth1);
+	peer->pairing.pending_auth1 = NULL;
+
 	if (!peer->pairing.pasn)
 		return;
 
@@ -107,7 +110,7 @@ int nan_pairing_abort(struct nan_data *nan_data, const u8 *peer_addr)
 		return -1;
 	}
 
-	if (!peer->pairing.pasn) {
+	if (!peer->pairing.pasn && !peer->pairing.pending_auth1) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: Pairing abort: No PASN in progress with peer "
 			   MACSTR, MAC2STR(peer_addr));
@@ -554,8 +557,20 @@ int nan_pairing_initiate_pasn_auth(struct nan_data *nan_data, const u8 *addr,
 
 	nan_configure_peer_schedule(nan_data, peer, sched);
 
-	if (responder)
+	if (responder) {
+		if (peer->pairing.pending_auth1) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Pairing: Responder - process pending Auth1");
+			ret = nan_pairing_auth_rx(nan_data,
+				wpabuf_head(peer->pairing.pending_auth1),
+				wpabuf_len(peer->pairing.pending_auth1));
+			wpabuf_free(peer->pairing.pending_auth1);
+			peer->pairing.pending_auth1 = NULL;
+
+			return ret;
+		}
 		return 0;
+	}
 
 	if (auth_mode == NAN_PASN_AUTH_MODE_PMK) {
 		peer->pairing.flags |= NAN_PAIRING_FLAG_NPK_VERIFICATION;
@@ -1210,6 +1225,28 @@ int nan_pairing_auth_rx(struct nan_data *nan_data,
 	}
 
 	if (!peer->pairing.pasn) {
+		if (status_code == WLAN_STATUS_SUCCESS &&
+		    auth_transaction == 1) {
+			struct nan_cipher_suite cs;
+
+			if (nan_pairing_process_elems(nan_data, peer, mgmt, len, &cs)) {
+				wpa_printf(MSG_DEBUG,
+					   "NAN: Pairing: Handle Auth1 NAN attributes failed");
+				return -1;
+			}
+
+			wpabuf_free(peer->pairing.pending_auth1);
+			peer->pairing.pending_auth1 =
+				wpabuf_alloc_copy((const u8 *)mgmt, len);
+			if (!peer->pairing.pending_auth1)
+				return -1;
+
+			nan_data->cfg->pairing_request(nan_data->cfg->cb_ctx,
+						       peer->nmi_addr, cs.csid,
+						       cs.instance_id);
+			return 0;
+		}
+
 		wpa_printf(MSG_DEBUG,
 			   "NAN: Pairing: PASN data not initialized for peer");
 		return -1;
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 94b7366a8c..432e752fc3 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -1057,6 +1057,15 @@ static const struct wpabuf *wpas_nan_get_npk_akmp_cb(void *ctx,
 	wpa_printf(MSG_DEBUG, "NAN: No matching NIK found");
 	return NULL;
 }
+
+
+static void
+wpas_nan_pasn_pairing_request_cb(void *ctx, const u8 *peer_nmi, u8 csid,
+				 u8 instance_id)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	wpas_notify_nan_pairing_request(wpa_s, peer_nmi, csid, instance_id);
+}
 #endif /* CONFIG_PASN */
 
 
@@ -1088,6 +1097,7 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 		nan.update_pairing_credentials =
 			wpas_nan_update_pairing_credentials_cb;
 		nan.get_npk_akmp = wpas_nan_get_npk_akmp_cb;
+		nan.pairing_request = wpas_nan_pasn_pairing_request_cb;
 		nan.pairing_cfg.pairing_setup = true;
 		nan.pairing_cfg.npk_caching = true;
 		nan.pairing_cfg.pairing_verification = true;
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 82f05fd117..3e122ed7fe 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1330,6 +1330,16 @@ out:
 	os_free(npk_hex);
 }
 
+
+void wpas_notify_nan_pairing_request(struct wpa_supplicant *wpa_s,
+				     const u8 *peer_nmi, u8 csid,
+				     u8 instance_id)
+{
+	wpa_msg_global(wpa_s, MSG_INFO, NAN_PAIRING_REQUEST
+		       "peer_nmi=" MACSTR " csid=%u instance_id=%u",
+		       MAC2STR(peer_nmi), csid, instance_id);
+}
+
 #endif /* CONFIG_NAN || CONFIG_NAN_USD */
 
 
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 3db90b780e..3b1517d91b 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -230,5 +230,8 @@ void wpas_notify_nan_bootstrap_failure(struct wpa_supplicant *wpa_s,
 				       const u8 *peer_addr, u16 pbm,
 				       u8 reason, int handle,
 				       u8 requestor_instance_id);
+void wpas_notify_nan_pairing_request(struct wpa_supplicant *wpa_s,
+				     const u8 *peer_nmi, u8 csid,
+				     u8 instance_id);
 
 #endif /* NOTIFY_H */
-- 
2.53.0




More information about the Hostap mailing list