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>
This commit is contained in:
parent
393e90191e
commit
84a65fd6a3
2 changed files with 187 additions and 35 deletions
|
@ -41,7 +41,6 @@ static void gcmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
|
fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
|
||||||
fc |= WLAN_FC_ISWEP;
|
|
||||||
WPA_PUT_LE16(aad, fc);
|
WPA_PUT_LE16(aad, fc);
|
||||||
pos = aad + 2;
|
pos = aad + 2;
|
||||||
os_memcpy(pos, hdr->addr1, 3 * ETH_ALEN);
|
os_memcpy(pos, hdr->addr1, 3 * ETH_ALEN);
|
||||||
|
@ -131,7 +130,6 @@ u8 * gcmp_encrypt(const u8 *tk, size_t tk_len, u8 *frame, size_t len,
|
||||||
|
|
||||||
os_memcpy(crypt, frame, hdrlen);
|
os_memcpy(crypt, frame, hdrlen);
|
||||||
hdr = (struct ieee80211_hdr *) crypt;
|
hdr = (struct ieee80211_hdr *) crypt;
|
||||||
hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
|
|
||||||
pos = crypt + hdrlen;
|
pos = crypt + hdrlen;
|
||||||
*pos++ = pn[5]; /* PN0 */
|
*pos++ = pn[5]; /* PN0 */
|
||||||
*pos++ = pn[4]; /* PN1 */
|
*pos++ = pn[4]; /* PN1 */
|
||||||
|
|
|
@ -225,65 +225,215 @@ static void test_vector_ccmp_mgmt(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void test_vector_gcmp(void)
|
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 tk[] = { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
|
|
||||||
0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f };
|
|
||||||
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;
|
u8 *enc, *plain;
|
||||||
size_t enc_len, plain_len;
|
size_t enc_len, plain_len;
|
||||||
u8 fcs[4];
|
u8 fcs[4];
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
wpa_printf(MSG_INFO, "\nIEEE P802.11ad/D9.0, M.11.1 GCMP test "
|
wpa_printf(MSG_INFO,
|
||||||
"vector #2\n");
|
"\nIEEE Std 802.11ad-2012, M.11.1 GCMP test mpdu #%d\n",
|
||||||
|
idx);
|
||||||
|
|
||||||
wpa_hexdump(MSG_INFO, "TK", tk, sizeof(tk));
|
wpa_hexdump(MSG_INFO, "TK", vector->tk, sizeof(vector->tk));
|
||||||
wpa_hexdump(MSG_INFO, "PN", pn, sizeof(pn));
|
wpa_hexdump(MSG_INFO, "PN", vector->pn, sizeof(vector->pn));
|
||||||
wpa_hexdump(MSG_INFO, "802.11 Header", frame, 26);
|
wpa_hexdump(MSG_INFO, "802.11 Header", vector->frame, vector->hdr_len);
|
||||||
wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 26, sizeof(frame) - 26);
|
wpa_hexdump(MSG_INFO, "Plaintext Data",
|
||||||
|
vector->frame + vector->hdr_len,
|
||||||
|
vector->payload_len);
|
||||||
|
|
||||||
enc = gcmp_encrypt(tk, sizeof(tk), frame, sizeof(frame), 26, frame + 24,
|
enc = gcmp_encrypt(vector->tk, sizeof(vector->tk),
|
||||||
pn, 0, &enc_len);
|
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) {
|
if (enc == NULL) {
|
||||||
wpa_printf(MSG_ERROR, "Failed to encrypt GCMP frame");
|
wpa_printf(MSG_ERROR, "Failed to encrypt GCMP frame");
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_hexdump(MSG_INFO, "Encrypted MPDU (without FCS)", enc, enc_len);
|
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_PUT_LE32(fcs, crc32(enc, enc_len));
|
||||||
wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
|
wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs));
|
||||||
|
|
||||||
wpa_debug_level = MSG_INFO;
|
wpa_debug_level = MSG_INFO;
|
||||||
plain = gcmp_decrypt(tk, sizeof(tk), (const struct ieee80211_hdr *) enc,
|
plain = gcmp_decrypt(vector->tk, sizeof(vector->tk),
|
||||||
enc + 26, enc_len - 26, &plain_len);
|
(const struct ieee80211_hdr *) enc,
|
||||||
|
enc + vector->hdr_len,
|
||||||
|
enc_len - vector->hdr_len, &plain_len);
|
||||||
wpa_debug_level = MSG_EXCESSIVE;
|
wpa_debug_level = MSG_EXCESSIVE;
|
||||||
os_free(enc);
|
os_free(enc);
|
||||||
|
|
||||||
if (plain == NULL) {
|
if (plain == NULL) {
|
||||||
wpa_printf(MSG_ERROR, "Failed to decrypt GCMP frame");
|
wpa_printf(MSG_ERROR, "Failed to decrypt GCMP frame");
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plain_len != sizeof(frame) - 26 ||
|
if (plain_len != vector->payload_len ||
|
||||||
os_memcmp(plain, frame + 26, plain_len) != 0) {
|
os_memcmp(plain, vector->frame + vector->hdr_len, plain_len) != 0) {
|
||||||
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
|
wpa_hexdump(MSG_ERROR, "Decryption result did not match",
|
||||||
plain, plain_len);
|
plain, plain_len);
|
||||||
|
err++;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_free(plain);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -482,6 +632,8 @@ static void test_vector_bip_gmac_256(void)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
wpa_debug_level = MSG_EXCESSIVE;
|
wpa_debug_level = MSG_EXCESSIVE;
|
||||||
wpa_debug_show_keys = 1;
|
wpa_debug_show_keys = 1;
|
||||||
|
|
||||||
|
@ -492,13 +644,15 @@ int main(int argc, char *argv[])
|
||||||
test_vector_ccmp();
|
test_vector_ccmp();
|
||||||
test_vector_bip();
|
test_vector_bip();
|
||||||
test_vector_ccmp_mgmt();
|
test_vector_ccmp_mgmt();
|
||||||
test_vector_gcmp();
|
errors += test_vector_gcmp();
|
||||||
test_vector_gcmp_256();
|
test_vector_gcmp_256();
|
||||||
test_vector_ccmp_256();
|
test_vector_ccmp_256();
|
||||||
test_vector_bip_gmac_128();
|
test_vector_bip_gmac_128();
|
||||||
test_vector_bip_gmac_256();
|
test_vector_bip_gmac_256();
|
||||||
|
|
||||||
|
if (errors)
|
||||||
|
wpa_printf(MSG_INFO, "One or more test vectors failed");
|
||||||
os_program_deinit();
|
os_program_deinit();
|
||||||
|
|
||||||
return 0;
|
return errors ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue