[RFC PATCH 17/34] Set password/PMK based on auth mode and configure rsnxe
Peddolla Harshavardhan Reddy
peddolla at qti.qualcomm.com
Thu May 15 00:17:40 PDT 2025
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla at qti.qualcomm.com>
---
src/common/proximity_ranging.c | 142 ++++++++++++++++++++++++++++++++-
src/common/proximity_ranging.h | 4 +
2 files changed, 143 insertions(+), 3 deletions(-)
diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index 2bd7ee9fe..f136fe06f 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -98,6 +98,11 @@ struct pr_data * pr_init(const struct pr_config *cfg)
dl_list_init(&pr->devices);
dl_list_init(&pr->dev_iks);
+#ifdef CONFIG_PASN
+ pr->initiator_pmksa = pasn_initiator_pmksa_cache_init();
+ pr->responder_pmksa = pasn_responder_pmksa_cache_init();
+#endif /* CONFIG_PASN */
+
return pr;
}
@@ -122,6 +127,11 @@ void pr_deinit(struct pr_data *pr)
os_free(dev_ik);
}
+#ifdef CONFIG_PASN
+ pasn_initiator_pmksa_cache_deinit(pr->initiator_pmksa);
+ pasn_responder_pmksa_cache_deinit(pr->responder_pmksa);
+#endif /* CONFIG_PASN */
+
os_free(pr);
wpa_printf(MSG_DEBUG, "PR: Deinit done");
}
@@ -985,9 +995,81 @@ void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
#ifdef CONFIG_PASN
+
+
+static struct wpabuf * pr_pasn_generate_rsnxe(struct pr_data *pr, int akmp)
+{
+ u32 capab;
+ size_t flen = 0;
+ struct wpabuf *buf;
+
+ capab = BIT(WLAN_RSNX_CAPAB_KEK_IN_PASN);
+
+ if (wpa_key_mgmt_sae(akmp))
+ capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
+ if (pr->cfg->secure_he_ltf)
+ capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
+
+ while (capab >> flen * 8)
+ flen++;
+
+ buf = wpabuf_alloc(2 + flen);
+ if (!buf)
+ return NULL;
+
+ if (wpabuf_tailroom(buf) < 2 + flen) {
+ wpa_printf(MSG_ERROR, "wpabuf tail room too small");
+ wpabuf_free(buf);
+ return NULL;
+ }
+ capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
+
+ wpa_printf(MSG_ERROR, "RSNXE capabilities: %04x", capab);
+ wpabuf_put_u8(buf, WLAN_EID_RSNX);
+ wpabuf_put_u8(buf, flen);
+ while (flen--) {
+ wpabuf_put_u8(buf, (capab & 0xff));
+ capab = capab >> 8;
+ }
+ return buf;
+}
+
+
+/* SSID used for deriving SAE pt for PR security */
+#define PR_PASN_SSID "516F9A010000"
+
+static void pr_pasn_set_password(struct pasn_data *pasn, u8 pasn_type,
+ const char *passphrase)
+{
+ int pasn_groups[4] = { 0 };
+ size_t len;
+
+ if (!passphrase)
+ return;
+
+ len = os_strlen(passphrase);
+
+ if (pasn_type & 0xc && pasn_type & 0x3) {
+ pasn_groups[0] = 20;
+ pasn_groups[1] = 19;
+ } else if (pasn_type & 0xc) {
+ pasn_groups[0] = 20;
+ } else {
+ pasn_groups[0] = 19;
+ }
+ pasn->pt = sae_derive_pt(pasn_groups, (const u8 *) PR_PASN_SSID,
+ os_strlen(PR_PASN_SSID),
+ (const u8 *) passphrase, len, NULL);
+ /* Set passphrase for PASN responder to validate Auth 1 frame */
+ pasn->password = passphrase;
+}
+
+
static int pr_pasn_initialize(struct pr_data *pr, struct pr_device *dev,
- const u8 *addr, u8 auth_mode, int freq)
+ const u8 *addr, u8 auth_mode, int freq,
+ const u8 *pmkid)
{
+ struct wpabuf *rsnxe;
struct pasn_data *pasn;
if (!pr || !dev)
@@ -1006,8 +1088,10 @@ static int pr_pasn_initialize(struct pr_data *pr, struct pr_device *dev,
os_memcpy(pasn->peer_addr, addr, ETH_ALEN);
if (dev->pasn_role == PR_ROLE_PASN_INITIATOR) {
+ pasn->pmksa = pr->initiator_pmksa;
os_memcpy(pasn->bssid, pasn->peer_addr, ETH_ALEN);
} else {
+ pasn->pmksa = pr->responder_pmksa;
os_memcpy(pasn->bssid, pasn->own_addr, ETH_ALEN);
}
@@ -1034,7 +1118,41 @@ static int pr_pasn_initialize(struct pr_data *pr, struct pr_device *dev,
if (auth_mode == PR_PASN_AUTH_MODE_SAE) {
pasn->akmp = WPA_KEY_MGMT_SAE;
- } else if (auth_mode == PR_PASN_AUTH_MODE_PMK) {
+ if (dev->password_valid) {
+ pr_pasn_set_password(pasn, pr->cfg->pasn_type,
+ dev->password);
+ } else if (pr->cfg->global_password_valid) {
+ pr_pasn_set_password(pasn, pr->cfg->pasn_type,
+ pr->cfg->global_password);
+ } else {
+ wpa_printf(MSG_ERROR, "PASN init: Password not available");
+ return -1;
+ }
+#ifdef CONFIG_TESTING_OPTIONS
+ if (dev->pasn_role == PR_ROLE_PASN_INITIATOR)
+ pasn_initiator_pmksa_cache_flush(pr->initiator_pmksa);
+ else
+ pasn_responder_pmksa_cache_flush(pr->responder_pmksa);
+#endif /* CONFIG_TESTING_OPTIONS */
+ } else if (auth_mode == PR_PASN_AUTH_MODE_PMK && dev->pmk_valid) {
+ if (!dev->pmk_valid) {
+ wpa_printf(MSG_ERROR, "PASN init: PMK not available");
+ return -1;
+ }
+ if (dev->pasn_role == PR_ROLE_PASN_INITIATOR)
+ pasn_initiator_pmksa_cache_add(pr->initiator_pmksa,
+ pasn->own_addr,
+ pasn->peer_addr,
+ dev->pmk,
+ WPA_PASN_PMK_LEN,
+ pmkid);
+ else
+ pasn_responder_pmksa_cache_add(pr->responder_pmksa,
+ pasn->own_addr,
+ pasn->peer_addr,
+ dev->pmk,
+ WPA_PASN_PMK_LEN,
+ pmkid);
pasn->akmp = WPA_KEY_MGMT_SAE;
} else {
pasn->akmp = WPA_KEY_MGMT_PASN;
@@ -1043,6 +1161,18 @@ static int pr_pasn_initialize(struct pr_data *pr, struct pr_device *dev,
pasn->rsn_pairwise = pasn->cipher;
pasn->wpa_key_mgmt = pasn->akmp;
+ rsnxe = pr_pasn_generate_rsnxe(pr, pasn->akmp);
+ if (rsnxe) {
+ os_free(pasn->rsnxe_ie);
+ pasn->rsnxe_ie = os_memdup(wpabuf_head_u8(rsnxe),
+ wpabuf_len(rsnxe));
+ if (!pasn->rsnxe_ie) {
+ wpabuf_free(rsnxe);
+ return -1;
+ }
+ wpabuf_free(rsnxe);
+ }
+
pasn->cb_ctx = pr->cfg->cb_ctx;
pasn->send_mgmt = pr->cfg->pasn_send_mgmt;
pasn->freq = freq;
@@ -1057,6 +1187,8 @@ int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq,
int ret = 0;
struct pasn_data *pasn;
struct pr_device *dev;
+ struct wpabuf *extra_ies;
+ u8 pmkid[PMKID_LEN];
if (!addr) {
wpa_printf(MSG_DEBUG, "Peer address NULL");
@@ -1074,7 +1206,11 @@ int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq,
dev->pasn_role = PR_ROLE_PASN_INITIATOR;
- if (pr_pasn_initialize(pr, dev, addr, auth_mode, freq)) {
+ if (auth_mode == PR_PASN_AUTH_MODE_PMK && dev->pmk_valid) {
+ if (os_get_random(pmkid, PMKID_LEN) < 0)
+ return -1;
+ }
+ if (pr_pasn_initialize(pr, dev, addr, auth_mode, freq, pmkid)) {
wpa_printf(MSG_ERROR, "PR PASN: Initialize failed");
return -1;
}
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index 16ebaabd7..780df8033 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -361,6 +361,10 @@ struct pr_data {
struct dl_list devices;
struct dl_list dev_iks;
+
+ /* PMKSA cache for PASN-PMK authentication */
+ struct rsn_pmksa_cache *initiator_pmksa;
+ struct rsn_pmksa_cache *responder_pmksa;
};
--
2.34.1
More information about the Hostap
mailing list