From: Ilan Peer <ilan.peer@xxxxxxxxx> When a non-AP MLD station associates with an AP MLD and the association is a multi-link association, the PMKSA that is created as part of the connection establishment is also relevant for the other links included in the association. Thus, update the PMKSA cache of the other BSSs (that are part of the MLD connection) with the same PMKSA information. This is useful for cases, where after initial connection establishment, the station disconnect and connects again, but instead of using the original link for the connection it uses a different link. Signed-off-by: Ilan Peer <ilan.peer@xxxxxxxxx> --- src/ap/dpp_hostapd.c | 14 +++---- src/ap/hostapd.c | 3 +- src/ap/ieee802_11.c | 40 ++++++++++++------- src/ap/ieee802_11.h | 4 ++ src/ap/ieee802_11_shared.c | 82 ++++++++++++++++++++++++++++++++++++++ src/ap/wnm_ap.c | 3 +- src/ap/wpa_auth.c | 18 --------- src/ap/wpa_auth.h | 3 -- 8 files changed, 122 insertions(+), 45 deletions(-) diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 1fee2d6a8a..8fd72b120c 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -23,7 +23,7 @@ #include "wpa_auth.h" #include "beacon.h" #include "dpp_hostapd.h" - +#include "ieee802_11.h" static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx); static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx, @@ -2133,9 +2133,9 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, else expiration = 0; - if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, - intro.pmkid, expiration, - WPA_KEY_MGMT_DPP, pkhash) < 0) { + if (hostapd_pmksa_add(hapd, src, intro.pmk, intro.pmk_len, + intro.pmkid, expiration, + WPA_KEY_MGMT_DPP, pkhash) < 0) { wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry"); goto done; } @@ -2907,9 +2907,9 @@ hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data *hapd, const u8 *src, else expiration = 0; - if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, - intro.pmkid, expiration, - WPA_KEY_MGMT_DPP, pkhash) < 0) { + if (hostapd_pmksa_add(hapd, src, intro.pmk, intro.pmk_len, + intro.pmkid, expiration, + WPA_KEY_MGMT_DPP, pkhash) < 0) { wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry"); goto done; } diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index b6031014d4..225d50f09a 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1129,7 +1129,8 @@ hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr) wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR " - disconnecting", MAC2STR(sta->addr)); - wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr); + + hostapd_pmksa_remove(hapd, sta->addr); hostapd_drv_sta_deauth(hapd, sta->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index ad85f216f2..4001edf9fc 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -894,6 +894,8 @@ static void sae_sme_send_external_auth_status(struct hostapd_data *hapd, void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta) { + int akmp; + #ifndef CONFIG_NO_VLAN struct vlan_description vlan_desc; @@ -931,9 +933,18 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta) crypto_bignum_deinit(sta->sae->peer_commit_scalar_accepted, 0); sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar; sta->sae->peer_commit_scalar = NULL; - wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr, - sta->sae->pmk, sta->sae->pmk_len, - sta->sae->pmkid, sta->sae->akmp); + + akmp = sta->sae->akmp; + if (!akmp) { + wpa_printf(MSG_DEBUG, "SAE: set AKMP=SAE for STA " MACSTR, + MAC2STR(sta->addr)); + akmp = WPA_KEY_MGMT_SAE; + } + + hostapd_pmksa_add(hapd, sta->addr, sta->sae->pmk, + sta->sae->pmk_len, sta->sae->pmkid, 0, + akmp, NULL); + sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS); } @@ -1092,7 +1103,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta, wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR ") doing reauthentication", MAC2STR(sta->addr)); - wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr); + hostapd_pmksa_remove(hapd, sta->addr); ap_free_sta(hapd, sta); *sta_removed = 1; } else if (auth_transaction == 1) { @@ -1309,7 +1320,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, if (sta->mesh_sae_pmksa_caching) { wpa_printf(MSG_DEBUG, "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication"); - wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr); + hostapd_pmksa_remove(hapd, sta->addr); sta->mesh_sae_pmksa_caching = 0; } @@ -2143,14 +2154,13 @@ prepare_auth_resp_fils(struct hostapd_data *hapd, sta->fils_erp_pmkid_set = 0; wpa_auth_add_fils_pmk_pmkid(sta->wpa_sm, pmk, pmk_len, sta->fils_erp_pmkid); - if (!hapd->conf->disable_pmksa_caching && - wpa_auth_pmksa_add2( - hapd->wpa_auth, sta->addr, - pmk, pmk_len, - sta->fils_erp_pmkid, - session_timeout, - wpa_auth_sta_key_mgmt(sta->wpa_sm), - NULL) < 0) { + + if (hostapd_pmksa_add(hapd, sta->addr, + pmk, pmk_len, + sta->fils_erp_pmkid, + session_timeout, + wpa_auth_sta_key_mgmt(sta->wpa_sm), + NULL) < 0) { wpa_printf(MSG_ERROR, "FILS: Failed to add PMKSA cache entry based on ERP"); } @@ -3655,9 +3665,9 @@ static u16 owe_process_assoc_req(struct hostapd_data *hapd, wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sta->owe_pmk, sta->owe_pmk_len); wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN); - wpa_auth_pmksa_add2(hapd->wpa_auth, sta->addr, sta->owe_pmk, - sta->owe_pmk_len, pmkid, 0, WPA_KEY_MGMT_OWE, NULL); + hostapd_pmksa_add(hapd, sta->addr, sta->owe_pmk, + sta->owe_pmk_len, pmkid, 0, WPA_KEY_MGMT_OWE, NULL); return WLAN_STATUS_SUCCESS; } diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 3f89874e23..e07f83eeb3 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -256,4 +256,8 @@ const char * sae_get_password(struct hostapd_data *hapd, struct sae_password_entry **pw_entry, struct sae_pt **s_pt, const struct sae_pk **s_pk); +int hostapd_pmksa_add(struct hostapd_data *hapd, const u8 *addr, + const u8 *pmk, size_t pmk_len, const u8 *pmkid, + int session_timeout, int akmp, const u8 *dpp_pkhash); +void hostapd_pmksa_remove(struct hostapd_data *hapd, const u8 *addr); #endif /* IEEE802_11_H */ diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index e7e5019de2..8548e6e7fe 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -1148,3 +1148,85 @@ u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, return WLAN_STATUS_SUCCESS; } + + +static void hostapd_mld_pmksa_add(struct hostapd_data *hapd, const u8 *addr, + const u8 *pmk, size_t pmk_len, + const u8 *pmkid, + int session_timeout, int akmp, + const u8 *dpp_pkhash) +{ +#ifdef CONFIG_IEEE80211BE + u32 i; + + for (i = 0; i < hapd->iface->interfaces->count; i++) { + struct hostapd_iface *iface = hapd->iface->interfaces->iface[i]; + + if (hapd->iface == iface) + continue; + + if (!iface->bss[0]->conf->mld_ap || + hapd->conf->mld_id != iface->bss[0]->conf->mld_id || + !iface->bss[0]->wpa_auth) + continue; + + wpa_printf(MSG_INFO, "MLD: add PMKSA to link=%u, addr=" MACSTR, + iface->bss[0]->mld_link_id, MAC2STR(addr)); + + wpa_auth_pmksa_add2(iface->bss[0]->wpa_auth, addr, + pmk, pmk_len, pmkid, session_timeout, akmp, + dpp_pkhash); + } +#endif /* CONFIG_IEEE80211BE */ +} + + +int hostapd_pmksa_add(struct hostapd_data *hapd, const u8 *addr, + const u8 *pmk, size_t pmk_len, const u8 *pmkid, + int session_timeout, int akmp, const u8 *dpp_pkhash) +{ + int ret; + + ret = wpa_auth_pmksa_add2(hapd->wpa_auth, addr, pmk, pmk_len, + pmkid, session_timeout, akmp, dpp_pkhash); + + if (ret < 0) + return ret; + + hostapd_mld_pmksa_add(hapd, addr, pmk, pmk_len, pmkid, session_timeout, + akmp, dpp_pkhash); + + return 0; +} + + +static void hostapd_mld_pmksa_remove(struct hostapd_data *hapd, const u8 *addr) +{ +#ifdef CONFIG_IEEE80211BE + u32 i; + + for (i = 0; i < hapd->iface->interfaces->count; i++) { + struct hostapd_iface *iface = hapd->iface->interfaces->iface[i]; + + if (hapd->iface == iface) + continue; + + if (!iface->bss[0]->conf->mld_ap || + hapd->conf->mld_id != iface->bss[0]->conf->mld_id || + !iface->bss[0]->wpa_auth) + continue; + + wpa_printf(MSG_INFO, "MLD: add PMKSA to link=%u", + iface->bss[0]->mld_link_id); + + wpa_auth_pmksa_remove(iface->bss[0]->wpa_auth, addr); + } +#endif /* CONFIG_IEEE80211BE */ +} + + +void hostapd_pmksa_remove(struct hostapd_data *hapd, const u8 *addr) +{ + wpa_auth_pmksa_remove(hapd->wpa_auth, addr); + hostapd_mld_pmksa_remove(hapd, addr); +} diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c index 153ee40334..a3d94fea00 100644 --- a/src/ap/wnm_ap.c +++ b/src/ap/wnm_ap.c @@ -20,6 +20,7 @@ #include "ap/wpa_auth.h" #include "mbo_ap.h" #include "wnm_ap.h" +#include "ieee802_11.h" #define MAX_TFS_IE_LEN 1024 @@ -862,7 +863,7 @@ static void set_disassoc_timer(struct hostapd_data *hapd, struct sta_info *sta, * full authentication with the authentication server (which may * decide to reject the connection), */ - wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr); + hostapd_pmksa_remove(hapd, sta->addr); beacon_int = hapd->iconf->beacon_int; if (beacon_int < 1) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index a1223265ed..2057cf393d 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -5653,24 +5653,6 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, } -int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk, size_t pmk_len, const u8 *pmkid, - int akmp) -{ - if (wpa_auth->conf.disable_pmksa_caching) - return -1; - - wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE", pmk, pmk_len); - if (!akmp) - akmp = WPA_KEY_MGMT_SAE; - if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid, - NULL, 0, wpa_auth->addr, addr, 0, NULL, akmp)) - return 0; - - return -1; -} - - void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid) { os_memcpy(sm->pmkid, pmkid, PMKID_LEN); diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 841897bf82..87894c38b4 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -471,9 +471,6 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, const u8 *pmk, size_t len, const u8 *sta_addr, int session_timeout, struct eapol_state_machine *eapol); -int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk, size_t pmk_len, const u8 *pmkid, - int akmp); void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid); int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr, const u8 *pmk, size_t pmk_len, const u8 *pmkid, -- 2.38.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap