wlantest: Add CCMP-256 test vector

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2012-09-09 18:38:18 +03:00
parent 4bf3910574
commit 7d19d3e9db
3 changed files with 153 additions and 0 deletions

View file

@ -175,3 +175,93 @@ u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
return crypt;
}
u8 * ccmp_256_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
const u8 *data, size_t data_len, size_t *decrypted_len)
{
u8 aad[30], nonce[13];
size_t aad_len;
size_t mlen;
u8 *plain;
if (data_len < 8 + 16)
return NULL;
plain = os_malloc(data_len + AES_BLOCK_SIZE);
if (plain == NULL)
return NULL;
mlen = data_len - 8 - 16;
os_memset(aad, 0, sizeof(aad));
ccmp_aad_nonce(hdr, data, aad, &aad_len, nonce);
wpa_hexdump(MSG_EXCESSIVE, "CCMP-256 AAD", aad, aad_len);
wpa_hexdump(MSG_EXCESSIVE, "CCMP-256 nonce", nonce, 13);
if (aes_ccm_ad(tk, 16, nonce, 16, data + 8, mlen, aad, aad_len,
data + 8 + mlen, plain) < 0) {
u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
wpa_printf(MSG_INFO, "Invalid CCMP-256 MIC in frame: A1=" MACSTR
" A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
MAC2STR(hdr->addr3),
WLAN_GET_SEQ_SEQ(seq_ctrl),
WLAN_GET_SEQ_FRAG(seq_ctrl));
os_free(plain);
return NULL;
}
wpa_hexdump(MSG_EXCESSIVE, "CCMP-256 decrypted", plain, mlen);
*decrypted_len = mlen;
return plain;
}
u8 * ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen,
u8 *qos, u8 *pn, int keyid, size_t *encrypted_len)
{
u8 aad[30], nonce[13];
size_t aad_len, plen;
u8 *crypt, *pos;
struct ieee80211_hdr *hdr;
if (len < hdrlen || hdrlen < 24)
return NULL;
plen = len - hdrlen;
crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE);
if (crypt == NULL)
return NULL;
os_memcpy(crypt, frame, hdrlen);
hdr = (struct ieee80211_hdr *) crypt;
hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
pos = crypt + hdrlen;
*pos++ = pn[5]; /* PN0 */
*pos++ = pn[4]; /* PN1 */
*pos++ = 0x00; /* Rsvd */
*pos++ = 0x20 | (keyid << 6);
*pos++ = pn[3]; /* PN2 */
*pos++ = pn[2]; /* PN3 */
*pos++ = pn[1]; /* PN4 */
*pos++ = pn[0]; /* PN5 */
os_memset(aad, 0, sizeof(aad));
ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce);
wpa_hexdump(MSG_EXCESSIVE, "CCMP-256 AAD", aad, aad_len);
wpa_hexdump(MSG_EXCESSIVE, "CCMP-256 nonce", nonce, 13);
if (aes_ccm_ae(tk, 16, nonce, 16, frame + hdrlen, plen, aad, aad_len,
pos, pos + plen) < 0) {
os_free(crypt);
return NULL;
}
wpa_hexdump(MSG_EXCESSIVE, "CCMP-256 encrypted", crypt + hdrlen + 8,
plen);
*encrypted_len = hdrlen + 8 + plen + 16;
return crypt;
}

View file

@ -350,6 +350,64 @@ static void test_vector_gcmp_256(void)
}
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);
}
int main(int argc, char *argv[])
{
wpa_debug_level = MSG_EXCESSIVE;
@ -364,6 +422,7 @@ int main(int argc, char *argv[])
test_vector_ccmp_mgmt();
test_vector_gcmp();
test_vector_gcmp_256();
test_vector_ccmp_256();
os_program_deinit();

View file

@ -227,6 +227,10 @@ u8 * ccmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
u8 *pn, int keyid, size_t *encrypted_len);
void ccmp_get_pn(u8 *pn, const u8 *data);
u8 * ccmp_256_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
const u8 *data, size_t data_len, size_t *decrypted_len);
u8 * ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen,
u8 *qos, u8 *pn, int keyid, size_t *encrypted_len);
u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
const u8 *data, size_t data_len, size_t *decrypted_len);