FILS: Accept another (Re)Association Request frame during an association
The previous implementation ended up starting a new EAPOL-Key 4-way handshake if the STA were to attempt to perform another association. This resulted in immediate disconnection since the PTK was not ready for configuring FILS TK at the point when EAPOL-Key msg 1/4 is sent out. This is better than alloing the association to continue with the same TK reconfigured, but not really ideal. Address this potential sequence by not starting a new 4-way handshake on the additional association attempt. Instead, allow the association to complete, but do so without reconfiguring the TK to avoid potential issues with PN reuse with the same TK. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
6db556b21d
commit
2f1357fb62
4 changed files with 23 additions and 2 deletions
|
@ -2961,6 +2961,9 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
ieee802_1x_new_station(hapd, sta);
|
ieee802_1x_new_station(hapd, sta);
|
||||||
if (reassoc) {
|
if (reassoc) {
|
||||||
if (sta->auth_alg != WLAN_AUTH_FT &&
|
if (sta->auth_alg != WLAN_AUTH_FT &&
|
||||||
|
sta->auth_alg != WLAN_AUTH_FILS_SK &&
|
||||||
|
sta->auth_alg != WLAN_AUTH_FILS_SK_PFS &&
|
||||||
|
sta->auth_alg != WLAN_AUTH_FILS_PK &&
|
||||||
!(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
|
!(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
|
||||||
wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
|
wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -2645,7 +2645,8 @@ static int add_associated_sta(struct hostapd_data *hapd,
|
||||||
*/
|
*/
|
||||||
if (!sta->added_unassoc &&
|
if (!sta->added_unassoc &&
|
||||||
(!(sta->flags & WLAN_STA_AUTHORIZED) ||
|
(!(sta->flags & WLAN_STA_AUTHORIZED) ||
|
||||||
!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm))) {
|
(!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) &&
|
||||||
|
!wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) {
|
||||||
hostapd_drv_sta_remove(hapd, sta->addr);
|
hostapd_drv_sta_remove(hapd, sta->addr);
|
||||||
wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
|
wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
|
||||||
set = 0;
|
set = 0;
|
||||||
|
|
|
@ -2152,6 +2152,7 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
sm->PTK_valid = TRUE;
|
sm->PTK_valid = TRUE;
|
||||||
|
sm->tk_already_set = FALSE;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R_AP
|
#ifdef CONFIG_IEEE80211R_AP
|
||||||
if (fils_ft_len) {
|
if (fils_ft_len) {
|
||||||
|
@ -2585,8 +2586,14 @@ int fils_set_tk(struct wpa_state_machine *sm)
|
||||||
enum wpa_alg alg;
|
enum wpa_alg alg;
|
||||||
int klen;
|
int klen;
|
||||||
|
|
||||||
if (!sm || !sm->PTK_valid)
|
if (!sm || !sm->PTK_valid) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FILS: No valid PTK available to set TK");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
if (sm->tk_already_set) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FILS: TK already set to the driver");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
alg = wpa_cipher_to_alg(sm->pairwise);
|
alg = wpa_cipher_to_alg(sm->pairwise);
|
||||||
klen = wpa_cipher_key_len(sm->pairwise);
|
klen = wpa_cipher_key_len(sm->pairwise);
|
||||||
|
@ -2597,6 +2604,7 @@ int fils_set_tk(struct wpa_state_machine *sm)
|
||||||
wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
|
wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
sm->tk_already_set = TRUE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3970,6 +3978,14 @@ int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wpa_auth_sta_fils_tk_already_set(struct wpa_state_machine *sm)
|
||||||
|
{
|
||||||
|
if (!sm || !wpa_key_mgmt_fils(sm->wpa_key_mgmt))
|
||||||
|
return 0;
|
||||||
|
return sm->tk_already_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
|
int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
|
||||||
struct rsn_pmksa_cache_entry *entry)
|
struct rsn_pmksa_cache_entry *entry)
|
||||||
{
|
{
|
||||||
|
|
|
@ -314,6 +314,7 @@ int wpa_auth_get_pairwise(struct wpa_state_machine *sm);
|
||||||
int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm);
|
int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm);
|
||||||
int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm);
|
int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm);
|
||||||
int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm);
|
int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm);
|
||||||
|
int wpa_auth_sta_fils_tk_already_set(struct wpa_state_machine *sm);
|
||||||
int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
|
int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
|
||||||
struct rsn_pmksa_cache_entry *entry);
|
struct rsn_pmksa_cache_entry *entry);
|
||||||
struct rsn_pmksa_cache_entry *
|
struct rsn_pmksa_cache_entry *
|
||||||
|
|
Loading…
Reference in a new issue