[PATCH 55/92] NAN: Add supported cipher suite list to the discovery result callback

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


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

When a service is discovered, get the supported cipher suites from
the Cipher Suite Information attribute and add them to the discovery
result callback.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 src/ap/nan_usd_ap.c             |  4 +-
 src/common/nan_de.c             | 82 ++++++++++++++++++++++++++++++++-
 src/common/nan_de.h             |  4 +-
 wpa_supplicant/nan_supplicant.c |  4 +-
 4 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/src/ap/nan_usd_ap.c b/src/ap/nan_usd_ap.c
index d7719e89cb..41e99510d9 100644
--- a/src/ap/nan_usd_ap.c
+++ b/src/ap/nan_usd_ap.c
@@ -49,7 +49,9 @@ hostapd_nan_de_discovery_result(void *ctx, int subscribe_id,
 				const u8 *ssi, size_t ssi_len,
 				int peer_publish_id, const u8 *peer_addr,
 				bool fsd, bool fsd_gas,
-				const u8 *pmkid_list, size_t pmkid_count)
+				const u8 *pmkid_list, size_t pmkid_count,
+				const u8 *cipher_suite,
+				size_t n_cipher_suite)
 {
 	struct hostapd_data *hapd = ctx;
 	char *ssi_hex;
diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index 7a728c45b5..4959ccd7fb 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -1132,6 +1132,73 @@ static void nan_de_get_sdea(const u8 *buf, size_t len, u8 instance_id,
 }
 
 
+static size_t nan_de_parse_csia(const u8 *buf, size_t len, u8 instance_id,
+				u8 *cipher_suites, size_t max_cipher_suites,
+				u8 *capabilities)
+{
+	const u8 *csia, *pos, *end;
+	u16 csia_len;
+	size_t cs_count = 0;
+	struct nan_cipher_suite_info *cs_info;
+
+	csia = nan_de_get_attr(buf, len, NAN_ATTR_CSIA, 0);
+	if (!csia)
+		return 0;
+
+	csia++;
+	csia_len = WPA_GET_LE16(csia);
+	csia += 2;
+
+	if (csia_len < 1)
+		return 0;
+
+	wpa_printf(MSG_DEBUG,
+		   "NAN: Parsing Cipher Suite Information attribute (len=%u)",
+		   csia_len);
+
+	cs_info = (struct nan_cipher_suite_info *)csia;
+
+	if (capabilities)
+		*capabilities = cs_info->capab;
+
+	pos = cs_info->cs;
+	end = csia + csia_len;
+
+	/* Parse cipher suite list. Each entry is 2 bytes (csid + publish_id) */
+	while (end - pos >= 2 && cs_count < max_cipher_suites) {
+		u8 csid = *pos;
+		u8 publish_id = pos[1];
+
+		pos += 2;
+
+		if (csid == NAN_CS_NONE || csid >= NAN_CS_MAX) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Invalid cipher suite ID %u for publish ID %u",
+				   csid, publish_id);
+			continue;
+		}
+
+		wpa_printf(MSG_DEBUG,
+			   "NAN: Cipher suite ID %u for publish ID %u",
+			   csid, publish_id);
+
+		/* Only include cipher suites for the matching publish ID */
+		if (publish_id == instance_id) {
+			cipher_suites[cs_count++] = csid;
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Added cipher suite %u for matching publish ID %u",
+				   csid, instance_id);
+		}
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "NAN: Parsed %zu cipher suites from CSIA for publish ID %u",
+		   cs_count, instance_id);
+
+	return cs_count;
+}
+
+
 static size_t nan_de_parse_scia(const u8 *buf, size_t len, u8 instance_id,
 				u8 *pmkid_list, size_t max_pmkids)
 {
@@ -1336,6 +1403,9 @@ static bool nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
 	/* The SCIA can potentially contain a PMKID for each cipher suite */
 	u8 pmkid_list[(NAN_CS_MAX - 1) * PMKID_LEN];
 	size_t pmkid_count = 0;
+	/* Cipher suites from CSIA */
+	u8 cipher_suites[NAN_CS_MAX - 1];
+	size_t cipher_suite_count = 0;
 
 	if (!nan_de_filter_match(srv, matching_filter, matching_filter_len))
 		return false;
@@ -1376,6 +1446,14 @@ static bool nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
 	}
 
 send_event:
+	/* Parse Cipher Suite Information Attribute for cipher suites */
+	if (buf && buf_len > 0) {
+		cipher_suite_count =
+			nan_de_parse_csia(buf, buf_len, instance_id,
+					  cipher_suites,
+					  ARRAY_SIZE(cipher_suites), NULL);
+	}
+
 	/* Parse Security Context Information attribute for PMKIDs */
 	if (buf && buf_len > 0) {
 		pmkid_count = nan_de_parse_scia(buf, buf_len, instance_id,
@@ -1391,7 +1469,9 @@ send_event:
 			sdea_control & NAN_SDEA_CTRL_FSD_REQ,
 			sdea_control & NAN_SDEA_CTRL_FSD_GAS,
 			pmkid_count > 0 ? pmkid_list : NULL,
-			pmkid_count);
+			pmkid_count,
+			cipher_suite_count > 0 ? cipher_suites : NULL,
+			cipher_suite_count);
 
 	return true;
 }
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index de7f08e7ea..b9801c2536 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -38,7 +38,9 @@ struct nan_callbacks {
 				 const u8 *ssi, size_t ssi_len,
 				 int peer_publish_id,
 				 const u8 *peer_addr, bool fsd, bool fsd_gas,
-				 const u8 *pmkid_list, size_t pmkid_count);
+				 const u8 *pmkid_list, size_t pmkid_count,
+				 const u8 *cipher_suite,
+				 size_t n_cipher_suite);
 
 	void (*replied)(void *ctx, int publish_id, const u8 *peer_addr,
 			int peer_subscribe_id,
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index e33a41cef3..495cae0e2c 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -3139,7 +3139,9 @@ wpas_nan_de_discovery_result(void *ctx, int subscribe_id,
 			     enum nan_service_protocol_type srv_proto_type,
 			     const u8 *ssi, size_t ssi_len, int peer_publish_id,
 			     const u8 *peer_addr, bool fsd, bool fsd_gas,
-			     const u8 *pmkid_list, size_t pmkid_count)
+			     const u8 *pmkid_list, size_t pmkid_count,
+			     const u8 *cipher_suite,
+			     size_t n_cipher_suite)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 
-- 
2.53.0




More information about the Hostap mailing list