[PATCH 49/92] NAN: Add function for creating a list of PMKIDs for a given PMK

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


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

The derivation of the ND-PMKID from the PMK depends on the cipher
suite used, thus for a given PMK multiple PMKIDs may need to be
derived based on the supported cipher suites.
Add a function to create a list of the PMKIDs that correspond to
a given PMK based on a list of supported cipher suites.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 src/nan/nan_crypto.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
 src/nan/nan_i.h      |  8 +++++
 2 files changed, 77 insertions(+)

diff --git a/src/nan/nan_crypto.c b/src/nan/nan_crypto.c
index 31702f5e9e..c0aea20c90 100644
--- a/src/nan/nan_crypto.c
+++ b/src/nan/nan_crypto.c
@@ -672,3 +672,72 @@ struct wpabuf *nan_crypto_decrypt_key_data(const u8 *kek, size_t kek_len,
 
 	return decrypted;
 }
+
+
+/*
+ * nan_crypto_clear_pmkid_list - Clear and free all entries in a PMKID list
+ *
+ * @pmkid_list: List of PMKIDs to clear
+ *
+ * This function removes and frees all PMKID entries from the provided list.
+ */
+void nan_crypto_clear_pmkid_list(struct dl_list *pmkid_list)
+{
+	struct nan_de_pmkid *p, *n;
+
+	dl_list_for_each_safe(p, n, pmkid_list, struct nan_de_pmkid, list) {
+		dl_list_del(&p->list);
+		os_free(p);
+	}
+}
+
+
+/*
+ * nan_crypto_pmkid_list - Generate PMKIDs for multiple cipher suites
+ *
+ * @pmkid_list: List to append generated PMKIDs to
+ * @raddr: Responder MAC address
+ * @srv_id: Service ID (6 bytes)
+ * @cipher_suites: Array of cipher suite identifiers (0 terminated)
+ * @pmk: Pairwise Master Key to generate PMKIDs from
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function generates a PMKID for each cipher suite in the provided array
+ * and adds them to the pmkid_list.
+ */
+int nan_crypto_pmkid_list(struct dl_list *pmkid_list, const u8 *raddr,
+			  const u8 *srv_id, const int *cipher_suites,
+			  const u8 *pmk)
+{
+	size_t cs_num = int_array_len(cipher_suites);
+	size_t i;
+
+	if (!cs_num || !pmk)
+		return 0;
+
+	for (i = 0; i < cs_num; i++) {
+		struct nan_de_pmkid *p;
+		int ret;
+		u8 iaddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+		enum nan_cipher_suite_id csid =
+			(enum nan_cipher_suite_id)cipher_suites[i];
+
+		p = os_zalloc(sizeof(*p));
+		if (!p)
+			return -1;
+
+		ret = nan_crypto_calc_pmkid(pmk, iaddr, raddr, srv_id, csid,
+					    p->pmkid);
+		if (ret < 0) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Failed to derive PMKID for cipher suite %d",
+				   cipher_suites[i]);
+			nan_crypto_clear_pmkid_list(pmkid_list);
+			return ret;
+		}
+
+		dl_list_add(pmkid_list, &p->list);
+	}
+
+	return 0;
+}
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index eedf6c2389..9c6ff10cab 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -636,6 +636,10 @@ static inline u8 nan_get_next_ndp_id(struct nan_data *nan)
 	return nan->ndp_id_counter;
 }
 
+struct nan_de_pmkid {
+	struct dl_list list;
+	u8 pmkid[PMKID_LEN];
+};
 
 struct nan_peer * nan_get_peer(struct nan_data *nan, const u8 *addr);
 bool nan_is_naf(const struct ieee80211_mgmt *mgmt, size_t len);
@@ -746,6 +750,10 @@ struct wpabuf *nan_crypto_encrypt_key_data(const struct wpabuf *key_data,
 struct wpabuf *nan_crypto_decrypt_key_data(const u8 *kek, size_t kek_len,
 					   const u8 *encrypted_data,
 					   size_t encrypted_len);
+int nan_crypto_pmkid_list(struct dl_list *pmkid_list, const u8 *raddr,
+			  const u8 *srv_id, const int *cipher_suites_list,
+			  const u8 *pmk);
+void nan_crypto_clear_pmkid_list(struct dl_list *pmkid_list);
 
 
 void nan_sec_reset(struct nan_data *nan, struct nan_ndp_sec *ndp_sec);
-- 
2.53.0




More information about the Hostap mailing list