diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 295376779..0becfac07 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1964,7 +1964,12 @@ struct wpa_bss_candidate_info { struct wpa_pmkid_params { const u8 *bssid; + const u8 *ssid; + size_t ssid_len; + const u8 *fils_cache_id; const u8 *pmkid; + const u8 *pmk; + size_t pmk_len; }; /** @@ -2153,7 +2158,9 @@ struct wpa_driver_ops { * Returns: 0 on success, -1 on failure * * This function is called when a new PMK is received, as a result of - * either normal authentication or RSN pre-authentication. + * either normal authentication or RSN pre-authentication. The PMKSA + * parameters are either a set of bssid, pmkid, and pmk; or a set of + * ssid, fils_cache_id, pmkid, and pmk. * * If the driver generates RSN IE, i.e., it does not use wpa_ie in * associate(), add_pmkid() can be used to add new PMKSA cache entries @@ -2171,7 +2178,8 @@ struct wpa_driver_ops { * Returns: 0 on success, -1 on failure * * This function is called when the supplicant drops a PMKSA cache - * entry for any reason. + * entry for any reason. The PMKSA parameters are either a set of + * bssid and pmkid; or a set of ssid, fils_cache_id, and pmkid. * * If the driver generates RSN IE, i.e., it does not use wpa_ie in * associate(), remove_pmkid() can be used to synchronize PMKSA caches diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 51d9b1a4e..6ecb810d6 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -7460,14 +7460,23 @@ static const char * nl80211_get_radio_name(void *priv) } -static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid, - const u8 *pmkid) +static int nl80211_pmkid(struct i802_bss *bss, int cmd, + struct wpa_pmkid_params *params) { struct nl_msg *msg; if (!(msg = nl80211_bss_msg(bss, 0, cmd)) || - (pmkid && nla_put(msg, NL80211_ATTR_PMKID, 16, pmkid)) || - (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))) { + (params->pmkid && + nla_put(msg, NL80211_ATTR_PMKID, 16, params->pmkid)) || + (params->bssid && + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid)) || + (params->ssid_len && + nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid)) || + (params->fils_cache_id && + nla_put(msg, NL80211_ATTR_FILS_CACHE_ID, 2, + params->fils_cache_id)) || + (params->pmk_len && + nla_put(msg, NL80211_ATTR_PMK, params->pmk_len, params->pmk))) { nlmsg_free(msg); return -ENOBUFS; } @@ -7479,28 +7488,49 @@ static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid, static int nl80211_add_pmkid(void *priv, struct wpa_pmkid_params *params) { struct i802_bss *bss = priv; - wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, - MAC2STR(params->bssid)); - return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, params->bssid, - params->pmkid); + + if (params->bssid) + wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, + MAC2STR(params->bssid)); + else if (params->fils_cache_id && params->ssid_len) { + wpa_printf(MSG_DEBUG, + "nl80211: Add PMKSA for cache id %02x%02x SSID %s", + params->fils_cache_id[0], params->fils_cache_id[1], + wpa_ssid_txt(params->ssid, params->ssid_len)); + } + + return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, params); } static int nl80211_remove_pmkid(void *priv, struct wpa_pmkid_params *params) { struct i802_bss *bss = priv; - wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR, - MAC2STR(params->bssid)); - return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, params->bssid, - params->pmkid); + + if (params->bssid) + wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR, + MAC2STR(params->bssid)); + else if (params->fils_cache_id && params->ssid_len) { + wpa_printf(MSG_DEBUG, + "nl80211: Delete PMKSA for cache id %02x%02x SSID %s", + params->fils_cache_id[0], params->fils_cache_id[1], + wpa_ssid_txt(params->ssid, params->ssid_len)); + } + + return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, params); } static int nl80211_flush_pmkid(void *priv) { struct i802_bss *bss = priv; + struct nl_msg *msg; + wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs"); - return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL); + msg = nl80211_bss_msg(bss, 0, NL80211_CMD_FLUSH_PMKSA); + if (!msg) + return -ENOBUFS; + return send_and_recv_msgs(bss->drv, msg, NULL, NULL); }