]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wlantest: Add decryption of CCMP-256, GCMP, GCMP-256
authorAshok Kumar Ponnaiah <aponnaia@qti.qualcomm.com>
Fri, 29 Aug 2014 13:05:05 +0000 (16:05 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 3 Sep 2014 12:41:35 +0000 (15:41 +0300)
This extends wlantest support for decrypting the new cipher suites.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
wlantest/Makefile
wlantest/rx_data.c
wlantest/rx_eapol.c
wlantest/wlantest.h

index 5b23bba53da67f85f002e43263a88343f6d6c918..0ccd615898d3045acf41f268def5f2e7fc18150d 100644 (file)
@@ -72,6 +72,7 @@ OBJS += ctrl.o
 OBJS += inject.o
 OBJS += wep.o
 OBJS += bip.o
+OBJS += gcmp.o
 
 LIBS += -lpcap
 
index e0c922904811adb9a77ac3f3752c417ba812848b..3c500d61f740ee28186b8012b65a474127b2d096 100644 (file)
@@ -103,14 +103,24 @@ static u8 * try_all_ptk(struct wlantest *wt, int pairwise_cipher,
 
        wpa_debug_level = MSG_WARNING;
        dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
+               unsigned int tk_len = ptk->ptk_len - 32;
                decrypted = NULL;
                if ((pairwise_cipher == WPA_CIPHER_CCMP ||
-                    pairwise_cipher == 0) && ptk->ptk_len == 48) {
+                    pairwise_cipher == 0) && tk_len == 16) {
                        decrypted = ccmp_decrypt(ptk->ptk.tk1, hdr, data,
                                                 data_len, decrypted_len);
-               }
-               if ((pairwise_cipher == WPA_CIPHER_TKIP ||
-                    pairwise_cipher == 0) && ptk->ptk_len == 64) {
+               } else if ((pairwise_cipher == WPA_CIPHER_CCMP_256 ||
+                           pairwise_cipher == 0) && tk_len == 32) {
+                       decrypted = ccmp_256_decrypt(ptk->ptk.tk1, hdr, data,
+                                                    data_len, decrypted_len);
+               } else if ((pairwise_cipher == WPA_CIPHER_GCMP ||
+                           pairwise_cipher == WPA_CIPHER_GCMP_256 ||
+                           pairwise_cipher == 0) &&
+                          (tk_len == 16 || tk_len == 32)) {
+                       decrypted = gcmp_decrypt(ptk->ptk.tk1, tk_len, hdr,
+                                                data, data_len, decrypted_len);
+               } else if ((pairwise_cipher == WPA_CIPHER_TKIP ||
+                           pairwise_cipher == 0) && tk_len == 32) {
                        decrypted = tkip_decrypt(ptk->ptk.tk1, hdr, data,
                                                 data_len, decrypted_len);
                }
@@ -133,7 +143,7 @@ static void rx_data_bss_prot_group(struct wlantest *wt,
 {
        struct wlantest_bss *bss;
        int keyid;
-       u8 *decrypted;
+       u8 *decrypted = NULL;
        size_t dlen;
        u8 pn[6];
 
@@ -209,9 +219,17 @@ skip_replay_det:
                                         &dlen);
        else if (bss->group_cipher == WPA_CIPHER_WEP40)
                decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
-       else
+       else if (bss->group_cipher == WPA_CIPHER_CCMP)
                decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len,
                                         &dlen);
+       else if (bss->group_cipher == WPA_CIPHER_CCMP_256)
+               decrypted = ccmp_256_decrypt(bss->gtk[keyid], hdr, data, len,
+                                            &dlen);
+       else if (bss->group_cipher == WPA_CIPHER_GCMP ||
+                bss->group_cipher == WPA_CIPHER_GCMP_256)
+               decrypted = gcmp_decrypt(bss->gtk[keyid], bss->gtk_len[keyid],
+                                        hdr, data, len, &dlen);
+
        if (decrypted) {
                rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
                                dlen, 1, NULL);
@@ -383,15 +401,31 @@ static void rx_data_bss_prot(struct wlantest *wt,
        }
 
 skip_replay_det:
-       if (tk)
-               decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen);
-       else if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
+       if (tk) {
+               if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256)
+                       decrypted = ccmp_256_decrypt(tk, hdr, data, len, &dlen);
+               else if (sta->pairwise_cipher == WPA_CIPHER_GCMP ||
+                        sta->pairwise_cipher == WPA_CIPHER_GCMP_256)
+                       decrypted = gcmp_decrypt(tk, sta->tk_len, hdr, data,
+                                                len, &dlen);
+               else
+                       decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen);
+       } else if (sta->pairwise_cipher == WPA_CIPHER_TKIP) {
                decrypted = tkip_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
-       else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
+       } else if (sta->pairwise_cipher == WPA_CIPHER_WEP40) {
                decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
-       else if (sta->ptk_set)
-               decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
-       else {
+       } else if (sta->ptk_set) {
+               if (sta->pairwise_cipher == WPA_CIPHER_CCMP_256)
+                       decrypted = ccmp_256_decrypt(sta->ptk.tk1, hdr, data,
+                                                    len, &dlen);
+               else if (sta->pairwise_cipher == WPA_CIPHER_GCMP ||
+                        sta->pairwise_cipher == WPA_CIPHER_GCMP_256)
+                       decrypted = gcmp_decrypt(sta->ptk.tk1, sta->tk_len,
+                                                hdr, data, len, &dlen);
+               else
+                       decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len,
+                                                &dlen);
+       } else {
                decrypted = try_all_ptk(wt, sta->pairwise_cipher, hdr, data,
                                        len, &dlen);
                ptk_iter_done = 1;
index 8118a2768ff9a875063f2674e3474cd515a6704e..98fcd8dadba408de562d46287f2506c6962ecd3a 100644 (file)
@@ -96,7 +96,10 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
                   struct wlantest_pmk *pmk)
 {
        struct wpa_ptk ptk;
-       size_t ptk_len = sta->pairwise_cipher == WPA_CIPHER_TKIP ? 64 : 48;
+       size_t ptk_len;
+
+       ptk_len = wpa_cipher_key_len(sta->pairwise_cipher) + 32;
+
        wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
                       "Pairwise key expansion",
                       bss->bssid, sta->addr, sta->anonce, sta->snonce,
@@ -105,6 +108,7 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
        if (check_mic(ptk.kck, ver, data, len) < 0)
                return -1;
 
+       sta->tk_len = wpa_cipher_key_len(sta->pairwise_cipher);
        wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
                   MAC2STR(sta->addr), MAC2STR(bss->bssid));
        sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
@@ -170,6 +174,8 @@ static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
                                   MACSTR " BSSID " MACSTR,
                                   MAC2STR(sta->addr), MAC2STR(bss->bssid));
                        add_note(wt, MSG_DEBUG, "Using pre-set PTK");
+                       ptk->ptk_len = 32 +
+                               wpa_cipher_key_len(sta->pairwise_cipher);
                        os_memcpy(&sta->ptk, &ptk->ptk, sizeof(ptk->ptk));
                        wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16);
                        wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16);
index 566ba6b4718235006b1b46300bf9dae31ea8d2c1..574714946f7ce7c88ee5fc70c4b2f3a161f4012c 100644 (file)
@@ -70,6 +70,7 @@ struct wlantest_sta {
        u8 anonce[32]; /* ANonce from the previous EAPOL-Key msg 1/4 or 3/4 */
        u8 snonce[32]; /* SNonce from the previous EAPOL-Key msg 2/4 */
        struct wpa_ptk ptk; /* Derived PTK */
+       size_t tk_len;
        int ptk_set;
        struct wpa_ptk tptk; /* Derived PTK during rekeying */
        int tptk_set;