a[0] = val & 0xff;
}
+static inline u64 WPA_GET_LE48(const u8 *a)
+{
+ return (((u64) a[5]) << 40) | (((u64) a[4]) << 32) |
+ (((u64) a[3]) << 24) | (((u64) a[2]) << 16) |
+ (((u64) a[1]) << 8) | ((u64) a[0]);
+}
+
+static inline void WPA_PUT_LE48(u8 *a, u64 val)
+{
+ a[5] = val >> 40;
+ a[4] = val >> 32;
+ a[3] = val >> 24;
+ a[2] = val >> 16;
+ a[1] = val >> 8;
+ a[0] = val & 0xff;
+}
+
static inline u64 WPA_GET_BE64(const u8 *a)
{
return (((u64) a[0]) << 56) | (((u64) a[1]) << 48) |
u8 * bip_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
- u8 *ipn, int keyid, size_t *prot_len)
+ u64 ipn, int keyid, size_t *prot_len)
{
u8 *prot, *pos, *buf;
u8 mic[16];
*pos++ = igtk_len == 32 ? 24 : 16;
WPA_PUT_LE16(pos, keyid);
pos += 2;
- os_memcpy(pos, ipn, 6);
+ WPA_PUT_LE48(pos, ipn);
pos += 6;
os_memset(pos, 0, igtk_len == 32 ? 16 : 8); /* MIC */
return -1;
os_memset(stub, 0x11, sizeof(stub));
- inc_byte_array(bss->ipn[bss->igtk_idx], 6);
+ bss->ipn[bss->igtk_idx]++;
prot = bip_protect(incorrect_key ? stub : bss->igtk[bss->igtk_idx],
bss->igtk_len[bss->igtk_idx],
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->ipn[key_id] = WPA_GET_LE48(pn);
bss->igtk_idx = key_id;
} else {
add_note(wt, MSG_INFO,
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->ipn[key_id] = WPA_GET_LE48(pn);
bss->bigtk_idx = key_id;
} else {
add_note(wt, MSG_INFO,
os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
bss->igtk_len[id] = 16;
ipn = ie.igtk + 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->ipn[id] = WPA_GET_LE48(ipn);
bss->igtk_idx = id;
}
} else if (ie.igtk_len == 40) {
os_memcpy(bss->igtk[id], ie.igtk + 8, 32);
bss->igtk_len[id] = 32;
ipn = ie.igtk + 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->ipn[id] = WPA_GET_LE48(ipn);
bss->igtk_idx = id;
}
} else {
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->ipn[id] = WPA_GET_LE48(ipn);
bss->bigtk_idx = id;
}
} else if (ie.bigtk_len == 40) {
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->ipn[id] = WPA_GET_LE48(ipn);
bss->bigtk_idx = id;
}
} else {
const u8 *mme;
size_t mic_len;
u16 keyid;
+ u64 rx_bipn;
mgmt = (const struct ieee80211_mgmt *) data;
offset = mgmt->u.beacon.variable - data;
return;
}
- wpa_printf(MSG_DEBUG, "Beacon frame MME KeyID %u", keyid);
- wpa_hexdump(MSG_MSGDUMP, "MME IPN", mme + 2, 6);
+ rx_bipn = WPA_GET_LE48(mme + 2);
+ wpa_printf(MSG_DEBUG, "Beacon frame BSSID " MACSTR
+ " MME KeyID %u BIPN 0x%lx",
+ MAC2STR(mgmt->bssid), keyid, rx_bipn);
wpa_hexdump(MSG_MSGDUMP, "MME MIC", mme + 8, mic_len);
if (!bss->igtk_len[keyid]) {
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 (rx_bipn <= bss->ipn[keyid]) {
+ add_note(wt, MSG_INFO, "BIP replay detected: SA=" MACSTR
+ " RX BIPN 0x%lx <= 0x%lx",
+ MAC2STR(mgmt->sa), rx_bipn, bss->ipn[keyid]);
}
if (check_mmie_mic(bss->mgmt_group_cipher, bss->igtk[keyid],
}
add_note(wt, MSG_DEBUG, "Valid MME MIC in Beacon frame");
- os_memcpy(bss->ipn[keyid], mme + 2, 6);
+ bss->ipn[keyid] = rx_bipn;
}
os_memcpy(bss->igtk[keyidx], igtk, igtk_len);
bss->igtk_len[keyidx] = igtk_len;
ipn = igtk_elem + 2;
- bss->ipn[keyidx][0] = ipn[5];
- bss->ipn[keyidx][1] = ipn[4];
- bss->ipn[keyidx][2] = ipn[3];
- bss->ipn[keyidx][3] = ipn[2];
- bss->ipn[keyidx][4] = ipn[1];
- bss->ipn[keyidx][5] = ipn[0];
+ bss->ipn[keyidx] = WPA_GET_LE48(ipn);
bss->igtk_idx = keyidx;
}
os_memcpy(bss->igtk[keyidx], bigtk, bigtk_len);
bss->igtk_len[keyidx] = bigtk_len;
ipn = bigtk_elem + 2;
- bss->ipn[keyidx][0] = ipn[5];
- bss->ipn[keyidx][1] = ipn[4];
- bss->ipn[keyidx][2] = ipn[3];
- bss->ipn[keyidx][3] = ipn[2];
- bss->ipn[keyidx][4] = ipn[1];
- bss->ipn[keyidx][5] = ipn[0];
+ bss->ipn[keyidx] = WPA_GET_LE48(ipn);
bss->bigtk_idx = keyidx;
}
u16 keyid;
struct wlantest_bss *bss;
size_t mic_len;
+ u64 rx_ipn;
mgmt = (const struct ieee80211_mgmt *) data;
fc = le_to_host16(mgmt->frame_control);
bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
return 0;
}
- wpa_printf(MSG_DEBUG, "MMIE KeyID %u", keyid);
- wpa_hexdump(MSG_MSGDUMP, "MMIE IPN", mmie + 2, 6);
+
+ rx_ipn = WPA_GET_LE48(mmie + 2);
+ wpa_printf(MSG_DEBUG, "MME KeyID %u IPN 0x%lx", keyid, rx_ipn);
wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, mic_len);
if (!bss->igtk_len[keyid]) {
return 0;
}
- if (os_memcmp(mmie + 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", mmie + 2, 6);
- wpa_hexdump(MSG_INFO, "Last RX IPN", bss->ipn[keyid], 6);
+ if (rx_ipn <= bss->ipn[keyid]) {
+ add_note(wt, MSG_INFO, "BIP replay detected: SA=" MACSTR
+ " RX IPN 0x%lx <= 0x%lx",
+ MAC2STR(mgmt->sa), rx_ipn, bss->ipn[keyid]);
}
if (check_mmie_mic(bss->mgmt_group_cipher, bss->igtk[keyid],
}
add_note(wt, MSG_DEBUG, "Valid MMIE MIC");
- os_memcpy(bss->ipn[keyid], mmie + 2, 6);
+ bss->ipn[keyid] = rx_ipn;
bss->counters[WLANTEST_BSS_COUNTER_VALID_BIP_MMIE]++;
if (stype == WLAN_FC_STYPE_DEAUTH)
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
};
- u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ u64 ipn = 0x04;
u8 frame[] = {
0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
"Deauthentication frame\n");
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
- wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
+ wpa_printf(MSG_INFO, "IPN: 0x%lx", ipn);
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
prot = bip_protect(igtk, sizeof(igtk), frame, sizeof(frame),
u8 igtk[8][32];
size_t igtk_len[8];
int igtk_idx;
- u8 ipn[8][6];
+ u64 ipn[8];
int bigtk_idx;
u32 counters[NUM_WLANTEST_BSS_COUNTER];
struct dl_list tdls; /* struct wlantest_tdls */
const u8 *data, size_t data_len, size_t *decrypted_len);
u8 * bip_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
- u8 *ipn, int keyid, size_t *prot_len);
+ u64 ipn, int keyid, size_t *prot_len);
u8 * bip_protect_s1g_beacon(const u8 *igtk, size_t igtk_len, const u8 *frame,
size_t len, const u8 *ipn, int keyid, bool bce,
size_t *prot_len);