wlantest: Add CCMP-256 test vector
Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
4bf3910574
commit
7d19d3e9db
3 changed files with 153 additions and 0 deletions
|
@ -175,3 +175,93 @@ u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
|
||||||
|
|
||||||
return crypt;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
wpa_debug_level = MSG_EXCESSIVE;
|
wpa_debug_level = MSG_EXCESSIVE;
|
||||||
|
@ -364,6 +422,7 @@ int main(int argc, char *argv[])
|
||||||
test_vector_ccmp_mgmt();
|
test_vector_ccmp_mgmt();
|
||||||
test_vector_gcmp();
|
test_vector_gcmp();
|
||||||
test_vector_gcmp_256();
|
test_vector_gcmp_256();
|
||||||
|
test_vector_ccmp_256();
|
||||||
|
|
||||||
os_program_deinit();
|
os_program_deinit();
|
||||||
|
|
||||||
|
|
|
@ -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 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
|
||||||
u8 *pn, int keyid, size_t *encrypted_len);
|
u8 *pn, int keyid, size_t *encrypted_len);
|
||||||
void ccmp_get_pn(u8 *pn, const u8 *data);
|
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,
|
u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
|
||||||
const u8 *data, size_t data_len, size_t *decrypted_len);
|
const u8 *data, size_t data_len, size_t *decrypted_len);
|
||||||
|
|
Loading…
Reference in a new issue