|
@@ -753,12 +753,24 @@ static void rx_mgmt_action(struct wlantest *wt, const u8 *data, size_t len,
|
|
|
}
|
|
|
|
|
|
|
|
|
-static int check_mmie_mic(const u8 *igtk, const u8 *data, size_t len)
|
|
|
+static int check_mmie_mic(const u8 *igtk, size_t igtk_len,
|
|
|
+ const u8 *data, size_t len)
|
|
|
{
|
|
|
u8 *buf;
|
|
|
u8 mic[16];
|
|
|
u16 fc;
|
|
|
const struct ieee80211_hdr *hdr;
|
|
|
+ int ret, mic_len;
|
|
|
+
|
|
|
+ if (igtk_len == 32)
|
|
|
+ mic_len = 16;
|
|
|
+ else if (igtk_len == 16)
|
|
|
+ mic_len = 8;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ if (len < 24 || len - 24 < mic_len)
|
|
|
+ return -1;
|
|
|
|
|
|
buf = os_malloc(len + 20 - 24);
|
|
|
if (buf == NULL)
|
|
@@ -772,19 +784,23 @@ static int check_mmie_mic(const u8 *igtk, const u8 *data, size_t len)
|
|
|
os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN);
|
|
|
|
|
|
/* Frame body with MMIE MIC masked to zero */
|
|
|
- os_memcpy(buf + 20, data + 24, len - 24 - 8);
|
|
|
- os_memset(buf + 20 + len - 24 - 8, 0, 8);
|
|
|
+ os_memcpy(buf + 20, data + 24, len - 24 - mic_len);
|
|
|
+ os_memset(buf + 20 + len - 24 - mic_len, 0, mic_len);
|
|
|
|
|
|
wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, len + 20 - 24);
|
|
|
/* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
|
|
|
- if (omac1_aes_128(igtk, buf, len + 20 - 24, mic) < 0) {
|
|
|
+ if (igtk_len == 32)
|
|
|
+ ret = omac1_aes_256(igtk, buf, len + 20 - 24, mic);
|
|
|
+ else
|
|
|
+ ret = omac1_aes_128(igtk, buf, len + 20 - 24, mic);
|
|
|
+ if (ret < 0) {
|
|
|
os_free(buf);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
os_free(buf);
|
|
|
|
|
|
- if (os_memcmp(data + len - 8, mic, 8) != 0)
|
|
|
+ if (os_memcmp(data + len - mic_len, mic, mic_len) != 0)
|
|
|
return -1;
|
|
|
|
|
|
return 0;
|
|
@@ -798,6 +814,7 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
|
|
|
const u8 *mmie;
|
|
|
u16 keyid;
|
|
|
struct wlantest_bss *bss;
|
|
|
+ size_t mic_len;
|
|
|
|
|
|
mgmt = (const struct ieee80211_mgmt *) data;
|
|
|
fc = le_to_host16(mgmt->frame_control);
|
|
@@ -814,8 +831,11 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
|
|
|
if (bss == NULL)
|
|
|
return 0; /* No key known yet */
|
|
|
|
|
|
- if (len < 24 + 18 || data[len - 18] != WLAN_EID_MMIE ||
|
|
|
- data[len - 17] != 16) {
|
|
|
+ mic_len = bss->igtk_len[4] == 32 || bss->igtk_len[5] == 32 ? 16 : 8;
|
|
|
+
|
|
|
+ if (len < 24 + 10 + mic_len ||
|
|
|
+ data[len - (10 + mic_len)] != WLAN_EID_MMIE ||
|
|
|
+ data[len - (10 + mic_len - 1)] != 8 + mic_len) {
|
|
|
/* No MMIE */
|
|
|
if (bss->rsn_capab & WPA_CAPABILITY_MFPC) {
|
|
|
add_note(wt, MSG_INFO, "Robust group-addressed "
|
|
@@ -827,7 +847,7 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- mmie = data + len - 16;
|
|
|
+ mmie = data + len - (8 + mic_len);
|
|
|
keyid = WPA_GET_LE16(mmie);
|
|
|
if (keyid & 0xf000) {
|
|
|
add_note(wt, MSG_INFO, "MMIE KeyID reserved bits not zero "
|
|
@@ -842,9 +862,9 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
|
|
|
}
|
|
|
wpa_printf(MSG_DEBUG, "MMIE KeyID %u", keyid);
|
|
|
wpa_hexdump(MSG_MSGDUMP, "MMIE IPN", mmie + 2, 6);
|
|
|
- wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, 8);
|
|
|
+ wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, mic_len);
|
|
|
|
|
|
- if (!bss->igtk_set[keyid]) {
|
|
|
+ if (!bss->igtk_len[keyid]) {
|
|
|
add_note(wt, MSG_DEBUG, "No IGTK known to validate BIP frame");
|
|
|
return 0;
|
|
|
}
|
|
@@ -856,7 +876,8 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
|
|
|
wpa_hexdump(MSG_INFO, "Last RX IPN", bss->ipn[keyid], 6);
|
|
|
}
|
|
|
|
|
|
- if (check_mmie_mic(bss->igtk[keyid], data, len) < 0) {
|
|
|
+ if (check_mmie_mic(bss->igtk[keyid], bss->igtk_len[keyid], data, len) <
|
|
|
+ 0) {
|
|
|
add_note(wt, MSG_INFO, "Invalid MMIE MIC in a frame from "
|
|
|
MACSTR, MAC2STR(mgmt->sa));
|
|
|
bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
|