]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wlantest: Extend BIP support to cover BIP-CMAC-256
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 23 Jan 2015 15:24:24 +0000 (17:24 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 24 Jan 2015 17:37:42 +0000 (19:37 +0200)
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
wlantest/bip.c
wlantest/inject.c
wlantest/rx_eapol.c
wlantest/rx_mgmt.c
wlantest/test_vectors.c
wlantest/wlantest.h

index d9a52e937bbde18af086aeb5ee77d09cdbcb3fa0..bda8036c5ec534849b35c5c1b7ae16e34594769c 100644 (file)
@@ -14,8 +14,8 @@
 #include "wlantest.h"
 
 
-u8 * bip_protect(const u8 *igtk, u8 *frame, size_t len, u8 *ipn, int keyid,
-                size_t *prot_len)
+u8 * bip_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
+                u8 *ipn, int keyid, size_t *prot_len)
 {
        u8 *prot, *pos, *buf;
        u8 mic[16];
@@ -23,19 +23,19 @@ u8 * bip_protect(const u8 *igtk, u8 *frame, size_t len, u8 *ipn, int keyid,
        struct ieee80211_hdr *hdr;
        size_t plen;
 
-       plen = len + 18;
+       plen = len + igtk_len == 32 ? 26 : 18;
        prot = os_malloc(plen);
        if (prot == NULL)
                return NULL;
        os_memcpy(prot, frame, len);
        pos = prot + len;
        *pos++ = WLAN_EID_MMIE;
-       *pos++ = 16;
+       *pos++ = igtk_len == 32 ? 24 : 16;
        WPA_PUT_LE16(pos, keyid);
        pos += 2;
        os_memcpy(pos, ipn, 6);
        pos += 6;
-       os_memset(pos, 0, 8); /* MIC */
+       os_memset(pos, 0, igtk_len == 32 ? 16 : 8); /* MIC */
 
        buf = os_malloc(plen + 20 - 24);
        if (buf == NULL) {
@@ -59,8 +59,8 @@ u8 * bip_protect(const u8 *igtk, u8 *frame, size_t len, u8 *ipn, int keyid,
        }
        os_free(buf);
 
-       os_memcpy(pos, mic, 8);
-       wpa_hexdump(MSG_DEBUG, "BIP MMIE MIC", pos, 8);
+       os_memcpy(pos, mic, igtk_len == 32 ? 16 : 8);
+       wpa_hexdump(MSG_DEBUG, "BIP MMIE MIC", pos, igtk_len == 32 ? 16 : 8);
 
        *prot_len = plen;
        return prot;
index 22a9e2afd835158ac36baf24c86816e3cb5eb39e..04cd9618397da2bda8fcc9a65e9aa5731fcb20c1 100644 (file)
@@ -82,17 +82,18 @@ static int wlantest_inject_bip(struct wlantest *wt, struct wlantest_bss *bss,
                               u8 *frame, size_t len, int incorrect_key)
 {
        u8 *prot;
-       u8 dummy[16];
+       u8 dummy[32];
        int ret;
        size_t plen;
 
-       if (!bss->igtk_set[bss->igtk_idx])
+       if (!bss->igtk_len[bss->igtk_idx])
                return -1;
 
        os_memset(dummy, 0x11, sizeof(dummy));
        inc_byte_array(bss->ipn[bss->igtk_idx], 6);
 
        prot = bip_protect(incorrect_key ? dummy : bss->igtk[bss->igtk_idx],
+                          bss->igtk_len[bss->igtk_idx],
                           frame, len, bss->ipn[bss->igtk_idx],
                           bss->igtk_idx, &plen);
        if (prot == NULL)
@@ -300,7 +301,7 @@ int wlantest_inject(struct wlantest *wt, struct wlantest_bss *bss,
             prot == WLANTEST_INJECT_INCORRECT_KEY) && bss) {
                if (!sta &&
                    ((WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
-                     !bss->igtk_set[bss->igtk_idx]) ||
+                     !bss->igtk_len[bss->igtk_idx]) ||
                     (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
                      !bss->gtk_len[bss->gtk_idx]))) {
                        wpa_printf(MSG_INFO, "No GTK/IGTK known for "
@@ -323,7 +324,7 @@ int wlantest_inject(struct wlantest *wt, struct wlantest_bss *bss,
                            bss->gtk_len[bss->gtk_idx])
                                protect = 1;
                        if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
-                           bss->igtk_set[bss->igtk_idx])
+                           bss->igtk_len[bss->igtk_idx])
                                protect = 1;
                }
        }
index 13510ef7a8cb03d2372cafccf25ccfd14d3306ba..704c0eb9f1b13e9b7d01748c9a8f5bdd2d26ecf8 100644 (file)
@@ -464,7 +464,30 @@ static void learn_kde_keys(struct wlantest *wt, struct wlantest_bss *bss,
                                wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
                                            16);
                                os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
-                               bss->igtk_set[id] = 1;
+                               bss->igtk_len[id] = 16;
+                               ipn = ie.igtk + 2;
+                               bss->ipn[id][0] = ipn[5];
+                               bss->ipn[id][1] = ipn[4];
+                               bss->ipn[id][2] = ipn[3];
+                               bss->ipn[id][3] = ipn[2];
+                               bss->ipn[id][4] = ipn[1];
+                               bss->ipn[id][5] = ipn[0];
+                               bss->igtk_idx = id;
+                       }
+               } else if (ie.igtk_len == 40) {
+                       u16 id;
+                       id = WPA_GET_LE16(ie.igtk);
+                       if (id > 5) {
+                               add_note(wt, MSG_INFO,
+                                        "Unexpected IGTK KeyID %u", id);
+                       } else {
+                               const u8 *ipn;
+                               add_note(wt, MSG_DEBUG, "IGTK KeyID %u", id);
+                               wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
+                               wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
+                                           32);
+                               os_memcpy(bss->igtk[id], ie.igtk + 8, 32);
+                               bss->igtk_len[id] = 32;
                                ipn = ie.igtk + 2;
                                bss->ipn[id][0] = ipn[5];
                                bss->ipn[id][1] = ipn[4];
index 367a6b5f767b71090074fd8655257f8b9cb13f5e..09688c6d5071acf7aab2aa8ee17b6ec8ffc88c26 100644 (file)
@@ -753,12 +753,24 @@ static void rx_mgmt_action(struct wlantest *wt, const u8 *data, size_t len,
 }
 
 
-static int check_mmie_mic(const u8 *igtk, const u8 *data, size_t len)
+static int check_mmie_mic(const u8 *igtk, size_t igtk_len,
+                         const u8 *data, size_t len)
 {
        u8 *buf;
        u8 mic[16];
        u16 fc;
        const struct ieee80211_hdr *hdr;
+       int ret, mic_len;
+
+       if (igtk_len == 32)
+               mic_len = 16;
+       else if (igtk_len == 16)
+               mic_len = 8;
+       else
+               return -1;
+
+       if (len < 24 || len - 24 < mic_len)
+               return -1;
 
        buf = os_malloc(len + 20 - 24);
        if (buf == NULL)
@@ -772,19 +784,23 @@ static int check_mmie_mic(const u8 *igtk, const u8 *data, size_t len)
        os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN);
 
        /* Frame body with MMIE MIC masked to zero */
-       os_memcpy(buf + 20, data + 24, len - 24 - 8);
-       os_memset(buf + 20 + len - 24 - 8, 0, 8);
+       os_memcpy(buf + 20, data + 24, len - 24 - mic_len);
+       os_memset(buf + 20 + len - 24 - mic_len, 0, mic_len);
 
        wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, len + 20 - 24);
        /* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
-       if (omac1_aes_128(igtk, buf, len + 20 - 24, mic) < 0) {
+       if (igtk_len == 32)
+               ret = omac1_aes_256(igtk, buf, len + 20 - 24, mic);
+       else
+               ret = omac1_aes_128(igtk, buf, len + 20 - 24, mic);
+       if (ret < 0) {
                os_free(buf);
                return -1;
        }
 
        os_free(buf);
 
-       if (os_memcmp(data + len - 8, mic, 8) != 0)
+       if (os_memcmp(data + len - mic_len, mic, mic_len) != 0)
                return -1;
 
        return 0;
@@ -798,6 +814,7 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
        const u8 *mmie;
        u16 keyid;
        struct wlantest_bss *bss;
+       size_t mic_len;
 
        mgmt = (const struct ieee80211_mgmt *) data;
        fc = le_to_host16(mgmt->frame_control);
@@ -814,8 +831,11 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
        if (bss == NULL)
                return 0; /* No key known yet */
 
