]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS+FT: STA mode validation of PMKR1Name in initial MD association
authorJouni Malinen <jouni@codeaurora.org>
Wed, 13 Mar 2019 17:13:49 +0000 (19:13 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 13 Mar 2019 17:15:13 +0000 (19:15 +0200)
Verify that the AP uses matching PMKR1Name in (Re)Association Response
frame when going through FT initial mobility domain association using
FILS. Thise step was missing from the initial implementation, but is
needed to match the IEEE 802.11ai requirements for explicit confirmation
of the FT key hierarchy (similarly to what is done in FT 4-way handshake
when FILS is not used).

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/rsn_supp/wpa.c

index 86593ab784e63da7c74c5a0c695d33734b184849..4b42f89b5d2ab860696d3daef7659b1b8c7d957d 100644 (file)
@@ -3988,11 +3988,13 @@ static int fils_ft_build_assoc_req_rsne(struct wpa_sm *sm, struct wpabuf *buf)
                   MAC2STR(sm->r1kh_id));
        pos = wpabuf_put(buf, WPA_PMK_NAME_LEN);
        if (wpa_derive_pmk_r1_name(sm->pmk_r0_name, sm->r1kh_id, sm->own_addr,
-                                  pos, use_sha384) < 0) {
+                                  sm->pmk_r1_name, use_sha384) < 0) {
                wpa_printf(MSG_WARNING, "FILS+FT: Could not derive PMKR1Name");
                return -1;
        }
-       wpa_hexdump(MSG_DEBUG, "FILS+FT: PMKR1Name", pos, WPA_PMK_NAME_LEN);
+       wpa_hexdump(MSG_DEBUG, "FILS+FT: PMKR1Name", sm->pmk_r1_name,
+                   WPA_PMK_NAME_LEN);
+       os_memcpy(pos, sm->pmk_r1_name, WPA_PMK_NAME_LEN);
 
 #ifdef CONFIG_IEEE80211W
        if (sm->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
@@ -4295,6 +4297,24 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
        }
 #endif /* CONFIG_OCV */
 
+#ifdef CONFIG_IEEE80211R
+       if (wpa_key_mgmt_ft(sm->key_mgmt) && sm->fils_ft_ies) {
+               struct wpa_ie_data rsn;
+
+               /* Check that PMKR1Name derived by the AP matches */
+               if (!elems.rsn_ie ||
+                   wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
+                                        &rsn) < 0 ||
+                   !rsn.pmkid || rsn.num_pmkid != 1 ||
+                   os_memcmp(rsn.pmkid, sm->pmk_r1_name,
+                             WPA_PMK_NAME_LEN) != 0) {
+                       wpa_printf(MSG_DEBUG,
+                                  "FILS+FT: No RSNE[PMKR1Name] match in AssocResp");
+                       goto fail;
+               }
+       }
+#endif /* CONFIG_IEEE80211R */
+
        /* Key Delivery */
        if (!elems.key_delivery) {
                wpa_printf(MSG_DEBUG, "FILS: No Key Delivery element");