]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: FTE parsing for SHA384-based AKM
authorJouni Malinen <j@w1.fi>
Mon, 4 Jun 2018 12:16:54 +0000 (15:16 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 5 Jun 2018 16:29:53 +0000 (19:29 +0300)
The MIC field is now a variable length field, so make the FTE parser
aware of the two different field lengths.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/wpa_auth_ft.c
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa.c
src/rsn_supp/wpa_ft.c
wlantest/rx_mgmt.c

index d6735a124e12ba2cff33b11f16c1fb4d40778167..93ed12662effe09fa2549ce56da7cc963509de24 100644 (file)
@@ -2317,10 +2317,12 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
        u8 *anonce, *snonce;
        const u8 *kck;
        size_t kck_len;
+       int use_sha384;
 
        if (sm == NULL)
                return pos;
 
+       use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
        conf = &sm->wpa_auth->conf;
 
        if (!wpa_key_mgmt_ft(sm->wpa_key_mgmt))
@@ -2398,7 +2400,8 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
                _ftie->mic_control[1] = 3; /* Information element count */
 
        ric_start = pos;
-       if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse) == 0 && parse.ric) {
+       if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse, use_sha384) == 0
+           && parse.ric) {
                pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
                                         parse.ric_len);
                if (auth_alg == WLAN_AUTH_FT)
@@ -2683,7 +2686,6 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
                                   u8 **resp_ies, size_t *resp_ies_len)
 {
        struct rsn_mdie *mdie;
-       struct rsn_ftie *ftie;
        u8 pmk_r1[PMK_LEN_MAX], pmk_r1_name[WPA_PMK_NAME_LEN];
        u8 ptk_name[WPA_PMK_NAME_LEN];
        struct wpa_auth_config *conf;
@@ -2695,8 +2697,8 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
        struct vlan_description vlan;
        const u8 *identity, *radius_cui;
        size_t identity_len = 0, radius_cui_len = 0;
-       int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
-       size_t pmk_r1_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN;
+       int use_sha384;
+       size_t pmk_r1_len;
 
        *resp_ies = NULL;
        *resp_ies_len = 0;
@@ -2707,10 +2709,12 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
        wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs",
                    ies, ies_len);
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, -1)) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
        }
+       use_sha384 = wpa_key_mgmt_sha384(parse.key_mgmt);
+       pmk_r1_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN;
 
        mdie = (struct rsn_mdie *) parse.mdie;
        if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
@@ -2721,13 +2725,27 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
                return WLAN_STATUS_INVALID_MDIE;
        }
 
-       ftie = (struct rsn_ftie *) parse.ftie;
-       if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
-               wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
-               return WLAN_STATUS_INVALID_FTIE;
-       }
+       if (use_sha384) {
+               struct rsn_ftie_sha384 *ftie;
+
+               ftie = (struct rsn_ftie_sha384 *) parse.ftie;
+               if (!ftie || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return WLAN_STATUS_INVALID_FTIE;
+               }
 
-       os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
+               os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
+       } else {
+               struct rsn_ftie *ftie;
+
+               ftie = (struct rsn_ftie *) parse.ftie;
+               if (!ftie || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return WLAN_STATUS_INVALID_FTIE;
+               }
+
+               os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
+       }
 
        if (parse.r0kh_id == NULL) {
                wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID");
@@ -2917,19 +2935,23 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
 {
        struct wpa_ft_ies parse;
        struct rsn_mdie *mdie;
-       struct rsn_ftie *ftie;
        u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
        size_t mic_len = 16;
        unsigned int count;
        const u8 *kck;
        size_t kck_len;
+       int use_sha384;
+       const u8 *anonce, *snonce, *fte_mic;
+       u8 fte_elem_count;
 
        if (sm == NULL)
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
 
+       use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
+
        wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, use_sha384) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
        }
@@ -2960,25 +2982,47 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
                return WLAN_STATUS_INVALID_MDIE;
        }
 
-       ftie = (struct rsn_ftie *) parse.ftie;
-       if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
-               wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
-               return WLAN_STATUS_INVALID_FTIE;
+       if (use_sha384) {
+               struct rsn_ftie_sha384 *ftie;
+
+               ftie = (struct rsn_ftie_sha384 *) parse.ftie;
+               if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return WLAN_STATUS_INVALID_FTIE;
+               }
+
+               anonce = ftie->anonce;
+               snonce = ftie->snonce;
+               fte_elem_count = ftie->mic_control[1];
+               fte_mic = ftie->mic;
+       } else {
+               struct rsn_ftie *ftie;
+
+               ftie = (struct rsn_ftie *) parse.ftie;
+               if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return WLAN_STATUS_INVALID_FTIE;
+               }
+
+               anonce = ftie->anonce;
+               snonce = ftie->snonce;
+               fte_elem_count = ftie->mic_control[1];
+               fte_mic = ftie->mic;
        }
 
