(unsigned) ie.igtk_len);
}
}
+
+ if (ie.bigtk) {
+ wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - BIGTK KDE",
+ ie.bigtk, ie.bigtk_len);
+ if (ie.bigtk_len == 24) {
+ u16 id;
+
+ id = WPA_GET_LE16(ie.bigtk);
+ if (id < 6 || id > 7) {
+ add_note(wt, MSG_INFO,
+ "Unexpected BIGTK KeyID %u", id);
+ } else {
+ const u8 *ipn;
+
+ add_note(wt, MSG_DEBUG, "BIGTK KeyID %u", id);
+ wpa_hexdump(MSG_DEBUG, "BIPN", ie.bigtk + 2, 6);
+ wpa_hexdump(MSG_DEBUG, "BIGTK", ie.bigtk + 8,
+ 16);
+ os_memcpy(bss->igtk[id], ie.bigtk + 8, 16);
+ bss->igtk_len[id] = 16;
+ ipn = ie.bigtk + 2;
+ bss->ipn[id][0] = ipn[5];
+ bss->ipn[id][1] = ipn[4];
+ bss->ipn[id][2] = ipn[3];
+ bss->ipn[id][3] = ipn[2];
+ bss->ipn[id][4] = ipn[1];
+ bss->ipn[id][5] = ipn[0];
+ bss->bigtk_idx = id;
+ }
+ } else if (ie.bigtk_len == 40) {
+ u16 id;
+
+ id = WPA_GET_LE16(ie.bigtk);
+ if (id < 6 || id > 7) {
+ add_note(wt, MSG_INFO,
+ "Unexpected BIGTK KeyID %u", id);
+ } else {
+ const u8 *ipn;
+
+ add_note(wt, MSG_DEBUG, "BIGTK KeyID %u", id);
+ wpa_hexdump(MSG_DEBUG, "BIPN", ie.bigtk + 2, 6);
+ wpa_hexdump(MSG_DEBUG, "BIGTK", ie.bigtk + 8,
+ 32);
+ os_memcpy(bss->igtk[id], ie.bigtk + 8, 32);
+ bss->igtk_len[id] = 32;
+ ipn = ie.bigtk + 2;
+ bss->ipn[id][0] = ipn[5];
+ bss->ipn[id][1] = ipn[4];
+ bss->ipn[id][2] = ipn[3];
+ bss->ipn[id][3] = ipn[2];
+ bss->ipn[id][4] = ipn[1];
+ bss->ipn[id][5] = ipn[0];
+ bss->bigtk_idx = id;
+ }
+ } else {
+ add_note(wt, MSG_INFO, "Invalid BIGTK KDE length %u",
+ (unsigned) ie.bigtk_len);
+ }
+ }
}
#include "wlantest.h"
+static int check_mmie_mic(unsigned int mgmt_group_cipher,
+ const u8 *igtk, size_t igtk_len,
+ const u8 *data, size_t len);
+
+
static const char * mgmt_stype(u16 stype)
{
switch (stype) {
struct wlantest_bss *bss;
struct ieee802_11_elems elems;
size_t offset;
+ const u8 *mme;
+ size_t mic_len;
+ u16 keyid;
mgmt = (const struct ieee80211_mgmt *) data;
offset = mgmt->u.beacon.variable - data;
}
bss_update(wt, bss, &elems);
+
+ mme = get_ie(mgmt->u.beacon.variable, len - offset, WLAN_EID_MMIE);
+ if (!mme) {
+ if (bss->bigtk_idx) {
+ add_note(wt, MSG_INFO,
+ "Unexpected unprotected Beacon frame from "
+ MACSTR, MAC2STR(mgmt->sa));
+ bss->counters[WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE]++;
+ }
+ return;
+ }
+
+ mic_len = bss->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ? 8 : 16;
+ if (len < 24 + 10 + mic_len ||
+ data[len - (10 + mic_len)] != WLAN_EID_MMIE ||
+ data[len - (10 + mic_len - 1)] != 8 + mic_len) {
+ add_note(wt, MSG_INFO, "Invalid MME in a Beacon frame from "
+ MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ mme += 2;
+ keyid = WPA_GET_LE16(mme);
+ if (keyid < 6 || keyid > 7) {
+ add_note(wt, MSG_INFO, "Unexpected MME KeyID %u from " MACSTR,
+ keyid, MAC2STR(mgmt->sa));
+ bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "Beacon frame MME KeyID %u", keyid);
+ wpa_hexdump(MSG_MSGDUMP, "MME IPN", mme + 2, 6);
+ wpa_hexdump(MSG_MSGDUMP, "MME MIC", mme + 8, mic_len);
+
+ if (!bss->igtk_len[keyid]) {
+ add_note(wt, MSG_DEBUG, "No BIGTK known to validate BIP frame");
+ return;
+ }
+
+ if (os_memcmp(mme + 2, bss->ipn[keyid], 6) <= 0) {
+ add_note(wt, MSG_INFO, "BIP replay detected: SA=" MACSTR,
+ MAC2STR(mgmt->sa));
+ wpa_hexdump(MSG_INFO, "RX IPN", mme + 2, 6);
+ wpa_hexdump(MSG_INFO, "Last RX IPN", bss->ipn[keyid], 6);
+ }
+
+ if (check_mmie_mic(bss->mgmt_group_cipher, bss->igtk[keyid],
+ bss->igtk_len[keyid], data, len) < 0) {
+ add_note(wt, MSG_INFO, "Invalid MME MIC in a Beacon frame from "
+ MACSTR, MAC2STR(mgmt->sa));
+ bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
+ return;
+ }
+
+ add_note(wt, MSG_DEBUG, "Valid MME MIC in Beacon frame");
+ os_memcpy(bss->ipn[keyid], mme + 2, 6);
}
os_memcpy(buf + 20, data + 24, len - 24 - mic_len);
os_memset(buf + 20 + len - 24 - mic_len, 0, mic_len);
+ if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) {
+ /* Timestamp field masked to zero */
+ os_memset(buf + 20, 0, 8);
+ }
+
wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, len + 20 - 24);
/* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {