Browse Source

wlantest: Add decryption of CCMP-256, GCMP, GCMP-256

This extends wlantest support for decrypting the new cipher suites.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Ashok Kumar Ponnaiah 10 years ago
parent
commit
eb2223e0ec
4 changed files with 56 additions and 14 deletions
  1. 1 0
      wlantest/Makefile
  2. 47 13
      wlantest/rx_data.c
  3. 7 1
      wlantest/rx_eapol.c
  4. 1 0
      wlantest/wlantest.h

+ 1 - 0
wlantest/Makefile

@@ -72,6 +72,7 @@ OBJS += ctrl.o
 OBJS += inject.o
 OBJS += wep.o
 OBJS += bip.o
+OBJS += gcmp.o
 
 LIBS += -lpcap
 

+ 47 - 13
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;

+ 7 - 1
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);

+ 1 - 0
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;