-       if (os_memcmp(ftie->snonce, sm->SNonce, WPA_NONCE_LEN) != 0) {
+       if (os_memcmp(snonce, sm->SNonce, WPA_NONCE_LEN) != 0) {
                wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
                wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
-                           ftie->snonce, WPA_NONCE_LEN);
+                           snonce, WPA_NONCE_LEN);
                wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
                            sm->SNonce, WPA_NONCE_LEN);
                return WLAN_STATUS_INVALID_FTIE;
        }
 
-       if (os_memcmp(ftie->anonce, sm->ANonce, WPA_NONCE_LEN) != 0) {
+       if (os_memcmp(anonce, sm->ANonce, WPA_NONCE_LEN) != 0) {
                wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE");
                wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
-                           ftie->anonce, WPA_NONCE_LEN);
+                           anonce, WPA_NONCE_LEN);
                wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
                            sm->ANonce, WPA_NONCE_LEN);
                return WLAN_STATUS_INVALID_FTIE;
@@ -3029,10 +3073,10 @@ 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 (ftie->mic_control[1] != count) {
+       if (fte_elem_count != count) {
                wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
                           "Control: received %u expected %u",
-                          ftie->mic_control[1], count);
+                          fte_elem_count, count);
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
        }
 
@@ -3053,12 +3097,12 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
        }
 
-       if (os_memcmp_const(mic, ftie->mic, mic_len) != 0) {
+       if (os_memcmp_const(mic, fte_mic, mic_len) != 0) {
                wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
                wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR,
                           MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr));
                wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
-                           ftie->mic, mic_len);
+                           fte_mic, mic_len);
                wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, mic_len);
                wpa_hexdump(MSG_MSGDUMP, "FT: MDIE",
                            parse.mdie - 2, parse.mdie_len + 2);
index 02f539511c91097feb02f3fdd6234557a6b42660..dc12dbf60edd1a1674009ff772857b4942cee47c 100644 (file)
@@ -828,23 +828,27 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
 
 
 static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
-                            struct wpa_ft_ies *parse)
+                            struct wpa_ft_ies *parse, int use_sha384)
 {
        const u8 *end, *pos;
 
        parse->ftie = ie;
        parse->ftie_len = ie_len;
 
-       pos = ie + sizeof(struct rsn_ftie);
+       pos = ie + (use_sha384 ? sizeof(struct rsn_ftie_sha384) :
+                   sizeof(struct rsn_ftie));
        end = ie + ie_len;
+       wpa_hexdump(MSG_DEBUG, "FT: Parse FTE subelements", pos, end - pos);
 
        while (end - pos >= 2) {
                u8 id, len;
 
                id = *pos++;
                len = *pos++;
-               if (len > end - pos)
+               if (len > end - pos) {
+                       wpa_printf(MSG_DEBUG, "FT: Truncated subelement");
                        break;
+               }
 
                switch (id) {
                case FTIE_SUBELEM_R1KH_ID:
@@ -876,6 +880,9 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
                        parse->igtk_len = len;
                        break;
 #endif /* CONFIG_IEEE80211W */
+               default:
+                       wpa_printf(MSG_DEBUG, "FT: Unknown subelem id %u", id);
+                       break;
                }
 
                pos += len;
@@ -886,13 +893,19 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
 
 
 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
-                    struct wpa_ft_ies *parse)
+                    struct wpa_ft_ies *parse, int use_sha384)
 {
        const u8 *end, *pos;
        struct wpa_ie_data data;
        int ret;
        const struct rsn_ftie *ftie;
        int prot_ie_count = 0;
+       int update_use_sha384 = 0;
+
+       if (use_sha384 < 0) {
+               use_sha384 = 0;
+               update_use_sha384 = 1;
+       }
 
        os_memset(parse, 0, sizeof(*parse));
        if (ies == NULL)
@@ -924,6 +937,11 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
                                parse->rsn_pmkid = data.pmkid;
                        parse->key_mgmt = data.key_mgmt;
                        parse->pairwise_cipher = data.pairwise_cipher;
+                       if (update_use_sha384) {
+                               use_sha384 =
+                                       wpa_key_mgmt_sha384(parse->key_mgmt);
+                               update_use_sha384 = 0;
+                       }
                        break;
                case WLAN_EID_MOBILITY_DOMAIN:
                        if (len < sizeof(struct rsn_mdie))
@@ -932,11 +950,24 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
                        parse->mdie_len = len;
                        break;
                case WLAN_EID_FAST_BSS_TRANSITION:
+                       if (use_sha384) {
+                               const struct rsn_ftie_sha384 *ftie_sha384;
+
+                               if (len < sizeof(*ftie_sha384))
+                                       return -1;
+                               ftie_sha384 =
+                                       (const struct rsn_ftie_sha384 *) pos;
+                               prot_ie_count = ftie_sha384->mic_control[1];
+                               if (wpa_ft_parse_ftie(pos, len, parse, 1) < 0)
+                                       return -1;
+                               break;
+                       }
+
                        if (len < sizeof(*ftie))
                                return -1;
                        ftie = (const struct rsn_ftie *) pos;
                        prot_ie_count = ftie->mic_control[1];
-                       if (wpa_ft_parse_ftie(pos, len, parse) < 0)
+                       if (wpa_ft_parse_ftie(pos, len, parse, 0) < 0)
                                return -1;
                        break;
                case WLAN_EID_TIMEOUT_INTERVAL:
index bb0765acfb9cf573b83f184e9f0d22c1742bb2c3..6d808d7fdaa4bb9cf1f61d25f78862f9e06b3b33 100644 (file)
@@ -314,6 +314,14 @@ struct rsn_ftie {
        /* followed by optional parameters */
 } STRUCT_PACKED;
 
+struct rsn_ftie_sha384 {
+       u8 mic_control[2];
+       u8 mic[24];
+       u8 anonce[WPA_NONCE_LEN];
+       u8 snonce[WPA_NONCE_LEN];
+       /* followed by optional parameters */
+} STRUCT_PACKED;
+
 #define FTIE_SUBELEM_R1KH_ID 1
 #define FTIE_SUBELEM_GTK 2
 #define FTIE_SUBELEM_R0KH_ID 3
@@ -449,7 +457,8 @@ struct wpa_ft_ies {
        int pairwise_cipher;
 };
 
-int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse);
+int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
+                    int use_sha384);
 
 int wpa_cipher_key_len(int cipher);
 int wpa_cipher_rsc_len(int cipher);
