fragattacks/wlantest/test_vectors.c
Jouni Malinen 84a65fd6a3 Extend GCMP test vectors to include both MPDUs
IEEE Std 802.11ad-2012 includes two test vectors for GCMP. Verify both
of those and also verify that the results match the values in the
standard instead of just verifying that decrypted frame matches
original.

Signed-hostap: Jouni Malinen <j@w1.fi>
2013-11-17 20:34:01 +02:00

659 lines
20 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"
extern int wpa_debug_level;
extern int wpa_debug_show_keys;
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 void 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 *enc, *plain;
size_t enc_len, plain_len;
u8 fcs[4];
wpa_printf(MSG_INFO, "\nGCMP-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;
}
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 = 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;
}
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);
}
os_free(plain);
}
static void 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 *enc, *plain;
size_t enc_len, plain_len;
u8 fcs[4];
wpa_printf(MSG_INFO, "\nCCMP-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;
}
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_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;
}
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_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 *prot;
size_t prot_len;
wpa_printf(MSG_INFO, "\nBIP-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;
}
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
os_free(prot);
}
static void 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 *prot;
size_t prot_len;
wpa_printf(MSG_INFO, "\nBIP-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;
}
wpa_hexdump(MSG_INFO, "Protected MPDU (without FCS)", prot, prot_len);
os_free(prot);
}
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();
test_vector_gcmp_256();
test_vector_ccmp_256();
test_vector_bip_gmac_128();
test_vector_bip_gmac_256();
if (errors)
wpa_printf(MSG_INFO, "One or more test vectors failed");
os_program_deinit();
return errors ? -1 : 0;
}