]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Accept another (Re)Association Request frame during an association
authorJouni Malinen <j@w1.fi>
Fri, 25 Aug 2017 13:24:18 +0000 (16:24 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 15 Oct 2017 23:03:47 +0000 (02:03 +0300)
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>
src/ap/hostapd.c
src/ap/ieee802_11.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h

index 990b42ca2f7355091584ec3d386e29809454a556..12911dfd46116bd3d42d52bdef59d0eadc5e34f9 100644 (file)
@@ -2961,6 +2961,9 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
        ieee802_1x_new_station(hapd, sta);
        if (reassoc) {
                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)))
                        wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
        } else
index 0578e78c5b782662c2ecdb664e83237559b3a66b..6740241e1a296908272fa3c93256f7d52a4cbea4 100644 (file)
@@ -2645,7 +2645,8 @@ static int add_associated_sta(struct hostapd_data *hapd,
         */
        if (!sta->added_unassoc &&
            (!(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);
                wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
                set = 0;
index 72b56226847e91f2c84fa4d7d375953384558582..922bfe72584d45861a331f97b67b2556ce5d61de 100644 (file)
@@ -2152,6 +2152,7 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
        if (res < 0)
                return res;
        sm->PTK_valid = TRUE;
+       sm->tk_already_set = FALSE;
 
 #ifdef CONFIG_IEEE80211R_AP
        if (fils_ft_len) {
@@ -2585,8 +2586,14 @@ int fils_set_tk(struct wpa_state_machine *sm)
        enum wpa_alg alg;
        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;
+       }
+       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);
        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");
                return -1;
        }
+       sm->tk_already_set = TRUE;
 
        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,
                             struct rsn_pmksa_cache_entry *entry)
 {
index 968df041789d89b5d26ae55eb0a0fd03638983e0..1fd2183b0d5237fdd4bb4f23da382f283b3007dc 100644 (file)
@@ -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_wpa_version(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,
                             struct rsn_pmksa_cache_entry *entry);
 struct rsn_pmksa_cache_entry *