index 4dd209b38fa8d1577721dbd613b08b15301ae809..b8ab2b1bc36847564581b961a8e689a51f993fa4 100644 (file)
@@ -3547,7 +3547,8 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
                        goto fail;
                }
 
-               if (wpa_ft_parse_ies(pos, end - pos, &parse) < 0) {
+               if (wpa_ft_parse_ies(pos, end - pos, &parse,
+                                    wpa_key_mgmt_sha384(sm->key_mgmt)) < 0) {
                        wpa_printf(MSG_DEBUG, "FILS+FT: Failed to parse IEs");
                        goto fail;
                }
index 696571222df437a6462be9b987a77c60a4f92be9..c9bc34bca7c4b44f0fb36a07436dbc7138be2b15 100644 (file)
@@ -65,11 +65,13 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
 {
        struct wpa_ft_ies ft;
+       int use_sha384;
 
        if (sm == NULL)
                return 0;
 
-       if (wpa_ft_parse_ies(ies, ies_len, &ft) < 0)
+       use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
+       if (wpa_ft_parse_ies(ies, ies_len, &ft, use_sha384) < 0)
                return -1;
 
        if (ft.mdie && ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1)
@@ -423,12 +425,13 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
        size_t ft_ies_len;
        struct wpa_ft_ies parse;
        struct rsn_mdie *mdie;
-       struct rsn_ftie *ftie;
        u8 ptk_name[WPA_PMK_NAME_LEN];
        int ret;
        const u8 *bssid;
        const u8 *kck;
        size_t kck_len;
+       int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
+       const u8 *anonce, *snonce;
 
        wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
        wpa_hexdump(MSG_DEBUG, "FT: RIC IEs", ric_ies, ric_ies_len);
@@ -454,7 +457,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
                return -1;
        }
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, use_sha384) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
                return -1;
        }
@@ -467,16 +470,34 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
                return -1;
        }
 
-       ftie = (struct rsn_ftie *) parse.ftie;
-       if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
-               wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
-               return -1;
+       if (use_sha384) {
+               struct rsn_ftie_sha384 *ftie;
+
+               ftie = (struct rsn_ftie_sha384 *) parse.ftie;
+               if (!ftie || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return -1;
+               }
+
+               anonce = ftie->anonce;
+               snonce = ftie->snonce;
+       } else {
+               struct rsn_ftie *ftie;
+
+               ftie = (struct rsn_ftie *) parse.ftie;
+               if (!ftie || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return -1;
+               }
+
+               anonce = ftie->anonce;
+               snonce = ftie->snonce;
        }
 
-       if (os_memcmp(ftie->snonce, sm->snonce, WPA_NONCE_LEN) != 0) {
+       if (os_memcmp(snonce, sm->snonce, WPA_NONCE_LEN) != 0) {
                wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
                wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
-                           ftie->snonce, WPA_NONCE_LEN);
+                           snonce, WPA_NONCE_LEN);
                wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
                            sm->snonce, WPA_NONCE_LEN);
                return -1;
