wlantest: FTE MIC calculation for MLO Reassociation Response frame
Use the MLD MAC addresses and MLO-specific MIC calculation rules per IEEE P802.11be/D4.0, 13.8.5. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
78b153f90a
commit
8cf919ffd5
1 changed files with 98 additions and 17 deletions
|
@ -1833,6 +1833,16 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
|
||||||
size_t mic_len = 16;
|
size_t mic_len = 16;
|
||||||
const u8 *kck, *kek;
|
const u8 *kck, *kek;
|
||||||
size_t kck_len, kek_len;
|
size_t kck_len, kek_len;
|
||||||
|
const u8 *aa, *spa;
|
||||||
|
struct wpabuf *extra = NULL, *rsne = NULL, *rsnxe = NULL;
|
||||||
|
|
||||||
|
if (ml) {
|
||||||
|
aa = bss->mld_mac_addr;
|
||||||
|
spa = sta->mld_mac_addr;
|
||||||
|
} else {
|
||||||
|
aa = bss->bssid;
|
||||||
|
spa = sta->addr;
|
||||||
|
}
|
||||||
|
|
||||||
use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
|
use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
|
||||||
|
|
||||||
|
@ -1949,11 +1959,64 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
|
||||||
os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
|
os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 3;
|
count = 2; /* MDE and FTE */
|
||||||
|
if (ml) {
|
||||||
|
int link_id;
|
||||||
|
struct wlantest_bss *l_bss;
|
||||||
|
|
||||||
|
extra = wpabuf_alloc(MAX_NUM_MLO_LINKS * ETH_ALEN);
|
||||||
|
rsne = wpabuf_alloc(MAX_NUM_MLO_LINKS * 256);
|
||||||
|
rsnxe = wpabuf_alloc(MAX_NUM_MLO_LINKS * 256);
|
||||||
|
if (!extra || !rsne || !rsnxe)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
for (link_id = 0; link_id < MAX_NUM_MLO_LINKS;
|
||||||
|
link_id++) {
|
||||||
|
if (is_zero_ether_addr(sta->link_addr[link_id]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
l_bss = bss_find_mld(wt, bss->mld_mac_addr,
|
||||||
|
link_id);
|
||||||
|
if (!l_bss) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"FT: No BSS entry found for AP MLD "
|
||||||
|
MACSTR " link ID %u",
|
||||||
|
MAC2STR(bss->mld_mac_addr),
|
||||||
|
link_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++; /* RSNE */
|
||||||
|
wpabuf_put_data(rsne, l_bss->rsnie,
|
||||||
|
2 + l_bss->rsnie[1]);
|
||||||
|
|
||||||
|
if (l_bss->rsnxe_len) {
|
||||||
|
count++;
|
||||||
|
wpabuf_put_u8(rsnxe, WLAN_EID_RSNX);
|
||||||
|
wpabuf_put_u8(rsnxe, l_bss->rsnxe_len);
|
||||||
|
wpabuf_put_data(rsnxe,
|
||||||
|
l_bss->rsnxe,
|
||||||
|
l_bss->rsnxe_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_put_data(extra, l_bss->bssid, ETH_ALEN);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
count++; /* RSNE */
|
||||||
|
rsne = wpabuf_alloc_copy(parse.rsn - 2,
|
||||||
|
parse.rsn_len + 2);
|
||||||
|
if (!rsne)
|
||||||
|
goto out;
|
||||||
|
if (parse.rsnxe) {
|
||||||
|
count++;
|
||||||
|
rsnxe = wpabuf_alloc_copy(parse.rsnxe - 2,
|
||||||
|
parse.rsnxe_len + 2);
|
||||||
|
if (!rsnxe)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (parse.ric)
|
if (parse.ric)
|
||||||
count += ieee802_11_ie_count(parse.ric, parse.ric_len);
|
count += ieee802_11_ie_count(parse.ric, parse.ric_len);
|
||||||
if (parse.rsnxe)
|
|
||||||
count++;
|
|
||||||
if (fte_elem_count != count) {
|
if (fte_elem_count != count) {
|
||||||
add_note(wt, MSG_INFO,
|
add_note(wt, MSG_INFO,
|
||||||
"FT: Unexpected IE count in MIC Control: received %u expected %u",
|
"FT: Unexpected IE count in MIC Control: received %u expected %u",
|
||||||
|
@ -1972,26 +2035,30 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
|
||||||
kek = sta->ptk.kek;
|
kek = sta->ptk.kek;
|
||||||
kek_len = sta->ptk.kek_len;
|
kek_len = sta->ptk.kek_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FTE might be fragmented. If it is, the separate Fragment
|
||||||
|
* elements are included in MIC calculation as full elements. */
|
||||||
if (wpa_ft_mic(sta->key_mgmt, kck, kck_len,
|
if (wpa_ft_mic(sta->key_mgmt, kck, kck_len,
|
||||||
sta->addr, bss->bssid, 6,
|
spa, aa, 6,
|
||||||
parse.mdie - 2, parse.mdie_len + 2,
|
parse.mdie - 2, parse.mdie_len + 2,
|
||||||
parse.ftie - 2, parse.ftie_len + 2,
|
elems.ftie - 2, elems.fte_defrag_len + 2,
|
||||||
parse.rsn - 2, parse.rsn_len + 2,
|
wpabuf_head(rsne), wpabuf_len(rsne),
|
||||||
parse.ric, parse.ric_len,
|
parse.ric, parse.ric_len,
|
||||||
parse.rsnxe ? parse.rsnxe - 2 : NULL,
|
rsnxe ? wpabuf_head(rsnxe) : NULL,
|
||||||
parse.rsnxe ? parse.rsnxe_len + 2 : 0,
|
rsnxe ? wpabuf_len(rsnxe) : 0,
|
||||||
NULL,
|
extra,
|
||||||
mic) < 0) {
|
mic) < 0) {
|
||||||
add_note(wt, MSG_INFO, "FT: Failed to calculate MIC");
|
add_note(wt, MSG_INFO, "FT: Failed to calculate MIC");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (os_memcmp_const(mic, fte_mic, mic_len) != 0) {
|
if (os_memcmp_const(mic, fte_mic, mic_len) != 0) {
|
||||||
|
int link_id;
|
||||||
|
|
||||||
add_note(wt, MSG_INFO, "FT: Invalid MIC in FTE");
|
add_note(wt, MSG_INFO, "FT: Invalid MIC in FTE");
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"FT: addr=" MACSTR " auth_addr=" MACSTR,
|
"FT: addr=" MACSTR " auth_addr=" MACSTR,
|
||||||
MAC2STR(sta->addr),
|
MAC2STR(spa), MAC2STR(aa));
|
||||||
MAC2STR(bss->bssid));
|
|
||||||
wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
|
wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC",
|
||||||
fte_mic, mic_len);
|
fte_mic, mic_len);
|
||||||
wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC",
|
wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC",
|
||||||
|
@ -1999,12 +2066,23 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
|
||||||
wpa_hexdump(MSG_MSGDUMP, "FT: MDE",
|
wpa_hexdump(MSG_MSGDUMP, "FT: MDE",
|
||||||
parse.mdie - 2, parse.mdie_len + 2);
|
parse.mdie - 2, parse.mdie_len + 2);
|
||||||
wpa_hexdump(MSG_MSGDUMP, "FT: FTE",
|
wpa_hexdump(MSG_MSGDUMP, "FT: FTE",
|
||||||
parse.ftie - 2, parse.ftie_len + 2);
|
elems.ftie - 2, elems.fte_defrag_len + 2);
|
||||||
wpa_hexdump(MSG_MSGDUMP, "FT: RSN",
|
wpa_hexdump_buf(MSG_MSGDUMP, "FT: RSNE", rsne);
|
||||||
parse.rsn - 2, parse.rsn_len + 2);
|
wpa_hexdump_buf(MSG_MSGDUMP, "FT: RSNXE", rsnxe);
|
||||||
wpa_hexdump(MSG_MSGDUMP, "FT: RSNXE",
|
for (link_id = 0; link_id < MAX_NUM_MLO_LINKS;
|
||||||
parse.rsnxe ? parse.rsnxe - 2 : NULL,
|
link_id++) {
|
||||||
parse.rsnxe ? parse.rsnxe_len + 2 : 0);
|
struct wlantest_bss *l_bss;
|
||||||
|
|
||||||
|
if (is_zero_ether_addr(sta->link_addr[link_id]))
|
||||||
|
continue;
|
||||||
|
l_bss = bss_find_mld(wt, bss->mld_mac_addr,
|
||||||
|
link_id);
|
||||||
|
if (l_bss)
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"FT: AP link %d address: "
|
||||||
|
MACSTR, link_id,
|
||||||
|
MAC2STR(l_bss->bssid));
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2032,6 +2110,9 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
wpa_ft_parse_ies_free(&parse);
|
wpa_ft_parse_ies_free(&parse);
|
||||||
|
wpabuf_free(rsne);
|
||||||
|
wpabuf_free(rsnxe);
|
||||||
|
wpabuf_free(extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elems.owe_dh && elems.owe_dh_len >= 2) {
|
if (elems.owe_dh && elems.owe_dh_len >= 2) {
|
||||||
|
|
Loading…
Reference in a new issue