]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: Set the new RSNXE Used subfield in FT reassociation
authorJouni Malinen <jouni@codeaurora.org>
Fri, 20 Mar 2020 19:23:48 +0000 (21:23 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 20 Mar 2020 19:23:48 +0000 (21:23 +0200)
This is a workaround needed to keep FT protocol backwards compatible for
the cases where either the AP or the STA uses RSNXE, but the other one
does not. This commit adds setting of the new field to 1 in
Reassociation Request/Response frame during FT protocol when the STA/AP
uses RSNXE in other frames. This mechanism is described in 20/332r3.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/wpa_auth.c
src/ap/wpa_auth_ft.c
src/ap/wpa_auth_i.h
src/rsn_supp/wpa_ft.c

index ab20705f0f3b0bb71723d25844944c5f9844043d..64fc09ca66d0a9a81bace772348ca06b49cb6838 100644 (file)
@@ -3422,7 +3422,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
                                             conf->r0_key_holder_len,
                                             NULL, NULL, pos,
                                             kde + kde_len - pos,
-                                            NULL, 0);
+                                            NULL, 0, 0);
                }
                if (res < 0) {
                        wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
@@ -5087,7 +5087,7 @@ int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
 
        return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder,
                              conf->r0_key_holder_len,
-                             NULL, NULL, buf, len, NULL, 0);
+                             NULL, NULL, buf, len, NULL, 0, 0);
 }
 #endif /* CONFIG_IEEE80211R_AP */
 
@@ -5289,7 +5289,7 @@ int wpa_auth_resend_m3(struct wpa_state_machine *sm,
                                             conf->r0_key_holder_len,
                                             NULL, NULL, pos,
                                             kde + kde_len - pos,
-                                            NULL, 0);
+                                            NULL, 0, 0);
                }
                if (res < 0) {
                        wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
index 1795848e1ffd2f75798058e27f5ccde0e68fddd8..c8751fddb76fac71c9da4bf5db40b6178251a619 100644 (file)
@@ -808,7 +808,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
                   const u8 *r0kh_id, size_t r0kh_id_len,
                   const u8 *anonce, const u8 *snonce,
                   u8 *buf, size_t len, const u8 *subelem,
-                  size_t subelem_len)
+                  size_t subelem_len, int rsnxe_used)
 {
        u8 *pos = buf, *ielen;
        size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) :
@@ -826,7 +826,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
 
                os_memset(hdr, 0, sizeof(*hdr));
                pos += sizeof(*hdr);
-               WPA_PUT_LE16(hdr->mic_control, 0);
+               WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
                if (anonce)
                        os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
                if (snonce)
@@ -836,7 +836,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
 
                os_memset(hdr, 0, sizeof(*hdr));
                pos += sizeof(*hdr);
-               WPA_PUT_LE16(hdr->mic_control, 0);
+               WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
                if (anonce)
                        os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
                if (snonce)
@@ -2470,6 +2470,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
        size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0;
        u8 rsnxe_buf[10], *rsnxe = rsnxe_buf;
        size_t rsnxe_len;
+       int rsnxe_used;
        int res;
        struct wpa_auth_config *conf;
        struct wpa_ft_ies parse;
@@ -2643,9 +2644,11 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                anonce = NULL;
                snonce = NULL;
        }
+       rsnxe_used = (auth_alg == WLAN_AUTH_FT) &&
+               (conf->sae_pwe == 1 || conf->sae_pwe == 2);
        res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
                             anonce, snonce, pos, end - pos,
-                            subelem, subelem_len);
+                            subelem, subelem_len, rsnxe_used);
        os_free(subelem);
        if (res < 0)
                return NULL;
@@ -3166,7 +3169,8 @@ pmk_r1_derived:
        pos += ret;
 
        ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len,
-                            sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0);
+                            sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0,
+                            0);
        if (ret < 0)
                goto fail;
        pos += ret;
index c2b22eba13a7e3157d416bfc1decf0e30ddb8bbb..5d7b96c6f194efbe3f2e1159ab9b836959acd83a 100644 (file)
@@ -294,7 +294,7 @@ int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
                   const u8 *r0kh_id, size_t r0kh_id_len,
                   const u8 *anonce, const u8 *snonce,
                   u8 *buf, size_t len, const u8 *subelem,
-                  size_t subelem_len);
+                  size_t subelem_len, int rsnxe_used);
 int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk);
 struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
index baa185ffe7f2bf35fe674fe0fa79639031e95191..bb3a8b5bbf0d15bdbacc54c6e3e5ab4c9849ac6f 100644 (file)
@@ -181,6 +181,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
        int mdie_len;
        u8 rsnxe[10];
        size_t rsnxe_len;
+       int rsnxe_used;
        int res;
 
        sm->ft_completed = 0;
@@ -309,10 +310,13 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
        ftie_pos = pos;
        *pos++ = WLAN_EID_FAST_BSS_TRANSITION;
        ftie_len = pos++;
+       rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) && anonce &&
+               (sm->sae_pwe == 1 || sm->sae_pwe == 2);
        if (wpa_key_mgmt_sha384(sm->key_mgmt)) {
                struct rsn_ftie_sha384 *ftie;
 
                ftie = (struct rsn_ftie_sha384 *) pos;
+               ftie->mic_control[0] = !!rsnxe_used;
                fte_mic = ftie->mic;
                elem_count = &ftie->mic_control[1];
                pos += sizeof(*ftie);
@@ -323,6 +327,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
                struct rsn_ftie *ftie;
 
                ftie = (struct rsn_ftie *) pos;
+               ftie->mic_control[0] = !!rsnxe_used;
                fte_mic = ftie->mic;
                elem_count = &ftie->mic_control[1];
                pos += sizeof(*ftie);