wlantest: Add CCMP-256 test vector
authorJouni Malinen <j@w1.fi>
Sun, 9 Sep 2012 15:38:18 +0000 (18:38 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 9 Sep 2012 15:38:18 +0000 (18:38 +0300)
Signed-hostap: Jouni Malinen <j@w1.fi>

wlantest/ccmp.c
wlantest/test_vectors.c
wlantest/wlantest.h

index f0d265a..d7a0e65 100644 (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;
+}
index 6a0283d..968ce99 100644 (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();
 
index a2a0a62..a8db20b 100644 (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);