@@ -515,8 +536,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
        os_memcpy(sm->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
        wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", sm->r1kh_id, FT_R1KH_ID_LEN);
        wpa_hexdump(MSG_DEBUG, "FT: SNonce", sm->snonce, WPA_NONCE_LEN);
-       wpa_hexdump(MSG_DEBUG, "FT: ANonce", ftie->anonce, WPA_NONCE_LEN);
-       os_memcpy(sm->anonce, ftie->anonce, WPA_NONCE_LEN);
+       wpa_hexdump(MSG_DEBUG, "FT: ANonce", anonce, WPA_NONCE_LEN);
+       os_memcpy(sm->anonce, anonce, WPA_NONCE_LEN);
        if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name,
                              sm->r1kh_id, sm->own_addr, sm->pmk_r1,
                              sm->pmk_r1_name) < 0)
@@ -528,7 +549,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
 
        bssid = target_ap;
        if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce,
-                             ftie->anonce, sm->own_addr, bssid,
+                             anonce, sm->own_addr, bssid,
                              sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt,
                              sm->pairwise_cipher) < 0)
                return -1;
@@ -540,7 +561,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
                kck = sm->ptk.kck;
                kck_len = sm->ptk.kck_len;
        }
-       ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, ftie->anonce,
+       ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, anonce,
                                    sm->pmk_r1_name,
                                    kck, kck_len, bssid,
                                    ric_ies, ric_ies_len,
@@ -731,11 +752,13 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
 {
        struct wpa_ft_ies parse;
        struct rsn_mdie *mdie;
-       struct rsn_ftie *ftie;
        unsigned int count;
        u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
        const u8 *kck;
        size_t kck_len;
+       int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
+       const u8 *anonce, *snonce, *fte_mic;
+       u8 fte_elem_count;
 
        wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
 
@@ -750,7 +773,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
                return 0;
        }
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, use_sha384) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
                return -1;
        }
@@ -763,25 +786,47 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
                return -1;
        }
 
-       ftie = (struct rsn_ftie *) parse.ftie;
-       if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
-               wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
-               return -1;
+       if (use_sha384) {
+               struct rsn_ftie_sha384 *ftie;
+
+               ftie = (struct rsn_ftie_sha384 *) parse.ftie;
+               if (!ftie || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return -1;
+               }
+
+               anonce = ftie->anonce;
+               snonce = ftie->snonce;
+               fte_elem_count = ftie->mic_control[1];
+               fte_mic = ftie->mic;
+       } else {
+               struct rsn_ftie *ftie;
+
+               ftie = (struct rsn_ftie *) parse.ftie;
+               if (!ftie || parse.ftie_len < sizeof(*ftie)) {
+                       wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
+                       return -1;
+               }
+
+               anonce = ftie->anonce;
+               snonce = ftie->snonce;
+               fte_elem_count = ftie->mic_control[1];
+               fte_mic = ftie->mic;
        }
 
-       if (os_memcmp(ftie->snonce, sm->snonce, WPA_NONCE_LEN) != 0) {
+       if (os_memcmp(snonce, sm->snonce, WPA_NONCE_LEN) != 0) {
                wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
                wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
-                           ftie->snonce, WPA_NONCE_LEN);
+                           snonce, WPA_NONCE_LEN);
                wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
                            sm->snonce, WPA_NONCE_LEN);
                return -1;
        }
 
-       if (os_memcmp(ftie->anonce, sm->anonce, WPA_NONCE_LEN) != 0) {
+       if (os_memcmp(anonce, sm->anonce, WPA_NONCE_LEN) != 0) {
                wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE");
                wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
-                           ftie->anonce, WPA_NONCE_LEN);
+                           anonce, WPA_NONCE_LEN);
                wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
                            sm->anonce, WPA_NONCE_LEN);
                return -1;
@@ -826,10 +871,10 @@ 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 (ftie->mic_control[1] != count) {
+       if (fte_elem_count != count) {
                wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
                           "Control: received %u expected %u",
-                          ftie->mic_control[1], count);
+                          fte_elem_count, count);
                return -1;
        }
 
@@ -851,9 +896,9 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
                return -1;
        }
 
-       if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
+       if (os_memcmp_const(mic, fte_mic, 16) != 0) {
                wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
-               wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16);
+               wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", fte_mic, 16);
                wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16);
                return -1;
        }
index 08ebd88ccce0be1e7d8f061eabd76dfe6b986218..95ff258c2e785e01d2bb5f032ced217d921e5922 100644 (file)
@@ -656,7 +656,7 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
                sta->state = STATE3;
        }
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse) == 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0) == 0) {
                if (parse.r0kh_id) {
                        os_memcpy(bss->r0kh_id, parse.r0kh_id,
                                  parse.r0kh_id_len);