From 6f80014b1060461f19a9b050102acc6eb80ee3bf Mon Sep 17 00:00:00 2001 From: Vinay Gannevaram Date: Fri, 7 Oct 2022 19:36:35 +0530 Subject: [PATCH] PASN: Allow custom PMKID in Authentication frames for Wi-Fi Aware Wi-Fi Aware R4 specification introduces a custom PMKID derived from Nonce and TAG. This custom PMKID is included in PASN Authentication frames during pairing verification. So, allow use of a custom PMKID in PASN frames and validate it using a function handler. Wi-Fi Aware component that uses libpasn.so should take care of validating the custom PMKID. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11.c | 22 ++++++++++++++++++++-- src/pasn/pasn_common.h | 12 ++++++++++++ wpa_supplicant/pasn_supplicant.c | 22 ++++++++++++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 14e4a4eab..810fc9ebd 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3088,7 +3088,9 @@ static int handle_auth_pasn_resp(struct wpas_pasn *pasn, const u8 *own_addr, if (status != WLAN_STATUS_SUCCESS) goto done; - if (pmksa) { + if (pmksa && pasn->custom_pmkid_valid) + pmkid = pasn->custom_pmkid; + else if (pmksa) { pmkid = pmksa->pmkid; #ifdef CONFIG_SAE } else if (pasn->akmp == WPA_KEY_MGMT_SAE) { @@ -3525,9 +3527,25 @@ static int handle_auth_pasn_1(struct wpas_pasn *pasn, wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry"); if (pasn->pmksa) { + const u8 *pmkid = NULL; + + if (pasn->custom_pmkid_valid) { + ret = pasn->validate_custom_pmkid( + pasn->cb_ctx, peer_addr, + rsn_data.pmkid); + if (ret) { + wpa_printf(MSG_DEBUG, + "PASN: Failed custom PMKID validation"); + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto send_resp; + } + } else { + pmkid = rsn_data.pmkid; + } + pmksa = pmksa_cache_auth_get(pasn->pmksa, peer_addr, - rsn_data.pmkid); + pmkid); if (pmksa) { cached_pmk = pmksa->pmk; cached_pmk_len = pmksa->pmk_len; diff --git a/src/pasn/pasn_common.h b/src/pasn/pasn_common.h index 24e3b5a99..f95df2b1b 100644 --- a/src/pasn/pasn_common.h +++ b/src/pasn/pasn_common.h @@ -112,6 +112,9 @@ struct wpas_pasn { u16 comeback_idx; u16 *comeback_pending_idx; + bool custom_pmkid_valid; + u8 custom_pmkid[PMKID_LEN]; + /** * send_mgmt - Function handler to transmit a Management frame * @ctx: Callback context from cb_ctx @@ -123,6 +126,15 @@ struct wpas_pasn { */ int (*send_mgmt)(void *ctx, const u8 *data, size_t data_len, int noack, unsigned int freq, unsigned int wait); + /** + * validate_custom_pmkid - Handler to validate vendor specific PMKID + * @ctx: Callback context from cb_ctx + * @addr : MAC address of the peer + * @pmkid: Custom PMKID + * Returns: 0 on success (valid PMKID), -1 on failure + */ + int (*validate_custom_pmkid)(void *ctx, const u8 *addr, + const u8 *pmkid); }; #endif /* CONFIG_PASN */ diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c index 2650fd31f..353e4ae9d 100644 --- a/wpa_supplicant/pasn_supplicant.c +++ b/wpa_supplicant/pasn_supplicant.c @@ -966,7 +966,9 @@ static struct wpabuf * wpas_pasn_build_auth_1(struct wpas_pasn *pasn, pmksa = pmksa_cache_get(pasn->pmksa, pasn->bssid, NULL, NULL, pasn->akmp); - if (pmksa) + if (pmksa && pasn->custom_pmkid_valid) + pmkid = pasn->custom_pmkid; + else if (pmksa) pmkid = pmksa->pmkid; /* @@ -1147,6 +1149,7 @@ static void wpa_pasn_reset(struct wpas_pasn *pasn) pasn->rsn_ie = NULL; pasn->rsn_ie_len = 0; pasn->rsnxe_ie = NULL; + pasn->custom_pmkid_valid = false; } @@ -1195,10 +1198,25 @@ static int wpas_pasn_set_pmk(struct wpas_pasn *pasn, } if (rsn_data->num_pmkid) { + int ret; struct rsn_pmksa_cache_entry *pmksa; + const u8 *pmkid = NULL; + + if (pasn->custom_pmkid_valid) { + ret = pasn->validate_custom_pmkid(pasn->cb_ctx, + pasn->bssid, + rsn_data->pmkid); + if (ret) { + wpa_printf(MSG_DEBUG, + "PASN: Failed custom PMKID validation"); + return -1; + } + } else { + pmkid = rsn_data->pmkid; + } pmksa = pmksa_cache_get(pasn->pmksa, pasn->bssid, - rsn_data->pmkid, NULL, pasn->akmp); + pmkid, NULL, pasn->akmp); if (pmksa) { wpa_printf(MSG_DEBUG, "PASN: Using PMKSA");