[PATCH 13/92] NAN: Add NIRA to NAN IE when pairing verification is enabled

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Apr 22 05:23:04 PDT 2026


From: Avraham Stern <avraham.stern at intel.com>

Add the NAN Identity Resolution attribute (NIRA) to the NAN IE if
pairing verification is enabled.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 src/nan/nan.c         |  7 +++++++
 src/nan/nan_i.h       | 18 ++++++++++++++++
 src/nan/nan_pairing.c | 49 +++++++++++++++++++++++++++++++++++++++++++
 src/nan/nan_util.c    | 33 +++++++++++++++++++++++++++++
 4 files changed, 107 insertions(+)

diff --git a/src/nan/nan.c b/src/nan/nan.c
index 969b37d712..3da56f4854 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -35,6 +35,13 @@ struct nan_data * nan_init(const struct nan_config *cfg)
 	if (!nan)
 		return NULL;
 
+	if (cfg->pairing_cfg.pairing_verification &&
+	    nan_nira_get_tag_nonce(cfg, nan->nira_nonce, nan->nira_tag) < 0) {
+		wpa_printf(MSG_DEBUG, "NAN: Failed to get NIRA tag and nonce");
+		os_free(nan);
+		return NULL;
+	}
+
 	nan->cfg = os_memdup(cfg, sizeof(*cfg));
 	if (!nan->cfg) {
 		os_free(nan);
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 323274312b..d917b48ffb 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -482,6 +482,8 @@ struct nan_peer {
  * @next_dialog_token: Dialog token for NDP and NDL negotiations. Incremented
  *     for each NDP and NDL request.
  * @cluster_id: Current cluster ID
+ * @nira_nonce: Nonce for NAN Identity Resolution attribute (NIRA)
+ * @nira_tag: Tag for NAN Identity Resolution attribute (NIRA)
  */
 struct nan_data {
 	struct nan_config *cfg;
@@ -492,6 +494,9 @@ struct nan_data {
 	u8 next_dialog_token;
 
 	u8 cluster_id[ETH_ALEN];
+
+	u8 nira_nonce[NAN_NIRA_NONCE_LEN];
+	u8 nira_tag[NAN_NIRA_TAG_LEN];
 };
 
 struct nan_attrs_entry {
@@ -684,5 +689,18 @@ bool nan_bootstrap_handle_rx(struct nan_data *nan, const u8 *peer_nmi,
 			     const u8 *npba, u16 npba_len,
 			     const u8 *buf, size_t len,
 			     int handle, u8 req_instance_id);
+int nan_add_nira_attr(struct wpabuf *buf, const u8 *nira_tag,
+		      const u8 *nira_nonce);
+#ifdef CONFIG_PASN
+int nan_nira_get_tag_nonce(const struct nan_config *nan, u8 *nira_nonce,
+			   u8 *nira_tag);
+#else
+static inline
+int nan_nira_get_tag_nonce(const struct nan_config *nan, u8 *nira_nonce,
+			   u8 *nira_tag)
+{
+	return -1;
+}
+#endif /* CONFIG_PASN */
 
 #endif /* NAN_I_H */
diff --git a/src/nan/nan_pairing.c b/src/nan/nan_pairing.c
index 49cfa17073..60c523c64e 100644
--- a/src/nan/nan_pairing.c
+++ b/src/nan/nan_pairing.c
@@ -10,6 +10,47 @@
 #include "common.h"
 #include "nan/nan_i.h"
 
+/*
+ * nan_nira_get_tag_nonce - Generate NIRA nonce and compute NIRA tag
+ *
+ * @nan: Pointer to NAN configuration structure
+ * @nira_nonce: Buffer to store the generated NIRA nonce (output)
+ * @nira_tag: Buffer to store the computed NIRA tag (output)
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function generates a random NIRA (NAN Identity Resolution Attribute)
+ * nonce and derives the corresponding NIRA tag using the
+ * NIK (NAN Identity Key), NMI address, and the generated nonce.
+ *
+ * The caller must ensure that nira_nonce buffer is at least NAN_NIRA_NONCE_LEN
+ * bytes and nira_tag buffer is at least NAN_NIRA_TAG_LEN bytes.
+ */
+int nan_nira_get_tag_nonce(const struct nan_config *nan, u8 *nira_nonce,
+			   u8 *nira_tag)
+{
+	struct wpabuf *tag_buf;
+
+	if (os_get_random(nira_nonce, NAN_NIRA_NONCE_LEN) < 0) {
+		wpa_printf(MSG_DEBUG, "NAN: Failed to generate NIRA nonce");
+		return -1;
+	}
+
+	tag_buf = nan_crypto_derive_nira_tag(nan->nik, NAN_NIK_LEN,
+					     nan->nmi_addr, nira_nonce);
+	if (!tag_buf)
+		return -1;
+
+	os_memcpy(nira_tag, wpabuf_head(tag_buf), NAN_NIRA_TAG_LEN);
+	wpabuf_free(tag_buf);
+
+	wpa_hexdump_key(MSG_DEBUG, "NAN: NIK", nan->nik, NAN_NIK_LEN);
+	wpa_hexdump(MSG_DEBUG, "NAN: NIRA-NONCE", nira_nonce,
+		    NAN_NIRA_NONCE_LEN);
+	wpa_hexdump(MSG_DEBUG, "NAN: NIRA-TAG", nira_tag, NAN_NIRA_TAG_LEN);
+	return 0;
+}
+
+
 /*
  * nan_pairing_add_attrs - Add NAN pairing attributes to a buffer
  *
@@ -28,5 +69,13 @@ int nan_pairing_add_attrs(struct nan_data *nan, struct wpabuf *buf)
 
 	nan_add_dev_capa_ext_attr(nan, buf);
 
+	if (nan->cfg->pairing_cfg.pairing_verification) {
+		if (nan_add_nira_attr(buf, nan->nira_tag, nan->nira_nonce)) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Failed to add NIRA attribute");
+			return -1;
+		}
+	}
+
 	return 0;
 }
diff --git a/src/nan/nan_util.c b/src/nan/nan_util.c
index 31df1c848e..3c9b7fd871 100644
--- a/src/nan/nan_util.c
+++ b/src/nan/nan_util.c
@@ -410,6 +410,39 @@ void nan_add_dev_capa_ext_attr(struct nan_data *nan, struct wpabuf *buf)
 	wpabuf_put_u8(buf, pairing_and_npk_caching);
 }
 
+/*
+ * nan_add_nira_attr - Add NIRA (NAN Identity Resolution Attribute) to a buffer
+ *
+ * @buf: Buffer to append the NIRA attribute to
+ * @nira_tag: Pointer to NIRA tag data (NAN_NIRA_TAG_LEN bytes)
+ * @nira_nonce: Pointer to NIRA nonce data (NAN_NIRA_NONCE_LEN bytes)
+ *
+ * This function constructs and appends a NAN Identity Resolution Attribute
+ * (NIRA) to the provided buffer.
+ *
+ * Returns: 0 on success, -1 if there is insufficient space in the buffer
+ */
+int nan_add_nira_attr(struct wpabuf *buf, const u8 *nira_tag,
+		      const u8 *nira_nonce)
+{
+	u16 attr_len = 1 + NAN_NIRA_NONCE_LEN + NAN_NIRA_TAG_LEN;
+
+	if (wpabuf_tailroom(buf) <
+	    (unsigned int)(NAN_ATTR_HDR_LEN + attr_len)) {
+		wpa_printf(MSG_DEBUG,
+			   "NAN: Not enough space to add NIRA attribute");
+		return -1;
+	}
+
+	wpabuf_put_u8(buf, NAN_ATTR_NIRA);
+	wpabuf_put_le16(buf, attr_len);
+	wpabuf_put_u8(buf, NAN_NIRA_CIPHER_VER_128);
+	wpabuf_put_data(buf, nira_nonce, NAN_NIRA_NONCE_LEN);
+	wpabuf_put_data(buf, nira_tag, NAN_NIRA_TAG_LEN);
+
+	return 0;
+}
+
 
 /**
  * nan_chan_to_chan_idx_map - Convert an op_class and chan to channel bitmap
-- 
2.53.0




More information about the Hostap mailing list