wlantest: Add test vectors for S1G BIP
- CMAC and GMAC modes - 128-bit and 256-bit modes - normal BIP and BIP using BCE - test vectors with minimum and optional additional header elements in S1G beacon frames - S1G Beacon Compatibility element in some cases, no other beacon body components Signed-off-by: Henry Ptasinski <henry@e78com.com> Signed-off-by: Andrew Pope <andrew.pope@morsemicro.com> Signed-off-by: David Goodall <dave@morsemicro.com>
This commit is contained in:
parent
3fad445496
commit
4e3f6b847a
4 changed files with 890 additions and 0 deletions
|
@ -24,6 +24,13 @@
|
||||||
#define WLAN_FC_ISWEP 0x4000
|
#define WLAN_FC_ISWEP 0x4000
|
||||||
#define WLAN_FC_HTC 0x8000
|
#define WLAN_FC_HTC 0x8000
|
||||||
|
|
||||||
|
#define WLAN_FC_S1G_BEACON_NEXT_TBTT 0x0100
|
||||||
|
#define WLAN_FC_S1G_BEACON_COMP_SSID 0x0200
|
||||||
|
#define WLAN_FC_S1G_BEACON_ANO 0x0400
|
||||||
|
#define WLAN_FC_S1G_BEACON_BSS_BW 0x3800
|
||||||
|
#define WLAN_FC_S1G_BEACON_SECURITY 0x4000
|
||||||
|
#define WLAN_FC_S1G_BEACON_AP_PM 0x8000
|
||||||
|
|
||||||
#define WLAN_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2)
|
#define WLAN_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2)
|
||||||
#define WLAN_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4)
|
#define WLAN_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4)
|
||||||
|
|
||||||
|
@ -36,6 +43,7 @@
|
||||||
#define WLAN_FC_TYPE_MGMT 0
|
#define WLAN_FC_TYPE_MGMT 0
|
||||||
#define WLAN_FC_TYPE_CTRL 1
|
#define WLAN_FC_TYPE_CTRL 1
|
||||||
#define WLAN_FC_TYPE_DATA 2
|
#define WLAN_FC_TYPE_DATA 2
|
||||||
|
#define WLAN_FC_TYPE_EXT 3
|
||||||
|
|
||||||
/* management */
|
/* management */
|
||||||
#define WLAN_FC_STYPE_ASSOC_REQ 0
|
#define WLAN_FC_STYPE_ASSOC_REQ 0
|
||||||
|
@ -77,6 +85,10 @@
|
||||||
#define WLAN_FC_STYPE_QOS_CFPOLL 14
|
#define WLAN_FC_STYPE_QOS_CFPOLL 14
|
||||||
#define WLAN_FC_STYPE_QOS_CFACKPOLL 15
|
#define WLAN_FC_STYPE_QOS_CFACKPOLL 15
|
||||||
|
|
||||||
|
/* extension */
|
||||||
|
#define WLAN_FC_STYPE_DMG_BEACON 0
|
||||||
|
#define WLAN_FC_STYPE_S1G_BEACON 1
|
||||||
|
|
||||||
/* Authentication algorithms */
|
/* Authentication algorithms */
|
||||||
#define WLAN_AUTH_OPEN 0
|
#define WLAN_AUTH_OPEN 0
|
||||||
#define WLAN_AUTH_SHARED_KEY 1
|
#define WLAN_AUTH_SHARED_KEY 1
|
||||||
|
@ -954,6 +966,23 @@ struct ieee80211_hdr {
|
||||||
|
|
||||||
#define IEEE80211_HDRLEN (sizeof(struct ieee80211_hdr))
|
#define IEEE80211_HDRLEN (sizeof(struct ieee80211_hdr))
|
||||||
|
|
||||||
|
struct ieee80211_hdr_s1g_beacon {
|
||||||
|
le16 frame_control;
|
||||||
|
le16 duration_id;
|
||||||
|
u8 sa[6];
|
||||||
|
u8 timestamp[4];
|
||||||
|
u8 change_seq[1];
|
||||||
|
/* followed by:
|
||||||
|
* 'u8 next_tbtt[3];' if the Next TBTT Present field in the
|
||||||
|
* Frame Control field is 1
|
||||||
|
* 'u8 compressed_ssid[4];' if the Compressed SSID Present field in
|
||||||
|
* the Frame Control is 1
|
||||||
|
* 'u8 ano[1];' if the ANO field in the Frame Control field is 1
|
||||||
|
*/
|
||||||
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
|
#define IEEE80211_HDRLEN_S1G_BEACON (sizeof(struct ieee80211_hdr_s1g_beacon))
|
||||||
|
|
||||||
#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4))
|
#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4))
|
||||||
|
|
||||||
struct ieee80211_mgmt {
|
struct ieee80211_mgmt {
|
||||||
|
@ -3007,6 +3036,15 @@ struct ieee80211_neighbor_ap_info {
|
||||||
u8 data[0];
|
u8 data[0];
|
||||||
} STRUCT_PACKED;
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
|
/* S1G Beacon Compatibility element */
|
||||||
|
struct ieee80211_s1g_beacon_compat {
|
||||||
|
u8 element_id;
|
||||||
|
u8 length;
|
||||||
|
le16 compat_info;
|
||||||
|
le16 beacon_interval;
|
||||||
|
le32 tsf_completion;
|
||||||
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
242
wlantest/bip.c
242
wlantest/bip.c
|
@ -67,6 +67,124 @@ u8 * bip_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MME_LEN_LESS_MIC 10
|
||||||
|
#define MIC_ELEM_LEN_LESS_MIC 2
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
u8 *prot, *pos, *buf;
|
||||||
|
u8 mic[16];
|
||||||
|
u16 fc;
|
||||||
|
struct ieee80211_hdr_s1g_beacon *hdr;
|
||||||
|
struct ieee80211_s1g_beacon_compat *bc;
|
||||||
|
size_t plen, mic_len, element_len, buf_len;
|
||||||
|
size_t hdr_add_len = 0, bce_add_len = 0;
|
||||||
|
|
||||||
|
mic_len = igtk_len == 32 ? 16 : 8;
|
||||||
|
if (bce)
|
||||||
|
element_len = MIC_ELEM_LEN_LESS_MIC + mic_len;
|
||||||
|
else
|
||||||
|
element_len = MME_LEN_LESS_MIC + mic_len;
|
||||||
|
|
||||||
|
plen = len + element_len; /* add element length */
|
||||||
|
prot = os_malloc(plen);
|
||||||
|
if (!prot)
|
||||||
|
return NULL;
|
||||||
|
os_memcpy(prot, frame, len);
|
||||||
|
pos = prot + len;
|
||||||
|
|
||||||
|
/* Add MME/MIC element to the end of the frame */
|
||||||
|
if (bce) {
|
||||||
|
bce_add_len = 6; /* AAD increases by 6 bytes for BCE */
|
||||||
|
*pos++ = WLAN_EID_MIC; /* Element ID */
|
||||||
|
*pos++ = element_len - 2; /* Length field */
|
||||||
|
} else {
|
||||||
|
*pos++ = WLAN_EID_MMIE; /* Element ID */
|
||||||
|
*pos++ = element_len - 2; /* Length field */
|
||||||
|
WPA_PUT_LE16(pos, keyid); /* KeyID */
|
||||||
|
pos += 2;
|
||||||
|
os_memcpy(pos, ipn, 6); /* BIPN */
|
||||||
|
pos += 6;
|
||||||
|
}
|
||||||
|
os_memset(pos, 0, mic_len); /* MIC */
|
||||||
|
|
||||||
|
/* Duration (2) and Timestamp (4) are omitted from AAD, BIPN (6) is
|
||||||
|
* added if BCE is used */
|
||||||
|
buf_len = plen - 6 + bce_add_len;
|
||||||
|
buf = os_malloc(buf_len);
|
||||||
|
if (!buf) {
|
||||||
|
os_free(prot);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIP AAD: FC SA ChangeSeq NextTBTT(if present)
|
||||||
|
* CompressedSSID(if present) ANO(if present), BIPN(if using BCE) */
|
||||||
|
hdr = (struct ieee80211_hdr_s1g_beacon *) frame;
|
||||||
|
fc = le_to_host16(hdr->frame_control);
|
||||||
|
if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_EXT ||
|
||||||
|
WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_S1G_BEACON) {
|
||||||
|
wpa_printf(MSG_ERROR, "Frame is not an S1G Beacon");
|
||||||
|
os_free(prot);
|
||||||
|
os_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WPA_PUT_LE16(buf, fc);
|
||||||
|
os_memcpy(buf + 2, hdr->sa, ETH_ALEN);
|
||||||
|
os_memcpy(buf + 8, hdr->change_seq, 1);
|
||||||
|
if (fc & WLAN_FC_S1G_BEACON_NEXT_TBTT)
|
||||||
|
hdr_add_len += 3;
|
||||||
|
if (fc & WLAN_FC_S1G_BEACON_COMP_SSID)
|
||||||
|
hdr_add_len += 4;
|
||||||
|
if (fc & WLAN_FC_S1G_BEACON_ANO)
|
||||||
|
hdr_add_len++;
|
||||||
|
os_memcpy(buf + 9, prot + IEEE80211_HDRLEN_S1G_BEACON, hdr_add_len);
|
||||||
|
if (bce)
|
||||||
|
os_memcpy(buf + 9 + hdr_add_len, ipn, bce_add_len);
|
||||||
|
os_memcpy(buf + 9 + hdr_add_len + bce_add_len,
|
||||||
|
prot + IEEE80211_HDRLEN_S1G_BEACON + hdr_add_len,
|
||||||
|
plen - (IEEE80211_HDRLEN_S1G_BEACON + hdr_add_len));
|
||||||
|
/* The S1G Beacon Compatibility element, when present, is the first
|
||||||
|
* element in the S1G Beacon frame body */
|
||||||
|
if (len >= IEEE80211_HDRLEN_S1G_BEACON + hdr_add_len +
|
||||||
|
sizeof(struct ieee80211_s1g_beacon_compat)) {
|
||||||
|
bc = (struct ieee80211_s1g_beacon_compat *)
|
||||||
|
(buf + 9 + hdr_add_len + bce_add_len);
|
||||||
|
if (bc->element_id == WLAN_EID_S1G_BCN_COMPAT) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"S1G Beacon Compatibility element found, masking TSF Completion field");
|
||||||
|
os_memset(&bc->tsf_completion, 0,
|
||||||
|
sizeof(bc->tsf_completion));
|
||||||
|
if (bce && keyid - 6 != (bc->compat_info & 0x80) >> 7) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Key ID does not match BIGTK Key ID Index in S1G Beacon Compatibility element");
|
||||||
|
os_free(prot);
|
||||||
|
os_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "S1G BIP-CMAC AAD|Body(masked)", buf, buf_len);
|
||||||
|
|
||||||
|
/* MIC = L(AES-128-CMAC(AAD || Frame Body), 0, 64) */
|
||||||
|
if (omac1_aes_128(igtk, buf, buf_len, mic) < 0) {
|
||||||
|
os_free(prot);
|
||||||
|
os_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
os_free(buf);
|
||||||
|
|
||||||
|
os_memcpy(pos, mic, mic_len);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "S1G BIP-CMAC MIC", pos, mic_len);
|
||||||
|
|
||||||
|
*prot_len = plen;
|
||||||
|
return prot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
u8 * bip_gmac_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
u8 * bip_gmac_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
||||||
u8 *ipn, int keyid, size_t *prot_len)
|
u8 *ipn, int keyid, size_t *prot_len)
|
||||||
{
|
{
|
||||||
|
@ -131,3 +249,127 @@ u8 * bip_gmac_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
||||||
*prot_len = plen;
|
*prot_len = plen;
|
||||||
return prot;
|
return prot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8 * bip_gmac_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)
|
||||||
|
{
|
||||||
|
u8 *prot, *pos, *buf;
|
||||||
|
u16 fc;
|
||||||
|
struct ieee80211_hdr_s1g_beacon *hdr;
|
||||||
|
struct ieee80211_s1g_beacon_compat *bc;
|
||||||
|
size_t plen, mic_len, element_len, buf_len;
|
||||||
|
size_t hdr_add_len = 0, bce_add_len = 0;
|
||||||
|
u8 nonce[12], *npos;
|
||||||
|
|
||||||
|
mic_len = 16;
|
||||||
|
if (bce)
|
||||||
|
element_len = MIC_ELEM_LEN_LESS_MIC + mic_len;
|
||||||
|
else
|
||||||
|
element_len = MME_LEN_LESS_MIC + mic_len;
|
||||||
|
|
||||||
|
plen = len + element_len; /* add element length */
|
||||||
|
prot = os_malloc(plen);
|
||||||
|
if (!prot)
|
||||||
|
return NULL;
|
||||||
|
os_memcpy(prot, frame, len);
|
||||||
|
pos = prot + len;
|
||||||
|
/* Add MME/MIC element to the end of the frame */
|
||||||
|
if (bce) {
|
||||||
|
bce_add_len = 6;
|
||||||
|
*pos++ = WLAN_EID_MIC; /* Element ID */
|
||||||
|
*pos++ = element_len - 2; /* Length field */
|
||||||
|
} else {
|
||||||
|
*pos++ = WLAN_EID_MMIE; /* Element ID */
|
||||||
|
*pos++ = element_len - 2; /* Length field */
|
||||||
|
WPA_PUT_LE16(pos, keyid); /* KeyID */
|
||||||
|
pos += 2;
|
||||||
|
os_memcpy(pos, ipn, 6); /* BIPN */
|
||||||
|
pos += 6;
|
||||||
|
}
|
||||||
|
os_memset(pos, 0, mic_len); /* MIC */
|
||||||
|
|
||||||
|
/* Duration (2) and Timestamp (4) are omitted from AAD,
|
||||||
|
* BIPN (6) is added if BCE is used */
|
||||||
|
buf_len = plen - 6 + bce_add_len;
|
||||||
|
buf = os_malloc(buf_len);
|
||||||
|
if (!buf) {
|
||||||
|
os_free(prot);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIP AAD: FC SA ChangeSeq NextTBTT(if present)
|
||||||
|
* CompressedSSID(if present) ANO(if present) */
|
||||||
|
hdr = (struct ieee80211_hdr_s1g_beacon *) frame;
|
||||||
|
fc = le_to_host16(hdr->frame_control);
|
||||||
|
if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_EXT ||
|
||||||
|
WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_S1G_BEACON) {
|
||||||
|
wpa_printf(MSG_ERROR, "Frame is not an S1G Beacon");
|
||||||
|
os_free(prot);
|
||||||
|
os_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WPA_PUT_LE16(buf, fc);
|
||||||
|
os_memcpy(buf + 2, hdr->sa, ETH_ALEN);
|
||||||
|
os_memcpy(buf + 8, hdr->change_seq, 1);
|
||||||
|
if (fc & WLAN_FC_S1G_BEACON_NEXT_TBTT)
|
||||||
|
hdr_add_len += 3;
|
||||||
|
if (fc & WLAN_FC_S1G_BEACON_COMP_SSID)
|
||||||
|
hdr_add_len += 4;
|
||||||
|
if (fc & WLAN_FC_S1G_BEACON_ANO)
|
||||||
|
hdr_add_len++;
|
||||||
|
os_memcpy(buf + 9, prot + IEEE80211_HDRLEN_S1G_BEACON, hdr_add_len);
|
||||||
|
if (bce)
|
||||||
|
os_memcpy(buf + 9 + hdr_add_len, ipn, bce_add_len);
|
||||||
|
os_memcpy(buf + 9 + hdr_add_len + bce_add_len,
|
||||||
|
prot + IEEE80211_HDRLEN_S1G_BEACON + hdr_add_len,
|
||||||
|
plen - (IEEE80211_HDRLEN_S1G_BEACON + hdr_add_len));
|
||||||
|
/* The S1G Beacon Compatibility element, when present, is the first
|
||||||
|
* element in the S1G Beacon frame body */
|
||||||
|
if (len >= IEEE80211_HDRLEN_S1G_BEACON + hdr_add_len +
|
||||||
|
sizeof(struct ieee80211_s1g_beacon_compat)) {
|
||||||
|
bc = (struct ieee80211_s1g_beacon_compat *)
|
||||||
|
(buf + 9 + hdr_add_len + bce_add_len);
|
||||||
|
if (bc->element_id == WLAN_EID_S1G_BCN_COMPAT) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"S1G Beacon Compatibility element found, masking TSF Completion field");
|
||||||
|
os_memset(&bc->tsf_completion, 0,
|
||||||
|
sizeof(bc->tsf_completion));
|
||||||
|
if (bce && keyid - 6 != (bc->compat_info & 0x80) >> 7) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Key ID does not match BIGTK Key ID Index in S1G Beacon Compatibility element");
|
||||||
|
os_free(prot);
|
||||||
|
os_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "S1G BIP-GMAC AAD|Body(masked)", buf, buf_len);
|
||||||
|
|
||||||
|
/* Nonce: SA | IPN */
|
||||||
|
os_memcpy(nonce, hdr->sa, ETH_ALEN);
|
||||||
|
npos = nonce + ETH_ALEN;
|
||||||
|
*npos++ = ipn[5];
|
||||||
|
*npos++ = ipn[4];
|
||||||
|
*npos++ = ipn[3];
|
||||||
|
*npos++ = ipn[2];
|
||||||
|
*npos++ = ipn[1];
|
||||||
|
*npos++ = ipn[0];
|
||||||
|
wpa_hexdump(MSG_EXCESSIVE, "S1G BIP-GMAC Nonce", nonce, sizeof(nonce));
|
||||||
|
|
||||||
|
/* MIC = AES-GMAC(AAD || Frame Body) */
|
||||||
|
if (aes_gmac(igtk, igtk_len, nonce, sizeof(nonce), buf, buf_len, pos) <
|
||||||
|
0) {
|
||||||
|
os_free(prot);
|
||||||
|
os_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
os_free(buf);
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_DEBUG, "S1G BIP-GMAC MIC", pos, 16);
|
||||||
|
|
||||||
|
*prot_len = plen;
|
||||||
|
return prot;
|
||||||
|
}
|
||||||
|
|
|
@ -381,6 +381,166 @@ static void test_vector_bip(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_vector_bip_s1g_beacon(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
|
||||||
|
* FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
|
||||||
|
* pm 1
|
||||||
|
* S1G Beacon, no extra header fields, S1G Beacon Compatibility element
|
||||||
|
*/
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
|
||||||
|
0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128, no optional header fields, S1G Beacon Compatibility element in body\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
|
||||||
|
ipn, 7, false, &prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-CMAC-128");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
os_free(prot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_vector_bip_s1g_beacon_ext(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
|
||||||
|
* FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
|
||||||
|
* pm 1
|
||||||
|
* S1G Beacon, all possible extra header fields, no body fields */
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128, all optional header fields, no body elements\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
|
||||||
|
ipn, 6, false, &prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-CMAC-128");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
os_free(prot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_vector_bip_s1g_beacon_bce(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
|
||||||
|
* FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
|
||||||
|
* pm 1
|
||||||
|
* S1G Beacon, no extra header fields, S1G Beacon Compatibility element
|
||||||
|
*/
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
|
||||||
|
0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128 using BCE, no optional header fields, S1G Beacon Compatibility element in body\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
|
||||||
|
ipn, 7, true, &prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP using BCE-CMAC-128");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
os_free(prot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_vector_bip_s1g_beacon_bce_ext(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
/* FC 2 Dur 2 SA 6 Time 4 CS 1 Next 0/3 Comp 0/4 ANO 0/1
|
||||||
|
* FC: prot 2 type 2 subtype 4 next 1 comp 1 ano 1 bss bw 3 sec 1 ap
|
||||||
|
* pm 1
|
||||||
|
* S1G Beacon, all possible extra header fields, no body fields */
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-CMAC-128 using BCE, all optional header fields, no body elements\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_protect_s1g_beacon(igtk, sizeof(igtk), frame, sizeof(frame),
|
||||||
|
ipn, 6, true, &prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP using BCE-CMAC-128");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
os_free(prot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void test_vector_ccmp_mgmt(void)
|
static void test_vector_ccmp_mgmt(void)
|
||||||
{
|
{
|
||||||
u8 tk[] = { 0x66, 0xed, 0x21, 0x04, 0x2f, 0x9f, 0x26, 0xd7,
|
u8 tk[] = { 0x66, 0xed, 0x21, 0x04, 0x2f, 0x9f, 0x26, 0xd7,
|
||||||
|
@ -863,6 +1023,218 @@ static int test_vector_bip_gmac_128(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_128_s1g_beacon(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78, 0x4c, 0x18, 0x06, 0x00, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xa5, 0xb2, 0x42, 0xc1, 0xc1,
|
||||||
|
0x1e, 0xab, 0x10, 0xc5, 0xa4, 0xe8, 0xb9, 0x53,
|
||||||
|
0x66, 0x19, 0x38
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128, no optional header fields, S1G Beacon Compatibility element in body\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 6, false,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-GMAC-128");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-128 test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_128_s1g_beacon_ext(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
|
||||||
|
0x18, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x39, 0xd0, 0x0c, 0xc2, 0xee, 0xd7, 0x4c,
|
||||||
|
0x2a, 0xb7, 0x41, 0xcc, 0xf8, 0x08, 0x9b, 0x5b,
|
||||||
|
0x08
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128, all optional header fields, no body elements\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 7, false,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-GMAC-128");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-128 test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_128_s1g_beacon_bce(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78, 0x8c, 0x10, 0xa2, 0x5b, 0x7e, 0x67, 0x76,
|
||||||
|
0xf0, 0x11, 0x57, 0xa4, 0xfb, 0x4a, 0x2d, 0x66,
|
||||||
|
0xd0, 0x17, 0x66
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128 using BCE, no optional header fields, S1G Beacon Compatibility element in body\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 6, true,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-GMAC-128 using BCE");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-128 using BCE test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_128_s1g_beacon_bce_ext(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
|
||||||
|
0x10, 0x86, 0xdd, 0xb6, 0xc0, 0x56, 0x21, 0x30,
|
||||||
|
0x9d, 0x3e, 0xbd, 0x25, 0x96, 0x67, 0x5b, 0xdd,
|
||||||
|
0xc3
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-128 using BCE, all optional header fields, no body elements\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 7, true,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-GMAC-128 using BCE");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-128 using BCE test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int test_vector_bip_gmac_256(void)
|
static int test_vector_bip_gmac_256(void)
|
||||||
{
|
{
|
||||||
u8 igtk[] = {
|
u8 igtk[] = {
|
||||||
|
@ -915,6 +1287,226 @@ static int test_vector_bip_gmac_256(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_256_s1g_beacon(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
|
||||||
|
0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
|
||||||
|
0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78, 0x4c, 0x18, 0x07, 0x00, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x33, 0xa2, 0x6f, 0xc6, 0x7e,
|
||||||
|
0xbf, 0xfd, 0xa0, 0xac, 0x9b, 0x29, 0xaa, 0x70,
|
||||||
|
0xda, 0x3f, 0x51
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256, no optional header fields, S1G Beacon Compatibility element in body\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 7, false,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-GMAC-256");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-256 test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_256_s1g_beacon_ext(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
|
||||||
|
0x18, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0a, 0x5f, 0xa0, 0xf4, 0x71, 0xdf, 0x73,
|
||||||
|
0x9e, 0x61, 0x4d, 0xcf, 0x5d, 0xbb, 0x36, 0xf9,
|
||||||
|
0x65
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256, all optional header fields, no body elements\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 6, false,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1B Beacon frame with BIP-GMAC-256");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-256 test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_256_s1g_beacon_bce(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5,
|
||||||
|
0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5,
|
||||||
|
0x08, 0x80, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56,
|
||||||
|
0x78, 0x8c, 0x10, 0xf8, 0x76, 0x22, 0x80, 0x3d,
|
||||||
|
0x9c, 0x22, 0x8a, 0xcb, 0x3c, 0x55, 0x8a, 0x33,
|
||||||
|
0x2e, 0x94, 0x13
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256 using BCE, no optional header fields, S1G Beacon Compatibility element in body\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 7, true,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1G Beacon frame with BIP-GMAC-256 using BCE");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-256 using BCE test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_vector_bip_gmac_256_s1g_beacon_bce_ext(void)
|
||||||
|
{
|
||||||
|
const u8 igtk[] = {
|
||||||
|
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
|
||||||
|
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf,
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||||
|
};
|
||||||
|
const u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
const u8 frame[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const u8 res[] = {
|
||||||
|
0x1c, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
|
||||||
|
0x10, 0x3c, 0x80, 0x49, 0xbe, 0x8c, 0x23, 0x34,
|
||||||
|
0x1f, 0x5c, 0x2f, 0x9c, 0xd6, 0x03, 0xe3, 0x7a,
|
||||||
|
0x5b
|
||||||
|
};
|
||||||
|
u8 *prot;
|
||||||
|
size_t prot_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"\nIEEE P802.11REVme/D4.0, J.9.2 S1G Beacon frame with BIP-GMAC-256 using BCE, all optional header fields, no body elements\n");
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "IGTK", igtk, sizeof(igtk));
|
||||||
|
wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
|
||||||
|
wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
|
||||||
|
|
||||||
|
prot = bip_gmac_protect_s1g_beacon(igtk, sizeof(igtk), frame,
|
||||||
|
sizeof(frame), ipn, 6, true,
|
||||||
|
&prot_len);
|
||||||
|
if (!prot) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"Failed to protect S1B Beacon frame with BIP-GMAC-256 using BCE");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
|
||||||
|
if (prot_len != sizeof(res) || os_memcmp(res, prot, prot_len) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"S1G Beacon frame with BIP-GMAC-256 using BCE test vector mismatch");
|
||||||
|
err++;
|
||||||
|
}
|
||||||
|
os_free(prot);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
@ -929,12 +1521,24 @@ int main(int argc, char *argv[])
|
||||||
test_vector_ccmp();
|
test_vector_ccmp();
|
||||||
test_vector_ccmp_pv1();
|
test_vector_ccmp_pv1();
|
||||||
test_vector_bip();
|
test_vector_bip();
|
||||||
|
test_vector_bip_s1g_beacon();
|
||||||
|
test_vector_bip_s1g_beacon_ext();
|
||||||
|
test_vector_bip_s1g_beacon_bce();
|
||||||
|
test_vector_bip_s1g_beacon_bce_ext();
|
||||||
test_vector_ccmp_mgmt();
|
test_vector_ccmp_mgmt();
|
||||||
errors += test_vector_gcmp();
|
errors += test_vector_gcmp();
|
||||||
errors += test_vector_gcmp_256();
|
errors += test_vector_gcmp_256();
|
||||||
errors += test_vector_ccmp_256();
|
errors += test_vector_ccmp_256();
|
||||||
errors += test_vector_bip_gmac_128();
|
errors += test_vector_bip_gmac_128();
|
||||||
|
errors += test_vector_bip_gmac_128_s1g_beacon();
|
||||||
|
errors += test_vector_bip_gmac_128_s1g_beacon_ext();
|
||||||
|
errors += test_vector_bip_gmac_128_s1g_beacon_bce();
|
||||||
|
errors += test_vector_bip_gmac_128_s1g_beacon_bce_ext();
|
||||||
errors += test_vector_bip_gmac_256();
|
errors += test_vector_bip_gmac_256();
|
||||||
|
errors += test_vector_bip_gmac_256_s1g_beacon();
|
||||||
|
errors += test_vector_bip_gmac_256_s1g_beacon_ext();
|
||||||
|
errors += test_vector_bip_gmac_256_s1g_beacon_bce();
|
||||||
|
errors += test_vector_bip_gmac_256_s1g_beacon_bce_ext();
|
||||||
|
|
||||||
if (errors)
|
if (errors)
|
||||||
wpa_printf(MSG_INFO, "One or more test vectors failed");
|
wpa_printf(MSG_INFO, "One or more test vectors failed");
|
||||||
|
|
|
@ -353,8 +353,14 @@ u8 * wep_decrypt(struct wlantest *wt, const struct ieee80211_hdr *hdr,
|
||||||
|
|
||||||
u8 * bip_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
u8 * bip_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
||||||
u8 *ipn, int keyid, size_t *prot_len);
|
u8 *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);
|
||||||
u8 * bip_gmac_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
u8 * bip_gmac_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
|
||||||
u8 *ipn, int keyid, size_t *prot_len);
|
u8 *ipn, int keyid, size_t *prot_len);
|
||||||
|
u8 * bip_gmac_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);
|
||||||
|
|
||||||
u8 * gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr,
|
u8 * gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr,
|
||||||
const u8 *a1, const u8 *a2, const u8 *a3,
|
const u8 *a1, const u8 *a2, const u8 *a3,
|
||||||
|
|
Loading…
Reference in a new issue