]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT-SAE: Add RSNXE into FT MIC
authorJouni Malinen <jouni@codeaurora.org>
Fri, 18 Oct 2019 13:20:27 +0000 (16:20 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 18 Oct 2019 13:20:27 +0000 (16:20 +0300)
Protect RSNXE, if present, in FT Reassociation Request/Response frames.
This is needed for SAE H2E with FT.

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

index 771f6dd1296f7516c1fe50e80c06beafe38af7bc..a599be2257ae4056d15bcee85093e062fa97ea69 100644 (file)
@@ -2418,6 +2418,8 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
        u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL;
        u8 *fte_mic, *elem_count;
        size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0;
+       u8 rsnxe[10];
+       size_t rsnxe_len;
        int res;
        struct wpa_auth_config *conf;
        struct wpa_ft_ies parse;
@@ -2580,6 +2582,13 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
        if (ric_start == pos)
                ric_start = NULL;
 
+       res = wpa_write_rsnxe(&sm->wpa_auth->conf, rsnxe, sizeof(rsnxe));
+       if (res < 0)
+               return NULL;
+       rsnxe_len = res;
+       if (auth_alg == WLAN_AUTH_FT && rsnxe_len)
+               *elem_count += 1;
+
        if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
                kck = sm->PTK.kck2;
                kck_len = sm->PTK.kck2_len;
@@ -2592,6 +2601,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                       mdie, mdie_len, ftie, ftie_len,
                       rsnie, rsnie_len,
                       ric_start, ric_start ? pos - ric_start : 0,
+                      rsnxe_len ? rsnxe : NULL, rsnxe_len,
                       fte_mic) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
                return NULL;
@@ -3249,6 +3259,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
        count = 3;
        if (parse.ric)
                count += ieee802_11_ie_count(parse.ric, parse.ric_len);
+       if (parse.rsnxe)
+               count++;
        if (fte_elem_count != count) {
                wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
                           "Control: received %u expected %u",
@@ -3268,6 +3280,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
                       parse.ftie - 2, parse.ftie_len + 2,
                       parse.rsn - 2, parse.rsn_len + 2,
                       parse.ric, parse.ric_len,
+                      parse.rsnxe ? parse.rsnxe - 2 : NULL,
+                      parse.rsnxe ? parse.rsnxe_len + 2 : 0,
                       mic) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
@@ -3286,6 +3300,9 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
                            parse.ftie - 2, parse.ftie_len + 2);
                wpa_hexdump(MSG_MSGDUMP, "FT: RSN",
                            parse.rsn - 2, parse.rsn_len + 2);
+               wpa_hexdump(MSG_MSGDUMP, "FT: RSNXE",
+                           parse.rsnxe ? parse.rsnxe - 2 : NULL,
+                           parse.rsnxe ? parse.rsnxe_len + 2 : 0);
                return WLAN_STATUS_INVALID_FTIE;
        }
 
index 1f8f18e902c63d07a5db2dc4aac5cc529930b529..e0f3599ebe70869ca211962fc9d918be51534ec6 100644 (file)
@@ -750,10 +750,12 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
               const u8 *mdie, size_t mdie_len,
               const u8 *ftie, size_t ftie_len,
               const u8 *rsnie, size_t rsnie_len,
-              const u8 *ric, size_t ric_len, u8 *mic)
+              const u8 *ric, size_t ric_len,
+              const u8 *rsnxe, size_t rsnxe_len,
+              u8 *mic)
 {
-       const u8 *addr[9];
-       size_t len[9];
+       const u8 *addr[10];
+       size_t len[10];
        size_t i, num_elem = 0;
        u8 zero_mic[24];
        size_t mic_len, fte_fixed_len;
@@ -820,6 +822,12 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
                num_elem++;
        }
 
+       if (rsnxe) {
+               addr[num_elem] = rsnxe;
+               len[num_elem] = rsnxe_len;
+               num_elem++;
+       }
+
        for (i = 0; i < num_elem; i++)
                wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]);
 #ifdef CONFIG_SHA384
@@ -961,6 +969,13 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
                                update_use_sha384 = 0;
                        }
                        break;
