]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wlantest: Add support for FT-PSK initial association key derivation
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 6 Aug 2015 12:51:36 +0000 (15:51 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 6 Aug 2015 17:47:25 +0000 (20:47 +0300)
This adds minimal support for deriving keys for FT-PSK to allow the
initial mobility domain association to be analyzed in more detail.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
wlantest/bss.c
wlantest/rx_eapol.c
wlantest/rx_mgmt.c
wlantest/wlantest.h

index 61e2960fd54aead9852a53971cdb5fb1bcab2329..f021956ccd312b68c84fb104e8cb2ba696055a0a 100644 (file)
@@ -217,6 +217,9 @@ void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
                          elems->wpa_ie_len + 2);
        }
 
+       if (elems->mdie)
+               os_memcpy(bss->mdid, elems->mdie, 2);
+
        if (!update)
                return;
 
index 569cd3c03a3592bad95b03ca0eaf2e5b545c1e64..75bfa7d3ebf20b569c28f79323382ddf0ff20206 100644 (file)
@@ -100,12 +100,42 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
 {
        struct wpa_ptk ptk;
 
-       if (wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
-                          "Pairwise key expansion",
-                          bss->bssid, sta->addr, sta->anonce, sta->snonce,
-                          &ptk, sta->key_mgmt, sta->pairwise_cipher) < 0 ||
-           check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data, len) < 0)
+       if (wpa_key_mgmt_ft(sta->key_mgmt)) {
+               u8 pmk_r0[PMK_LEN];
+               u8 pmk_r0_name[WPA_PMK_NAME_LEN];
+               u8 pmk_r1[PMK_LEN];
+               u8 pmk_r1_name[WPA_PMK_NAME_LEN];
+               u8 ptk_name[WPA_PMK_NAME_LEN];
+
+               wpa_derive_pmk_r0(pmk->pmk, sizeof(pmk->pmk),
+                                 bss->ssid, bss->ssid_len, bss->mdid,
+                                 bss->r0kh_id, bss->r0kh_id_len,
+                                 sta->addr, pmk_r0, pmk_r0_name);
+               wpa_hexdump(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN);
+               wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name,
+                           WPA_PMK_NAME_LEN);
+               wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, bss->r1kh_id,
+                                 sta->addr, pmk_r1, pmk_r1_name);
+               wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN);
+               wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name,
+                           WPA_PMK_NAME_LEN);
+               if (wpa_pmk_r1_to_ptk(pmk_r1, sta->snonce, sta->anonce,
+                                     sta->addr,
+                                     bss->bssid, pmk_r1_name, &ptk, ptk_name,
+                                     sta->key_mgmt,
+                                     sta->pairwise_cipher) < 0 ||
+                   check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
+                             len) < 0)
+                       return -1;
+       } else if (wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
+                                 "Pairwise key expansion",
+                                 bss->bssid, sta->addr, sta->anonce,
+                                 sta->snonce, &ptk, sta->key_mgmt,
+                                 sta->pairwise_cipher) < 0 ||
+                  check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
+                            len) < 0) {
                return -1;
+       }
 
        sta->tk_len = wpa_cipher_key_len(sta->pairwise_cipher);
        wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
index 45433dd4e3e5430482ea48da7dd69043b23b7ba2..6242bc600bfa5d32a835f0aa461d5e01a421dc1e 100644 (file)
@@ -314,6 +314,9 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
        struct wlantest_bss *bss;
        struct wlantest_sta *sta;
        u16 capab, status, aid;
+       const u8 *ies;
+       size_t ies_len;
+       struct wpa_ft_ies parse;
 
        mgmt = (const struct ieee80211_mgmt *) data;
        bss = bss_get(wt, mgmt->bssid);
@@ -329,6 +332,9 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
                return;
        }
 
+       ies = mgmt->u.assoc_resp.variable;
+       ies_len = len - (mgmt->u.assoc_resp.variable - data);
+
        capab = le_to_host16(mgmt->u.assoc_resp.capab_info);
        status = le_to_host16(mgmt->u.assoc_resp.status_code);
        aid = le_to_host16(mgmt->u.assoc_resp.aid);
@@ -340,8 +346,6 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
 
        if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
                struct ieee802_11_elems elems;
-               const u8 *ies = mgmt->u.assoc_resp.variable;
-               size_t ies_len = len - (mgmt->u.assoc_resp.variable - data);
                if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
                    ParseFailed) {
                        add_note(wt, MSG_INFO, "Failed to parse IEs in "
@@ -382,6 +386,16 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
                         MAC2STR(sta->addr), MAC2STR(bss->bssid));
                sta->state = STATE3;
        }
+
+       if (wpa_ft_parse_ies(ies, ies_len, &parse) == 0) {
+               if (parse.r0kh_id) {
+                       os_memcpy(bss->r0kh_id, parse.r0kh_id,
+                                 parse.r0kh_id_len);
+                       bss->r0kh_id_len = parse.r0kh_id_len;
+               }
+               if (parse.r1kh_id)
+                       os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
+       }
 }
 
 
index 29bcab501b88f9611eda198abfa28656544ba1dc..ced9baa0e32254f2507e77b4ad493b59c18eb483 100644 (file)
@@ -151,6 +151,10 @@ struct wlantest_bss {
        u8 ipn[6][6];
        u32 counters[NUM_WLANTEST_BSS_COUNTER];
        struct dl_list tdls; /* struct wlantest_tdls */
+       u8 mdid[2];
+       u8 r0kh_id[FT_R0KH_ID_MAX_LEN];
+       size_t r0kh_id_len;
+       u8 r1kh_id[FT_R1KH_ID_LEN];
 };
 
 struct wlantest_radius {