diff --git a/wlantest/gcmp.c b/wlantest/gcmp.c index 5639b7e2b..d8535d0e2 100644 --- a/wlantest/gcmp.c +++ b/wlantest/gcmp.c @@ -73,7 +73,7 @@ static void gcmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data, } -u8 * gcmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, +u8 * gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, const u8 *data, size_t data_len, size_t *decrypted_len) { u8 aad[30], nonce[12], *plain; @@ -95,7 +95,7 @@ u8 * gcmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", aad, aad_len); wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce)); - if (aes_gcm_ad(tk, 16, nonce, sizeof(nonce), m, mlen, aad, aad_len, + if (aes_gcm_ad(tk, tk_len, nonce, sizeof(nonce), m, mlen, aad, aad_len, m + mlen, plain) < 0) { u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); wpa_printf(MSG_INFO, "Invalid GCMP frame: A1=" MACSTR @@ -113,7 +113,8 @@ u8 * gcmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, } -u8 * gcmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, +u8 * gcmp_encrypt(const u8 *tk, size_t tk_len, u8 *frame, size_t len, + size_t hdrlen, u8 *qos, u8 *pn, int keyid, size_t *encrypted_len) { u8 aad[30], nonce[12], *crypt, *pos; @@ -146,8 +147,8 @@ u8 * gcmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, wpa_hexdump(MSG_EXCESSIVE, "GCMP AAD", aad, aad_len); wpa_hexdump(MSG_EXCESSIVE, "GCMP nonce", nonce, sizeof(nonce)); - if (aes_gcm_ae(tk, 16, nonce, sizeof(nonce), frame + hdrlen, plen, aad, - aad_len, pos, pos + plen) < 0) { + if (aes_gcm_ae(tk, tk_len, nonce, sizeof(nonce), frame + hdrlen, plen, + aad, aad_len, pos, pos + plen) < 0) { os_free(crypt); return NULL; } diff --git a/wlantest/test_vectors.c b/wlantest/test_vectors.c index 011620bd0..6a0283d3c 100644 --- a/wlantest/test_vectors.c +++ b/wlantest/test_vectors.c @@ -255,8 +255,8 @@ static void test_vector_gcmp(void) wpa_hexdump(MSG_INFO, "802.11 Header", frame, 26); wpa_hexdump(MSG_INFO, "Plaintext Data", frame + 26, sizeof(frame) - 26); - enc = gcmp_encrypt(tk, frame, sizeof(frame), 26, frame + 24, pn, 0, - &enc_len); + 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; @@ -267,7 +267,70 @@ static void test_vector_gcmp(void) wpa_hexdump(MSG_INFO, "FCS", fcs, sizeof(fcs)); wpa_debug_level = MSG_INFO; - plain = gcmp_decrypt(tk, (const struct ieee80211_hdr *) enc, + 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_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); @@ -300,6 +363,7 @@ int main(int argc, char *argv[]) test_vector_bip(); test_vector_ccmp_mgmt(); test_vector_gcmp(); + test_vector_gcmp_256(); os_program_deinit(); diff --git a/wlantest/wlantest.h b/wlantest/wlantest.h index be8f1f145..a2a0a6245 100644 --- a/wlantest/wlantest.h +++ b/wlantest/wlantest.h @@ -240,9 +240,10 @@ u8 * wep_decrypt(struct wlantest *wt, const struct ieee80211_hdr *hdr, u8 * bip_protect(const u8 *igtk, u8 *frame, size_t len, u8 *ipn, int keyid, size_t *prot_len); -u8 * gcmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, +u8 * gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, const u8 *data, size_t data_len, size_t *decrypted_len); -u8 * gcmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, +u8 * gcmp_encrypt(const u8 *tk, size_t tk_len, u8 *frame, size_t len, + size_t hdrlen, u8 *qos, u8 *pn, int keyid, size_t *encrypted_len); int ctrl_init(struct wlantest *wt);