-       if (len < 24 + 18 || data[len - 18] != WLAN_EID_MMIE ||
-           data[len - 17] != 16) {
+       mic_len = bss->igtk_len[4] == 32 || bss->igtk_len[5] == 32 ? 16 : 8;
+
+       if (len < 24 + 10 + mic_len ||
+           data[len - (10 + mic_len)] != WLAN_EID_MMIE ||
+           data[len - (10 + mic_len - 1)] != 8 + mic_len) {
                /* No MMIE */
                if (bss->rsn_capab & WPA_CAPABILITY_MFPC) {
                        add_note(wt, MSG_INFO, "Robust group-addressed "
@@ -827,7 +847,7 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
                return 0;
        }
 
-       mmie = data + len - 16;
+       mmie = data + len - (8 + mic_len);
        keyid = WPA_GET_LE16(mmie);
        if (keyid & 0xf000) {
                add_note(wt, MSG_INFO, "MMIE KeyID reserved bits not zero "
@@ -842,9 +862,9 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
        }
        wpa_printf(MSG_DEBUG, "MMIE KeyID %u", keyid);
        wpa_hexdump(MSG_MSGDUMP, "MMIE IPN", mmie + 2, 6);
-       wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, 8);
+       wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, mic_len);
 
-       if (!bss->igtk_set[keyid]) {
+       if (!bss->igtk_len[keyid]) {
                add_note(wt, MSG_DEBUG, "No IGTK known to validate BIP frame");
                return 0;
        }
@@ -856,7 +876,8 @@ static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
                wpa_hexdump(MSG_INFO, "Last RX IPN", bss->ipn[keyid], 6);
        }
 
-       if (check_mmie_mic(bss->igtk[keyid], data, len) < 0) {
+       if (check_mmie_mic(bss->igtk[keyid], bss->igtk_len[keyid], data, len) <
+           0) {
                add_note(wt, MSG_INFO, "Invalid MMIE MIC in a frame from "
                         MACSTR, MAC2STR(mgmt->sa));
                bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
index 0800db7f3a3adeaf0b67b1570f82320a6d4c0de5..321d930aeea1f64e888db99e8bcefd2536394c04 100644 (file)
@@ -159,7 +159,8 @@ static void test_vector_bip(void)
        wpa_hexdump(MSG_INFO, "IPN", ipn, sizeof(ipn));
        wpa_hexdump(MSG_INFO, "Plaintext frame", frame, sizeof(frame));
 
-       prot = bip_protect(igtk, frame, sizeof(frame), ipn, 4, &prot_len);
+       prot = bip_protect(igtk, sizeof(igtk), frame, sizeof(frame),
+                          ipn, 4, &prot_len);
        if (prot == NULL) {
                wpa_printf(MSG_ERROR, "Failed to protect BIP frame");
                return;
index 574714946f7ce7c88ee5fc70c4b2f3a161f4012c..1d8088fa6d5d7fa7c45561a7ab992f493fda644a 100644 (file)
@@ -145,8 +145,8 @@ struct wlantest_bss {
        size_t gtk_len[4];
        int gtk_idx;
        u8 rsc[4][6];
-       u8 igtk[6][16];
-       int igtk_set[6];
+       u8 igtk[6][32];
+       size_t igtk_len[6];
        int igtk_idx;
        u8 ipn[6][6];
        u32 counters[NUM_WLANTEST_BSS_COUNTER];
@@ -284,8 +284,8 @@ void tkip_get_pn(u8 *pn, const u8 *data);
 u8 * wep_decrypt(struct wlantest *wt, const struct ieee80211_hdr *hdr,
                 const u8 *data, size_t data_len, size_t *decrypted_len);
 
-u8 * bip_protect(const u8 *igtk, u8 *frame, size_t len, u8 *ipn, int keyid,
-                size_t *prot_len);
+u8 * bip_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
+                u8 *ipn, int keyid, size_t *prot_len);
 u8 * bip_gmac_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len,
                      u8 *ipn, int keyid, size_t *prot_len);