Accumulative patch from commit dc013f1e37df3462085cf01a13f0c432f146ad7a

Author: Jouni Malinen <jouni@qca.qualcomm.com>
Date:   Tue Jan 15 12:03:29 2013 +0200
    eapol_test: Remove unnecessary header file inclusion

 - P2P: Send P2P-FIND-STOPPED event in the new continue-search states
 - P2P: Add some more details on Service Query TLV format
 - P2P: Use the same Dialog Token value for every GO Negotiation retry
 - P2P: Publish more connected clients info in Probe Response frames
 - P2P: Fix some memory leaks in p2p_add_device()
 - P2P: Use the same Dialog Token value for every PD retry
 - P2P: Document operating channel selection functions
 - P2P: Always re-select operating channel if not hard coded
 - P2P: Do not allow re-selection of GO channel if forced_freq in use
 - P2P: Set FORCE_FREQ flag as part of p2p_prepare_channel()
 - P2P: Share a single function for GO channel selection
 - P2P: Prefer operating channels where HT40 is possible
 - P2P: Be more careful with wpa_config_update_psk() call
 - P2P: Allow PSK to be used instead of passphrase for persistent GO
 - P2P: Consider age for the P2P scan results
 - Move some P2P offchannel operations to offchannel.c
 - P2P: Add more complete description of p2p_cancel
 - P2P: Allow p2p_cancel to be used to stop p2p_connect-join operation
 - Interworking changes
 - WNM changes
 - WPS changes
 - SAE changes

Change-Id: I38b847d3460066cc58aecbcf67266bfcff1d344e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/rsn_supp/peerkey.c b/src/rsn_supp/peerkey.c
index f2bac34..789ac25 100644
--- a/src/rsn_supp/peerkey.c
+++ b/src/rsn_supp/peerkey.c
@@ -217,23 +217,17 @@
 		return -1;
 	}
 
-	cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
-	if (cipher & WPA_CIPHER_CCMP) {
-		wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
-		cipher = WPA_CIPHER_CCMP;
-	} else if (cipher & WPA_CIPHER_GCMP) {
-		wpa_printf(MSG_DEBUG, "RSN: Using GCMP for PeerKey");
-		cipher = WPA_CIPHER_GCMP;
-	} else if (cipher & WPA_CIPHER_TKIP) {
-		wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
-		cipher = WPA_CIPHER_TKIP;
-	} else {
+	cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
+					  sm->allowed_pairwise_cipher, 0);
+	if (cipher < 0) {
 		wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
 		wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
 					      STK_MUI_SMK, STK_ERR_CPHR_NS,
 					      ver);
 		return -1;
 	}
+	wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
+		   wpa_cipher_txt(cipher));
 
 	/* TODO: find existing entry and if found, use that instead of adding
 	 * a new one; how to handle the case where both ends initiate at the
@@ -496,17 +490,9 @@
 	peerkey->rsnie_p_len = kde->rsn_ie_len;
 	os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);
 
-	cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
-	if (cipher & WPA_CIPHER_CCMP) {
-		wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
-		peerkey->cipher = WPA_CIPHER_CCMP;
-	} else if (cipher & WPA_CIPHER_GCMP) {
-		wpa_printf(MSG_DEBUG, "RSN: Using GCMP for PeerKey");
-		peerkey->cipher = WPA_CIPHER_GCMP;
-	} else if (cipher & WPA_CIPHER_TKIP) {
-		wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
-		peerkey->cipher = WPA_CIPHER_TKIP;
-	} else {
+	cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
+					  sm->allowed_pairwise_cipher, 0);
+	if (cipher < 0) {
 		wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
 			   "unacceptable cipher", MAC2STR(kde->mac_addr));
 		wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
@@ -515,6 +501,9 @@
 		/* TODO: abort negotiation */
 		return -1;
 	}
+	wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
+		   wpa_cipher_txt(cipher));
+	peerkey->cipher = cipher;
 
 	return 0;
 }
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 7646ca8..c38fada 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -1309,21 +1309,10 @@
 		wpa_printf(MSG_DEBUG, "TDLS: No supported rates received");
 		return -1;
 	}