+               case WLAN_EID_RSNX:
+                       wpa_hexdump(MSG_DEBUG, "FT: RSNXE", pos, len);
+                       if (len < 1)
+                               break;
+                       parse->rsnxe = pos;
+                       parse->rsnxe_len = len;
+                       break;
                case WLAN_EID_MOBILITY_DOMAIN:
                        wpa_hexdump(MSG_DEBUG, "FT: MDE", pos, len);
                        if (len < sizeof(struct rsn_mdie))
@@ -1043,6 +1058,8 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
                prot_ie_count--;
        if (parse->ftie)
                prot_ie_count--;
+       if (parse->rsnxe)
+               prot_ie_count--;
        if (prot_ie_count < 0) {
                wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
                           "the protected IE count");
index c7711f16853743b400a6d236f01199521fd7ef3f..beb1ecd5e4fd1286c396b82334bee847941f6e78 100644 (file)
@@ -364,7 +364,9 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
               const u8 *mdie, size_t mdie_len,
               const u8 *ftie, size_t ftie_len,
               const u8 *rsnie, size_t rsnie_len,
-              const u8 *ric, size_t ric_len, u8 *mic);
+              const u8 *ric, size_t ric_len,
+              const u8 *rsnxe, size_t rsnxe_len,
+              u8 *mic);
 int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
                      const u8 *ssid, size_t ssid_len,
                      const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
@@ -461,6 +463,8 @@ struct wpa_ft_ies {
        size_t ric_len;
        int key_mgmt;
        int pairwise_cipher;
+       const u8 *rsnxe;
+       size_t rsnxe_len;
 };
 
 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
index a6da3471a0b6fb27bc4f1427b1ffde57817548cc..2b8b41fa5852ed008069b9e1207e43f67589f234 100644 (file)
@@ -18,6 +18,7 @@
 #include "drivers/driver.h"
 #include "wpa.h"
 #include "wpa_i.h"
+#include "wpa_ie.h"
 #include "pmksa_cache.h"
 
 #ifdef CONFIG_IEEE80211R
@@ -171,6 +172,9 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
        struct rsn_ie_hdr *rsnie;
        u16 capab;
        int mdie_len;
+       u8 rsnxe[10];
+       size_t rsnxe_len;
+       int res;
 
        sm->ft_completed = 0;
        sm->ft_reassoc_completed = 0;
@@ -359,6 +363,13 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
                pos += ric_ies_len;
        }
 
+       res = wpa_gen_rsnxe(sm, rsnxe, sizeof(rsnxe));
+       if (res < 0) {
+               os_free(buf);
+               return NULL;
+       }
+       rsnxe_len = res;
+
        if (kck) {
                /*
                 * IEEE Std 802.11r-2008, 11A.8.4
@@ -370,14 +381,18 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
                 * MDIE
                 * FTIE (with MIC field set to 0)
                 * RIC-Request (if present)
+                * RSNXE (if present)
                 */
                /* Information element count */
                *elem_count = 3 + ieee802_11_ie_count(ric_ies, ric_ies_len);
+               if (rsnxe_len)
+                       *elem_count += 1;
                if (wpa_ft_mic(kck, kck_len, sm->own_addr, target_ap, 5,
                               ((u8 *) mdie) - 2, 2 + sizeof(*mdie),
                               ftie_pos, 2 + *ftie_len,
                               (u8 *) rsnie, 2 + rsnie->len, ric_ies,
-                              ric_ies_len, fte_mic) < 0) {
+                              ric_ies_len, rsnxe_len ? rsnxe : NULL, rsnxe_len,
+                              fte_mic) < 0) {
                        wpa_printf(MSG_INFO, "FT: Failed to calculate MIC");
                        os_free(buf);
                        return NULL;
@@ -961,6 +976,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
        count = 3;
        if (parse.ric)
                count += ieee802_11_ie_count(parse.ric, parse.ric_len);
+       if (parse.rsnxe)
+               count++;
        if (fte_elem_count != count) {
                wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
                           "Control: received %u expected %u",
@@ -981,6 +998,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
                       parse.ftie - 2, parse.ftie_len + 2,
                       parse.rsn - 2, parse.rsn_len + 2,
                       parse.ric, parse.ric_len,
+                      parse.rsnxe ? parse.rsnxe - 2 : NULL,
+                      parse.rsnxe ? parse.rsnxe_len + 2 : 0,
                       mic) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
                return -1;