hostapd/wlantest/test_vectors.c
Jouni Malinen 0187c41d88 Declare wpa_debug_* variables in src/utils/wpa_debug.h
These were somewhat more hidden to avoid direct use, but there are now
numerous places where these are needed and more justification to make
the extern int declarations available from wpa_debug.h. In addition,
this avoids some warnings from sparse.

Signed-hostap: Jouni Malinen <j@w1.fi>
2013-12-31 19:29:52 +02:00

727 lines
22 KiB
C

/*
* test_vectors - IEEE 802.11 test vector generator
* Copyright (c) 2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/includes.h"
#include "utils/common.h"
#include "utils/eloop.h"
#include "wlantest.h"
static void test_vector_tkip(void)
{
u8 tk[] = {
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,
0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34
};
u8 pn[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
u8 frame[] = {
0x08, 0x42, 0x2c, 0x00, 0x02, 0x03, 0x04, 0x05,
0x06, 0x08, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xd0, 0x02,
/* 0x00, 0x20, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, */
0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00,
0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
0x40, 0x01, 0xa5, 0x55, 0xc0, 0xa8, 0x0a, 0x02,
0xc0, 0xa8, 0x0a, 0x01, 0x08, 0x00, 0x3a, 0xb0,
0x00, 0x00, 0x00, 0x00, 0xcd, 0x4c, 0x05, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37,
/* 0x68, 0x81, 0xa3, 0xf3, 0xd6, 0x48, 0xd0, 0x3c */
};
u8 *enc, *plain;
size_t enc_len, plain_len;
wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.6.3 TKIP test "
"vector\n");
wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
wpa_hexdump(MSG_INFO, "Plaintext MPDU", frame, sizeof(frame));
enc = tkip_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
if (enc == NULL) {
wpa_printf(MSG_ERROR, "Failed to encrypt TKIP frame");
return;
}
wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
wpa_debug_level = MSG_INFO;
plain = tkip_decrypt(tk, (const struct ieee80211_hdr *) enc,
enc + 24, enc_len - 24, &plain_len);
wpa_debug_level = MSG_EXCESSIVE;
os_free(enc);
if (plain == NULL) {
wpa_printf(MSG_ERROR, "Failed to decrypt TKIP frame");
return;
}
if (plain_len != sizeof(frame) - 24 ||
os_memcmp(plain, frame + 24, plain_len) != 0) {
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
plain, plain_len);
}
os_free(plain);
}
static void test_vector_ccmp(void)
{
u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f };
u8 pn[] = { 0xB5, 0x03, 0x97, 0x76, 0xE7, 0x0C };
u8 frame[] = {
0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
0x7e, 0x78, 0xa0, 0x50
};
u8 *enc, *plain;
size_t enc_len, plain_len;
u8 fcs[4];
wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.6.4 CCMP test "
"vector\n");
wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);
enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
if (enc == NULL) {
wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
return;
}
wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
WPA_PUT_LE32(fcs, crc32(enc, enc_len));
wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
wpa_debug_level = MSG_INFO;
plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
enc + 24, enc_len - 24, &plain_len);
wpa_debug_level = MSG_EXCESSIVE;
os_free(enc);
if (plain == NULL) {
wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
return;
}
if (plain_len != sizeof(frame) - 24 ||
os_memcmp(plain, frame + 24, plain_len) != 0) {
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
plain, plain_len);
}
os_free(plain);
}
static void test_vector_bip(void)
{
u8 igtk[] = {
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
};
u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
u8 frame[] = {
0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
0x02, 0x00
};
u8 *prot;
size_t prot_len;
wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.9.1 BIP with broadcast "
"Deauthentication frame\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(igtk, frame, sizeof(frame), ipn, 4, &prot_len);
if (prot == NULL) {
wpa_printf(MSG_ERROR, "Failed to protect BIP frame");
return;
}
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
os_free(prot);
}
static void test_vector_ccmp_mgmt(void)
{
u8 tk[] = { 0x66, 0xed, 0x21, 0x04, 0x2f, 0x9f, 0x26, 0xd7,
0x11, 0x57, 0x06, 0xe4, 0x04, 0x14, 0xcf, 0x2e };
u8 pn[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
u8 frame[] = {
0xc0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
0x02, 0x00
};
u8 *enc, *plain;
size_t enc_len, plain_len;
wpa_printf(MSG_INFO, "\nIEEE Std 802.11-2012, M.9.2 CCMP with unicast "
"Deauthentication frame\n");
wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);
enc = ccmp_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0, &enc_len);
if (enc == NULL) {
wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
return;
}
wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
wpa_debug_level = MSG_INFO;
plain = ccmp_decrypt(tk, (const struct ieee80211_hdr *) enc,
enc + 24, enc_len - 24, &plain_len);
wpa_debug_level = MSG_EXCESSIVE;
os_free(enc);
if (plain == NULL) {
wpa_printf(MSG_ERROR, "Failed to decrypt CCMP frame");
return;
}
if (plain_len != sizeof(frame) - 24 ||
os_memcmp(plain, frame + 24, plain_len) != 0) {
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
plain, plain_len);
}
os_free(plain);
}
struct gcmp_test {
u8 tk[16];
u8 pn[6];
u8 frame[300];
size_t hdr_len;
size_t payload_len;
u8 mic[16];
u8 encr[300];
};
static struct gcmp_test gcmp_vectors[] =
{
{
.tk = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
.pn = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
.frame = {
0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
.hdr_len = 24,
.payload_len = 256,
.mic = {
0x80, 0xCB, 0x06, 0x62, 0xEA, 0x71, 0xAB, 0xFD,
0x9F, 0x04, 0xC7, 0xF8, 0x72, 0xF5, 0x80, 0x90 },
.encr = {
0x5F, 0x55, 0x78, 0xC1, 0x8F, 0x13, 0x7A, 0xD2,
0x79, 0xBF, 0x3F, 0x2B, 0x24, 0xC7, 0xBD, 0x8F,
0x27, 0x7A, 0x1B, 0xE6, 0x77, 0x0D, 0xA1, 0xD9,
0x8B, 0x70, 0xC6, 0xD2, 0x8A, 0xE0, 0x1C, 0x55,
0x9E, 0xCB, 0xA6, 0xA0, 0x1D, 0xB0, 0x67, 0xC5,
0xA2, 0x7E, 0x4D, 0xB0, 0x8C, 0xDA, 0xDC, 0x77,
0x52, 0xAD, 0x63, 0x7E, 0xAF, 0x0A, 0x18, 0xED,
0x13, 0xFB, 0xAA, 0x14, 0x3B, 0xAF, 0xEF, 0x18,
0xF8, 0xFB, 0xCE, 0x4C, 0x65, 0xE8, 0x6B, 0xD0,
0x2A, 0x87, 0xB6, 0x01, 0xB7, 0xEA, 0xB9, 0x3F,
0x2B, 0xBC, 0x87, 0x4C, 0x8A, 0x71, 0x05, 0x80,
0xF5, 0x02, 0x34, 0x1A, 0x6A, 0x53, 0x39, 0x31,
0x43, 0xDE, 0x4C, 0x9E, 0xC6, 0xA2, 0x86, 0xF1,
0x25, 0x71, 0x83, 0x78, 0xAE, 0xDC, 0x84, 0xEB,
0xA2, 0xB3, 0x0F, 0x5C, 0x28, 0xBB, 0x5D, 0x75,
0xC6, 0xB0, 0x25, 0x46, 0x6D, 0x06, 0x51, 0xC7,
0x22, 0xDC, 0x71, 0x15, 0x1F, 0x21, 0x2D, 0x68,
0x87, 0x82, 0x8A, 0x03, 0x82, 0xE9, 0x28, 0x8A,
0x7F, 0x43, 0xD5, 0x2B, 0x7D, 0x25, 0x08, 0x61,
0x57, 0x64, 0x69, 0x54, 0xBB, 0x43, 0xB5, 0x7E,
0xA5, 0x87, 0xA0, 0x25, 0xF4, 0x0C, 0xE7, 0x45,
0x11, 0xE4, 0xDD, 0x22, 0x85, 0xB4, 0x0B, 0xA3,
0xF3, 0xB9, 0x62, 0x62, 0xCB, 0xC2, 0x8C, 0x6A,
0xA7, 0xBE, 0x44, 0x3E, 0x7B, 0x41, 0xE1, 0xEB,
0xFF, 0x52, 0x48, 0x57, 0xA6, 0x81, 0x68, 0x97,
0x75, 0x01, 0x15, 0xB0, 0x23, 0x1A, 0xB7, 0xC2,
0x84, 0x72, 0xC0, 0x6D, 0xD0, 0xB4, 0x9B, 0xE9,
0xF3, 0x69, 0xA8, 0xC3, 0x9C, 0xCD, 0x0D, 0xB7,
0x98, 0x35, 0x10, 0xE1, 0xAE, 0x8F, 0x05, 0xD7,
0x75, 0x45, 0xE0, 0x23, 0x5C, 0xDB, 0xD6, 0x12,
0xF3, 0x15, 0x07, 0x54, 0xCE, 0xE5, 0xCE, 0x6A,
0x12, 0x25, 0xD9, 0x95, 0x25, 0x02, 0x6F, 0x74
}
},
{
.tk = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f },
.pn = { 0x00, 0x89, 0x5F, 0x5F, 0x2B, 0x08 },
.frame = {
0x88, 0x48, 0x0b, 0x00, 0x0f, 0xd2, 0xe1, 0x28,
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0x80, 0x33,
0x03, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
},
.hdr_len = 26,
.payload_len = 40,
.mic = {
0xde, 0xf6, 0x19, 0xc2, 0xa3, 0x74, 0xb6, 0xdf,
0x66, 0xff, 0xa5, 0x3b, 0x6c, 0x69, 0xd7, 0x9e },
.encr = {
0x60, 0xe9, 0x70, 0x0c, 0xc4, 0xd4, 0x0a, 0xc6,
0xd2, 0x88, 0xb2, 0x01, 0xc3, 0x8f, 0x5b, 0xf0,
0x8b, 0x80, 0x74, 0x42, 0x64, 0x0a, 0x15, 0x96,
0xe5, 0xdb, 0xda, 0xd4, 0x1d, 0x1f, 0x36, 0x23,
0xf4, 0x5d, 0x7a, 0x12, 0xdb, 0x7a, 0xfb, 0x23
}
}
};
static int run_gcmp(int idx, struct gcmp_test *vector)
{
u8 *enc, *plain;
size_t enc_len, plain_len;
u8 fcs[4];
int err = 0;
wpa_printf(MSG_INFO,
"\nIEEE Std 802.11ad-2012, M.11.1 GCMP test mpdu #%d\n",
idx);
wpa_hexdump(MSG_INFO, "TK", vector->tk, sizeof(vector->tk));
wpa_hexdump(MSG_INFO, "PN", vector->pn, sizeof(vector->pn));
wpa_hexdump(MSG_INFO, "802.11 Header", vector->frame, vector->hdr_len);
wpa_hexdump(MSG_INFO, "Plaintext Data",
vector->frame + vector->hdr_len,
vector->payload_len);
enc = gcmp_encrypt(vector->tk, sizeof(vector->tk),
vector->frame,
vector->hdr_len + vector->payload_len,
vector->hdr_len,
vector->hdr_len == 26 ?
vector->frame + vector->hdr_len - 2 : NULL,
vector->pn, 0, &enc_len);
if (enc == NULL) {
wpa_printf(MSG_ERROR, "Failed to encrypt GCMP frame");
return 1;
}
wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
if (os_memcmp(vector->encr, enc + vector->hdr_len + 8,
vector->payload_len) != 0) {
wpa_printf(MSG_ERROR, "GCMP test mpdu #%d enctypted data mismatch",
idx);
err++;
}
if (os_memcmp(vector->mic, enc + enc_len - sizeof(vector->mic),
sizeof(vector->mic)) != 0) {
wpa_printf(MSG_ERROR, "GCMP test mpdu #%d MIC mismatch", idx);
err++;
}
WPA_PUT_LE32(fcs, crc32(enc, enc_len));
wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
wpa_debug_level = MSG_INFO;
plain = gcmp_decrypt(vector->tk, sizeof(vector->tk),
(const struct ieee80211_hdr *) enc,
enc + vector->hdr_len,
enc_len - vector->hdr_len, &plain_len);
wpa_debug_level = MSG_EXCESSIVE;
os_free(enc);
if (plain == NULL) {
wpa_printf(MSG_ERROR, "Failed to decrypt GCMP frame");
return 1;
}
if (plain_len != vector->payload_len ||
os_memcmp(plain, vector->frame + vector->hdr_len, plain_len) != 0) {
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
plain, plain_len);
err++;
}
os_free(plain);
return err;
}
static int test_vector_gcmp(void)
{
int err = 0;
int i;
for (i = 0; i < ARRAY_SIZE(gcmp_vectors); i++) {
if (run_gcmp(i + 1, &gcmp_vectors[i]))
err++;
}
return err;
}
static int test_vector_gcmp_256(void)
{
u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
u8 pn[] = {
0x00, 0x89, 0x5F, 0x5F, 0x2B, 0x08
};
u8 frame[] = {
0x88, 0x48, 0x0b, 0x00, 0x0f, 0xd2, 0xe1, 0x28,
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0x80, 0x33,
0x03, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x26, 0x27
};
u8 encr[] = {
0x88, 0x48, 0x0b, 0x00, 0x0f, 0xd2, 0xe1, 0x28,
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0x80, 0x33,
0x03, 0x00, 0x08, 0x2b, 0x00, 0x20, 0x5f, 0x5f,
0x89, 0x00, 0x65, 0x83, 0x43, 0xc8, 0xb1, 0x44,
0x47, 0xd9, 0x21, 0x1d, 0xef, 0xd4, 0x6a, 0xd8,
0x9c, 0x71, 0x0c, 0x6f, 0xc3, 0x33, 0x33, 0x23,
0x6e, 0x39, 0x97, 0xb9, 0x17, 0x6a, 0x5a, 0x8b,
0xe7, 0x79, 0xb2, 0x12, 0x66, 0x55, 0x5e, 0x70,
0xad, 0x79, 0x11, 0x43, 0x16, 0x85, 0x90, 0x95,
0x47, 0x3d, 0x5b, 0x1b, 0xd5, 0x96, 0xb3, 0xde,
0xa3, 0xbf
};
u8 *enc, *plain;
size_t enc_len, plain_len;
u8 fcs[4];
int err = 0;
wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.11.1 GCMP-256 test vector\n");
wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
wpa_hexdump(MSG_INFO, "802.11 Header", frame, 26);
wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 26, sizeof(frame) - 26);
enc = gcmp_encrypt(tk, sizeof(tk), frame, sizeof(frame), 26, frame + 24,
pn, 0, &enc_len);
if (enc == NULL) {
wpa_printf(MSG_ERROR, "Failed to encrypt GCMP frame");
return 1;
}
wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
if (enc_len != sizeof(encr) || os_memcmp(enc, encr, enc_len) != 0) {
wpa_printf(MSG_ERROR, "GCMP-256 test vector mismatch");
err++;
}
WPA_PUT_LE32(fcs, crc32(enc, enc_len));
wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
wpa_debug_level = MSG_INFO;
plain = gcmp_decrypt(tk, sizeof(tk), (const struct ieee80211_hdr *) enc,
enc + 26, enc_len - 26, &plain_len);
wpa_debug_level = MSG_EXCESSIVE;
os_free(enc);
if (plain == NULL) {
wpa_printf(MSG_ERROR, "Failed to decrypt GCMP frame");
return 1;
}
if (plain_len != sizeof(frame) - 26 ||
os_memcmp(plain, frame + 26, plain_len) != 0) {
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
plain, plain_len);
err++;
}
os_free(plain);
return err;
}
static int test_vector_ccmp_256(void)
{
u8 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
u8 pn[] = { 0xB5, 0x03, 0x97, 0x76, 0xE7, 0x0C };
u8 frame[] = {
0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
0x7e, 0x78, 0xa0, 0x50
};
u8 encr[] = {
0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
0x0c, 0xe7, 0x00, 0x20, 0x76, 0x97, 0x03, 0xb5,
0x6d, 0x15, 0x5d, 0x88, 0x32, 0x66, 0x82, 0x56,
0xd6, 0xa9, 0x2b, 0x78, 0xe1, 0x1d, 0x8e, 0x54,
0x49, 0x5d, 0xd1, 0x74, 0x80, 0xaa, 0x56, 0xc9,
0x49, 0x2e, 0x88, 0x2b, 0x97, 0x64, 0x2f, 0x80,
0xd5, 0x0f, 0xe9, 0x7b
};
u8 *enc, *plain;
size_t enc_len, plain_len;
u8 fcs[4];
int err = 0;
wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.6.4 CCMP-256 test vector\n");
wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
wpa_hexdump(MSG_INFO, "802.11 Header", frame, 24);
wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 24, sizeof(frame) - 24);
enc = ccmp_256_encrypt(tk, frame, sizeof(frame), 24, NULL, pn, 0,
&enc_len);
if (enc == NULL) {
wpa_printf(MSG_ERROR, "Failed to encrypt CCMP frame");
return 1;
}
wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
if (enc_len != sizeof(encr) || os_memcmp(enc, encr, enc_len) != 0) {
wpa_printf(MSG_ERROR, "CCMP-256 test vector mismatch");
err++;
}
WPA_PUT_LE32(fcs, crc32(enc, enc_len));
wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
wpa_debug_level = MSG_INFO;
plain = ccmp_256_decrypt(tk, (const struct ieee80211_hdr *) enc,
enc + 24, enc_len - 24, &plain_len);
wpa_debug_level = MSG_EXCESSIVE;
os_free(enc);
if (plain == NULL) {
wpa_printf(MSG_ERROR, "Failed to decrypt CCMP-256 frame");
return 1;
}
if (plain_len != sizeof(frame) - 24 ||
os_memcmp(plain, frame + 24, plain_len) != 0) {
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
plain, plain_len);
err++;
}
os_free(plain);
return err;
}
static int test_vector_bip_gmac_128(void)
{
u8 igtk[] = {
0x4e, 0xa9, 0x54, 0x3e, 0x09, 0xcf, 0x2b, 0x1e,
0xca, 0x66, 0xff, 0xc5, 0x8b, 0xde, 0xcb, 0xcf
};
u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
u8 frame[] = {
0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
0x02, 0x00
};
u8 res[] = {
0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
0x02, 0x00, 0x4c, 0x18, 0x04, 0x00, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0xd8, 0x62, 0xfb,
0x0f, 0x33, 0x38, 0xdd, 0x33, 0x86, 0xc8, 0x97,
0xe2, 0xed, 0x05, 0x3d
};
u8 *prot;
size_t prot_len;
int err = 0;
wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.9.1 BIP-GMAC-128 with broadcast "
"Deauthentication frame\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(igtk, sizeof(igtk), frame, sizeof(frame),
ipn, 4, &prot_len);
if (prot == NULL) {
wpa_printf(MSG_ERROR, "Failed to protect BIP-GMAC-128 frame");
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, "BIP-GMAC-128 test vector mismatch");
err++;
}
os_free(prot);
return err;
}
static int test_vector_bip_gmac_256(void)
{
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
};
u8 ipn[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 };
u8 frame[] = {
0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
0x02, 0x00
};
u8 res[] = {
0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
0x02, 0x00, 0x4c, 0x18, 0x04, 0x00, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x23, 0xbe, 0x59, 0xdc,
0xc7, 0x02, 0x2e, 0xe3, 0x83, 0x62, 0x7e, 0xbb,
0x10, 0x17, 0xdd, 0xfc
};
u8 *prot;
size_t prot_len;
int err = 0;
wpa_printf(MSG_INFO, "\nIEEE P802.11ac/D7.0, M.9.1 BIP-GMAC-256 with broadcast Deauthentication frame\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(igtk, sizeof(igtk), frame, sizeof(frame),
ipn, 4, &prot_len);
if (prot == NULL) {
wpa_printf(MSG_ERROR, "Failed to protect BIP-GMAC-256 frame");
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, "BIP-GMAC-128 test vector mismatch");
err++;
}
os_free(prot);
return err;
}
int main(int argc, char *argv[])
{
int errors = 0;
wpa_debug_level = MSG_EXCESSIVE;
wpa_debug_show_keys = 1;
if (os_program_init())
return -1;
test_vector_tkip();
test_vector_ccmp();
test_vector_bip();
test_vector_ccmp_mgmt();
errors += test_vector_gcmp();
errors += test_vector_gcmp_256();
errors += test_vector_ccmp_256();
errors += test_vector_bip_gmac_128();
errors += test_vector_bip_gmac_256();
if (errors)
wpa_printf(MSG_INFO, "One or more test vectors failed");
os_program_deinit();
return errors ? -1 : 0;
}