wlantest: Learn GTK/IGTK/BIGTK for the current link in MLO case

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2022-09-29 00:00:45 +03:00 committed by Jouni Malinen
parent 3d842d9108
commit 26cf43dd5d

View file

@ -514,11 +514,120 @@ static u8 * decrypt_eapol_key_data(struct wlantest *wt, int akmp, const u8 *kek,
}
static void learn_kde_keys_mlo(struct wlantest *wt, struct wlantest_bss *bss,
struct wlantest_sta *sta, int link_id,
struct wpa_eapol_ie_parse *ie)
{
const u8 *key, *pn;
size_t key_len;
unsigned int key_id;
bool tx;
if (ie->mlo_gtk[link_id]) {
pn = ie->mlo_gtk[link_id] + 1;
key = ie->mlo_gtk[link_id] + RSN_MLO_GTK_KDE_PREFIX_LENGTH;
key_len = ie->mlo_gtk_len[link_id] -
RSN_MLO_GTK_KDE_PREFIX_LENGTH;
key_id = ie->mlo_gtk[link_id][0] &
RSN_MLO_GTK_KDE_PREFIX0_KEY_ID_MASK;
tx = ie->mlo_gtk[link_id][0] & RSN_MLO_GTK_KDE_PREFIX0_TX;
if (key_len <= WPA_GTK_MAX_LEN) {
add_note(wt, MSG_DEBUG, "GTK KeyID=%u tx=%u",
key_id, tx);
if (ie->mlo_gtk[link_id][0] & BIT(3)) {
add_note(wt, MSG_INFO,
"MLO GTK KDE: Reserved field set");
}
wpa_hexdump(MSG_DEBUG, "GTK", key, key_len);
bss->gtk_len[key_id] = key_len;
sta->gtk_len = key_len;
os_memcpy(bss->gtk[key_id], key, key_len);
os_memcpy(sta->gtk, key, key_len);
bss->rsc[key_id][0] = pn[5];
bss->rsc[key_id][1] = pn[4];
bss->rsc[key_id][2] = pn[3];
bss->rsc[key_id][3] = pn[2];
bss->rsc[key_id][4] = pn[1];
bss->rsc[key_id][5] = pn[0];
bss->gtk_idx = key_id;
sta->gtk_idx = key_id;
wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[key_id], 6);
} else {
add_note(wt, MSG_INFO,
"Invalid MLO GTK KDE key length %zu",
key_len);
}
}
if (ie->mlo_igtk[link_id]) {
pn = ie->mlo_igtk[link_id] + 2;
key = ie->mlo_igtk[link_id] + RSN_MLO_IGTK_KDE_PREFIX_LENGTH;
key_len = ie->mlo_igtk_len[link_id] -
RSN_MLO_IGTK_KDE_PREFIX_LENGTH;
key_id = WPA_GET_LE16(ie->mlo_igtk[link_id]);
if (key_len <= WPA_IGTK_MAX_LEN && key_id >= 4 && key_id <= 5) {
add_note(wt, MSG_DEBUG, "IGTK KeyID=%u", key_id);
if (ie->mlo_igtk[link_id][2 + 6] & 0x0f) {
add_note(wt, MSG_INFO,
"MLO IGTK KDE: Reserved field set");
}
wpa_hexdump(MSG_DEBUG, "IGTK", key, key_len);
wpa_hexdump(MSG_DEBUG, "IPN", pn, 6);
bss->igtk_len[key_id] = key_len;
os_memcpy(bss->igtk[key_id], key, key_len);
bss->ipn[key_id][0] = pn[5];
bss->ipn[key_id][1] = pn[4];
bss->ipn[key_id][2] = pn[3];
bss->ipn[key_id][3] = pn[2];
bss->ipn[key_id][4] = pn[1];
bss->ipn[key_id][5] = pn[0];
bss->igtk_idx = key_id;
} else {
add_note(wt, MSG_INFO,
"Invalid MLO IGTK KDE ID %u or key length %zu",
key_id, key_len);
}
}
if (ie->mlo_bigtk[link_id]) {
pn = ie->mlo_bigtk[link_id] + 2;
key = ie->mlo_bigtk[link_id] + RSN_MLO_BIGTK_KDE_PREFIX_LENGTH;
key_len = ie->mlo_bigtk_len[link_id] -
RSN_MLO_BIGTK_KDE_PREFIX_LENGTH;
key_id = WPA_GET_LE16(ie->mlo_bigtk[link_id]);
if (key_len <= WPA_BIGTK_MAX_LEN &&
key_id >= 6 && key_id <= 7) {
add_note(wt, MSG_DEBUG, "BIGTK KeyID=%u", key_id);
if (ie->mlo_bigtk[link_id][2 + 6] & 0x0f) {
add_note(wt, MSG_INFO,
"MLO BIGTK KDE: Reserved field set");
}
wpa_hexdump(MSG_DEBUG, "BIGTK", key, key_len);
wpa_hexdump(MSG_DEBUG, "BIPN", pn, 6);
bss->igtk_len[key_id] = key_len;
os_memcpy(bss->igtk[key_id], key, key_len);
bss->ipn[key_id][0] = pn[5];
bss->ipn[key_id][1] = pn[4];
bss->ipn[key_id][2] = pn[3];
bss->ipn[key_id][3] = pn[2];
bss->ipn[key_id][4] = pn[1];
bss->ipn[key_id][5] = pn[0];
bss->bigtk_idx = key_id;
} else {
add_note(wt, MSG_INFO,
"Invalid MLO IGTK KDE ID %u or key length %zu",
key_id, key_len);
}
}
}
static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
struct wlantest_sta *sta,
const u8 *buf, size_t len, const u8 *rsc)
{
struct wpa_eapol_ie_parse ie;
int link_id;
if (wpa_parse_kde_ies(buf, len, &ie) < 0) {
add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
@ -685,6 +794,21 @@ static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
(unsigned) ie.bigtk_len);
}
}
for (link_id = 0; link_id < MAX_NUM_MLO_LINKS; link_id++) {
const u8 *addr;
if (!ie.mlo_link[link_id])
continue;
addr = &ie.mlo_link[link_id][RSN_MLO_LINK_KDE_LINK_MAC_INDEX];
if (os_memcmp(addr, bss->bssid, ETH_ALEN) != 0)
continue;
wpa_printf(MSG_DEBUG,
"Trying to learn keys for the current MLO link (ID %u)",
link_id);
learn_kde_keys_mlo(wt, bss, sta, link_id, &ie);
break;
}
}