[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