-
-	peer->supp_rates_len = kde->supp_rates_len - 2;
-	if (peer->supp_rates_len > IEEE80211_MAX_SUPP_RATES)
-		peer->supp_rates_len = IEEE80211_MAX_SUPP_RATES;
-	os_memcpy(peer->supp_rates, kde->supp_rates + 2, peer->supp_rates_len);
-
-	if (kde->ext_supp_rates) {
-		int clen = kde->ext_supp_rates_len - 2;
-		if (peer->supp_rates_len + clen > IEEE80211_MAX_SUPP_RATES)
-			clen = IEEE80211_MAX_SUPP_RATES - peer->supp_rates_len;
-		os_memcpy(peer->supp_rates + peer->supp_rates_len,
-			  kde->ext_supp_rates + 2, clen);
-		peer->supp_rates_len += clen;
-	}
-
+	peer->supp_rates_len = merge_byte_arrays(
+		peer->supp_rates, sizeof(peer->supp_rates),
+		kde->supp_rates + 2, kde->supp_rates_len - 2,
+		kde->ext_supp_rates + 2, kde->ext_supp_rates_len - 2);
 	return 0;
 }
 
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 3c45f3a..e50404c 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -2627,7 +2627,7 @@
 }
 
 
-#ifdef CONFIG_IEEE80211V
+#ifdef CONFIG_WNM
 int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
 {
 	struct wpa_gtk_data gd;
@@ -2637,7 +2637,6 @@
 #endif /* CONFIG_IEEE80211W */
 	u16 keyinfo;
 	u8 keylen;  /* plaintext key len */
-	u8 keydatalen;
 	u8 *key_rsc;
 
 	os_memset(&gd, 0, sizeof(gd));
@@ -2655,8 +2654,7 @@
 
 	if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
 		key_rsc = buf + 5;
-		keyinfo = WPA_GET_LE16(buf+2);
-		keydatalen = buf[1] - 11 - 8;
+		keyinfo = WPA_GET_LE16(buf + 2);
 		gd.gtk_len = keylen;
 		if (gd.gtk_len != buf[4]) {
 			wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
@@ -2667,18 +2665,7 @@
 		gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
 		         sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
 
-		if (keydatalen % 8) {
-			wpa_printf(MSG_DEBUG, "WPA: Unsupported AES-WRAP len "
-				   "%d", keydatalen);
-			return -1;
-		}
-
-		if (aes_unwrap(sm->ptk.kek, keydatalen / 8, buf + 13, gd.gtk))
-		{
-			wpa_printf(MSG_WARNING, "WNM: AES unwrap failed - "
-				   "could not decrypt GTK");
-			return -1;
-		}
+		os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
 
 		wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
 				gd.gtk, gd.gtk_len);
@@ -2689,22 +2676,11 @@
 		}
 #ifdef CONFIG_IEEE80211W
 	} else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
-		if (buf[1] != 2 + 6 + WPA_IGTK_LEN + 8) {
-			wpa_printf(MSG_DEBUG, "WPA: Unsupported AES-WRAP len "
-				   "%d", buf[1] - 2 - 6 - 8);
-			return -1;
-		}
 		os_memcpy(igd.keyid, buf + 2, 2);
 		os_memcpy(igd.pn, buf + 4, 6);
 
 		keyidx = WPA_GET_LE16(igd.keyid);
-
-		if (aes_unwrap(sm->ptk.kek, WPA_IGTK_LEN / 8, buf + 10,
-			       igd.igtk)) {
-			wpa_printf(MSG_WARNING, "WNM: AES unwrap failed - "
-				   "could not decrypr IGTK");
-			return -1;
-		}
+		os_memcpy(igd.igtk, buf + 10, WPA_IGTK_LEN);
 
 		wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
 				igd.igtk, WPA_IGTK_LEN);
@@ -2723,4 +2699,4 @@
 
 	return 0;
 }
-#endif /* CONFIG_IEEE80211V */
+#endif /* CONFIG_WNM */
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 8afdf39..791974c 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -365,8 +365,6 @@
 void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr);
 int wpa_tdls_is_external_setup(struct wpa_sm *sm);
 
-#ifdef CONFIG_IEEE80211V
 int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf);
-#endif /* CONFIG_IEEE80211V */
 
 #endif /* WPA_H */