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) {
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;
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
*/
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 */
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;
/*
pasn->rsn_ie = NULL;
pasn->rsn_ie_len = 0;
pasn->rsnxe_ie = NULL;
+ pasn->custom_pmkid_valid = false;
}
}
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");