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/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 0816b25..fa4b1cb 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -282,8 +282,9 @@
 static int wpa_group_init_gmk_and_counter(struct wpa_authenticator *wpa_auth,
 					  struct wpa_group *group)
 {
-	u8 buf[ETH_ALEN + 8 + sizeof(group)];
+	u8 buf[ETH_ALEN + 8 + sizeof(unsigned long)];
 	u8 rkey[32];
+	unsigned long ptr;
 
 	if (random_get_bytes(group->GMK, WPA_GMK_LEN) < 0)
 		return -1;
@@ -295,7 +296,8 @@
 	 */
 	os_memcpy(buf, wpa_auth->addr, ETH_ALEN);
 	wpa_get_ntp_timestamp(buf + ETH_ALEN);
-	os_memcpy(buf + ETH_ALEN + 8, &group, sizeof(group));
+	ptr = (unsigned long) group;
+	os_memcpy(buf + ETH_ALEN + 8, &ptr, sizeof(ptr));
 	if (random_get_bytes(rkey, sizeof(rkey)) < 0)
 		return -1;
 
@@ -2413,11 +2415,9 @@
 				"marking station for GTK rekeying");
 	}
 
-#ifdef CONFIG_IEEE80211V
-	/* Do not rekey GTK/IGTK when STA is in wnmsleep */
+	/* Do not rekey GTK/IGTK when STA is in WNM-Sleep Mode */
 	if (sm->is_wnmsleep)
 		return 0;
-#endif /* CONFIG_IEEE80211V */
 
 	sm->group->GKeyDoneStations++;
 	sm->GUpdateStationKeys = TRUE;
@@ -2427,8 +2427,8 @@
 }
 
 
-#ifdef CONFIG_IEEE80211V
-/* update GTK when exiting wnmsleep mode */
+#ifdef CONFIG_WNM
+/* update GTK when exiting WNM-Sleep Mode */
 void wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm)
 {
 	if (sm->is_wnmsleep)
@@ -2446,111 +2446,65 @@
 
 int wpa_wnmsleep_gtk_subelem(struct wpa_state_machine *sm, u8 *pos)
 {
-	u8 *subelem;
 	struct wpa_group *gsm = sm->group;
-	size_t subelem_len, pad_len;
-	const u8 *key;
-	size_t key_len;
-	u8 keybuf[32];
-
-	/* GTK subslement */
-	key_len = gsm->GTK_len;
-	if (key_len > sizeof(keybuf))
-		return 0;
+	u8 *start = pos;
 
 	/*
-	 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
-	 * than 16 bytes.
-	 */
-	pad_len = key_len % 8;
-	if (pad_len)
-		pad_len = 8 - pad_len;
-	if (key_len + pad_len < 16)
-		pad_len += 8;
-	if (pad_len) {
-		os_memcpy(keybuf, gsm->GTK[gsm->GN - 1], key_len);
-		os_memset(keybuf + key_len, 0, pad_len);
-		keybuf[key_len] = 0xdd;
-		key_len += pad_len;
-		key = keybuf;
-	} else
-		key = gsm->GTK[gsm->GN - 1];
-
-	/*
+	 * GTK subelement:
 	 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] |
-	 * Key[5..32] | 8 padding.
+	 * Key[5..32]
 	 */
-	subelem_len = 13 + key_len + 8;
-	subelem = os_zalloc(subelem_len);
-	if (subelem == NULL)
-		return 0;
-
-	subelem[0] = WNM_SLEEP_SUBELEM_GTK;
-	subelem[1] = 11 + key_len + 8;
+	*pos++ = WNM_SLEEP_SUBELEM_GTK;
+	*pos++ = 11 + gsm->GTK_len;
 	/* Key ID in B0-B1 of Key Info */
-	WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03);
-	subelem[4] = gsm->GTK_len;
-	if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5) != 0)
-	{
-		os_free(subelem);
+	WPA_PUT_LE16(pos, gsm->GN & 0x03);
+	pos += 2;
+	*pos++ = gsm->GTK_len;
+	if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, pos) != 0)
 		return 0;
-	}
-	if (aes_wrap(sm->PTK.kek, key_len / 8, key, subelem + 13)) {
-		os_free(subelem);
-		return 0;
-	}
+	pos += 8;
+	os_memcpy(pos, gsm->GTK[gsm->GN - 1], gsm->GTK_len);
+	pos += gsm->GTK_len;
 
-	os_memcpy(pos, subelem, subelem_len);
-
-	wpa_hexdump_key(MSG_DEBUG, "Plaintext GTK",
+	wpa_printf(MSG_DEBUG, "WNM: GTK Key ID %u in WNM-Sleep Mode exit",
+		   gsm->GN);
+	wpa_hexdump_key(MSG_DEBUG, "WNM: GTK in WNM-Sleep Mode exit",
 			gsm->GTK[gsm->GN - 1], gsm->GTK_len);
-	os_free(subelem);
 
-	return subelem_len;
+	return pos - start;
 }
 
 
 #ifdef CONFIG_IEEE80211W
 int wpa_wnmsleep_igtk_subelem(struct wpa_state_machine *sm, u8 *pos)
 {
-	u8 *subelem, *ptr;
 	struct wpa_group *gsm = sm->group;
-	size_t subelem_len;
+	u8 *start = pos;
 
-	/* IGTK subelement
-	 * Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] |
-	 * Key[16] | 8 padding */
-	subelem_len = 1 + 1 + 2 + 6 + WPA_IGTK_LEN + 8;
-	subelem = os_zalloc(subelem_len);
-	if (subelem == NULL)
+	/*
+	 * IGTK subelement:
+	 * Sub-elem ID[1] | Length[1] | KeyID[2] | PN[6] | Key[16]
+	 */
+	*pos++ = WNM_SLEEP_SUBELEM_IGTK;
+	*pos++ = 2 + 6 + WPA_IGTK_LEN;
+	WPA_PUT_LE16(pos, gsm->GN_igtk);
+	pos += 2;
+	if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos) != 0)
 		return 0;
+	pos += 6;
 
-	ptr = subelem;
-	*ptr++ = WNM_SLEEP_SUBELEM_IGTK;
-	*ptr++ = subelem_len - 2;
-	WPA_PUT_LE16(ptr, gsm->GN_igtk);
-	ptr += 2;
-	if (wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, ptr) != 0) {
-		os_free(subelem);
-		return 0;
-	}
-	ptr += 6;
-	if (aes_wrap(sm->PTK.kek, WPA_IGTK_LEN / 8,
-		     gsm->IGTK[gsm->GN_igtk - 4], ptr)) {
-		os_free(subelem);
-		return -1;
-	}
+	os_memcpy(pos, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
+	pos += WPA_IGTK_LEN;
 
-	os_memcpy(pos, subelem, subelem_len);
-
-	wpa_hexdump_key(MSG_DEBUG, "Plaintext IGTK",
+	wpa_printf(MSG_DEBUG, "WNM: IGTK Key ID %u in WNM-Sleep Mode exit",
+		   gsm->GN_igtk);
+	wpa_hexdump_key(MSG_DEBUG, "WNM: IGTK in WNM-Sleep Mode exit",
 			gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
-	os_free(subelem);
 
-	return subelem_len;
+	return pos - start;
 }
 #endif /* CONFIG_IEEE80211W */
-#endif /* CONFIG_IEEE80211V */
+#endif /* CONFIG_WNM */
 
 
 static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth,