diff --git a/wlantest/Makefile b/wlantest/Makefile index 5b23bba53..0ccd61589 100644 --- a/wlantest/Makefile +++ b/wlantest/Makefile @@ -72,6 +72,7 @@ OBJS += ctrl.o OBJS += inject.o OBJS += wep.o OBJS += bip.o +OBJS += gcmp.o LIBS += -lpcap diff --git a/wlantest/rx_data.c b/wlantest/rx_data.c index e0c922904..3c500d61f 100644 --- a/wlantest/rx_data.c +++ b/wlantest/rx_data.c @@ -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; diff --git a/wlantest/rx_eapol.c b/wlantest/rx_eapol.c index 8118a2768..98fcd8dad 100644 --- a/wlantest/rx_eapol.c +++ b/wlantest/rx_eapol.c @@ -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); diff --git a/wlantest/wlantest.h b/wlantest/wlantest.h index 566ba6b47..574714946 100644 --- a/wlantest/wlantest.h +++ b/wlantest/wlantest.h @@ -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;