14126Szf162725 /*
25895Syz147064  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
34126Szf162725  * Use is subject to license terms.
44126Szf162725  */
54126Szf162725 
64126Szf162725 /*
74126Szf162725  * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
84126Szf162725  * Sun elects to license this software under the BSD license.
94126Szf162725  * See README for more details.
104126Szf162725  */
114126Szf162725 
124126Szf162725 #pragma ident	"%Z%%M%	%I%	%E% SMI"
134126Szf162725 
144126Szf162725 #include <stdio.h>
154126Szf162725 #include <stdlib.h>
164126Szf162725 #include <string.h>
174126Szf162725 #include <time.h>
184126Szf162725 #include <netinet/in.h>
194126Szf162725 #include <sys/ethernet.h>
204126Szf162725 #include <fcntl.h>
214126Szf162725 #include <unistd.h>
224126Szf162725 
234126Szf162725 #include "wpa_impl.h"
244126Szf162725 #include "wpa_enc.h"
254126Szf162725 #include "driver.h"
264126Szf162725 #include "eloop.h"
274126Szf162725 #include "l2_packet.h"
284126Szf162725 
294126Szf162725 static void pmksa_cache_set_expiration(struct wpa_supplicant *);
304126Szf162725 
314126Szf162725 /*
324126Szf162725  * IEEE 802.11i/D3.0
334126Szf162725  */
344126Szf162725 static const int WPA_SELECTOR_LEN = 4;
35*6411Szf162725 static const uint8_t WPA_OUI_AND_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
364126Szf162725 static const uint8_t
374126Szf162725 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] 		= { 0x00, 0x50, 0xf2, 1 };
384126Szf162725 static const uint8_t
394126Szf162725 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] 		= { 0x00, 0x50, 0xf2, 2 };
404126Szf162725 static const uint8_t WPA_CIPHER_SUITE_NONE[]	= { 0x00, 0x50, 0xf2, 0 };
414126Szf162725 static const uint8_t WPA_CIPHER_SUITE_WEP40[]	= { 0x00, 0x50, 0xf2, 1 };
424126Szf162725 static const uint8_t WPA_CIPHER_SUITE_TKIP[]	= { 0x00, 0x50, 0xf2, 2 };
434126Szf162725 static const uint8_t WPA_CIPHER_SUITE_CCMP[]	= { 0x00, 0x50, 0xf2, 4 };
444126Szf162725 static const uint8_t WPA_CIPHER_SUITE_WEP104[]	= { 0x00, 0x50, 0xf2, 5 };
454126Szf162725 
464126Szf162725 /*
474126Szf162725  * WPA IE version 1
484126Szf162725  * 00-50-f2:1 (OUI:OUI type)
494126Szf162725  * 0x01 0x00 (version; little endian)
504126Szf162725  * (all following fields are optional:)
514126Szf162725  * Group Suite Selector (4 octets) (default: TKIP)
524126Szf162725  * Pairwise Suite Count (2 octets, little endian) (default: 1)
534126Szf162725  * Pairwise Suite List (4 * n octets) (default: TKIP)
544126Szf162725  * Authenticated Key Management Suite Count (2 octets, little endian)
554126Szf162725  * (default: 1)
564126Szf162725  * Authenticated Key Management Suite List (4 * n octets)
574126Szf162725  * (default: unspec 802.1x)
584126Szf162725  * WPA Capabilities (2 octets, little endian) (default: 0)
594126Szf162725  */
604126Szf162725 #pragma pack(1)
614126Szf162725 struct wpa_ie_hdr {
624126Szf162725 	uint8_t		elem_id;
634126Szf162725 	uint8_t		len;
644126Szf162725 	uint8_t		oui[3];
654126Szf162725 	uint8_t		oui_type;
664126Szf162725 	uint16_t	version;
674126Szf162725 };
684126Szf162725 #pragma pack()
694126Szf162725 
704126Szf162725 /*
714126Szf162725  * IEEE 802.11i/D9.0
724126Szf162725  */
734126Szf162725 static const int RSN_SELECTOR_LEN = 4;
744126Szf162725 static const uint16_t RSN_VERSION = 1;
754126Szf162725 static const uint8_t
764126Szf162725 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]		= { 0x00, 0x0f, 0xac, 1 };
774126Szf162725 static const uint8_t
784126Szf162725 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]		= { 0x00, 0x0f, 0xac, 2 };
794126Szf162725 static const uint8_t RSN_CIPHER_SUITE_NONE[]	= { 0x00, 0x0f, 0xac, 0 };
804126Szf162725 static const uint8_t RSN_CIPHER_SUITE_WEP40[]	= { 0x00, 0x0f, 0xac, 1 };
814126Szf162725 static const uint8_t RSN_CIPHER_SUITE_TKIP[]	= { 0x00, 0x0f, 0xac, 2 };
824126Szf162725 static const uint8_t RSN_CIPHER_SUITE_CCMP[]	= { 0x00, 0x0f, 0xac, 4 };
834126Szf162725 static const uint8_t RSN_CIPHER_SUITE_WEP104[]	= { 0x00, 0x0f, 0xac, 5 };
844126Szf162725 
854126Szf162725 /*
864126Szf162725  * EAPOL-Key Key Data Encapsulation
874126Szf162725  * GroupKey and STAKey require encryption, otherwise, encryption is optional.
884126Szf162725  */
894126Szf162725 static const uint8_t RSN_KEY_DATA_GROUPKEY[]	= { 0x00, 0x0f, 0xac, 1 };
904126Szf162725 static const uint8_t RSN_KEY_DATA_PMKID[]	= { 0x00, 0x0f, 0xac, 4 };
914126Szf162725 
924126Szf162725 /*
934126Szf162725  * 1/4: PMKID
944126Szf162725  * 2/4: RSN IE
954126Szf162725  * 3/4: one or two RSN IEs + GTK IE (encrypted)
964126Szf162725  * 4/4: empty
974126Szf162725  * 1/2: GTK IE (encrypted)
984126Szf162725  * 2/2: empty
994126Szf162725  */
1004126Szf162725 
1014126Szf162725 /*
1024126Szf162725  * RSN IE version 1
1034126Szf162725  * 0x01 0x00 (version; little endian)
1044126Szf162725  * (all following fields are optional:)
1054126Szf162725  * Group Suite Selector (4 octets) (default: CCMP)
1064126Szf162725  * Pairwise Suite Count (2 octets, little endian) (default: 1)
1074126Szf162725  * Pairwise Suite List (4 * n octets) (default: CCMP)
1084126Szf162725  * Authenticated Key Management Suite Count (2 octets, little endian)
1094126Szf162725  *    (default: 1)
1104126Szf162725  * Authenticated Key Management Suite List (4 * n octets)
1114126Szf162725  *    (default: unspec 802.1x)
1124126Szf162725  * RSN Capabilities (2 octets, little endian) (default: 0)
1134126Szf162725  * PMKID Count (2 octets) (default: 0)
1144126Szf162725  * PMKID List (16 * n octets)
1154126Szf162725  */
1164126Szf162725 #pragma pack(1)
1174126Szf162725 struct rsn_ie_hdr {
1184126Szf162725 	uint8_t		elem_id; /* WLAN_EID_RSN */
1194126Szf162725 	uint8_t		len;
1204126Szf162725 	uint16_t	version;
1214126Szf162725 };
1224126Szf162725 #pragma pack()
1234126Szf162725 
1244126Szf162725 static int
1254126Szf162725 random_get_pseudo_bytes(uint8_t *ptr, size_t len)
1264126Szf162725 {
1274126Szf162725 	int fd;
1284126Szf162725 	size_t resid = len;
1294126Szf162725 	size_t bytes;
1304126Szf162725 
1314126Szf162725 	fd = open("/dev/urandom", O_RDONLY);
1324126Szf162725 	if (fd == -1) {
1334126Szf162725 		wpa_printf(MSG_ERROR, "Could not open /dev/urandom.\n");
1344126Szf162725 		return (-1);
1354126Szf162725 	}
1364126Szf162725 
1374126Szf162725 	while (resid != 0) {
1384126Szf162725 		bytes = read(fd, ptr, resid);
1394126Szf162725 		ptr += bytes;
1404126Szf162725 		resid -= bytes;
1414126Szf162725 	}
1424126Szf162725 
1434126Szf162725 	(void) close(fd);
1444126Szf162725 
1454126Szf162725 	return (0);
1464126Szf162725 }
1474126Szf162725 
1484126Szf162725 static void
1494126Szf162725 inc_byte_array(uint8_t *counter, size_t len)
1504126Szf162725 {
1514126Szf162725 	int pos = len - 1;
1524126Szf162725 	while (pos >= 0) {
1534126Szf162725 		counter[pos]++;
1544126Szf162725 		if (counter[pos] != 0)
1554126Szf162725 			break;
1564126Szf162725 		pos--;
1574126Szf162725 	}
1584126Szf162725 }
1594126Szf162725 
1604126Szf162725 static int
1614126Szf162725 wpa_selector_to_bitfield(uint8_t *s)
1624126Szf162725 {
1634126Szf162725 	if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)
1644126Szf162725 		return (WPA_CIPHER_NONE);
1654126Szf162725 	if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0)
1664126Szf162725 		return (WPA_CIPHER_WEP40);
1674126Szf162725 	if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0)
1684126Szf162725 		return (WPA_CIPHER_TKIP);
1694126Szf162725 	if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0)
1704126Szf162725 		return (WPA_CIPHER_CCMP);
1714126Szf162725 	if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0)
1724126Szf162725 		return (WPA_CIPHER_WEP104);
1734126Szf162725 	return (0);
1744126Szf162725 }
1754126Szf162725 
1764126Szf162725 static int
1774126Szf162725 wpa_key_mgmt_to_bitfield(uint8_t *s)
1784126Szf162725 {
1794126Szf162725 	if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0)
1804126Szf162725 		return (WPA_KEY_MGMT_IEEE8021X);
1814126Szf162725 	if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) ==
1824126Szf162725 	    0)
1834126Szf162725 		return (WPA_KEY_MGMT_PSK);
1844126Szf162725 	return (0);
1854126Szf162725 }
1864126Szf162725 
1874126Szf162725 static int
1884126Szf162725 rsn_selector_to_bitfield(uint8_t *s)
1894126Szf162725 {
1904126Szf162725 	if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0)
1914126Szf162725 		return (WPA_CIPHER_NONE);
1924126Szf162725 	if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0)
1934126Szf162725 		return (WPA_CIPHER_WEP40);
1944126Szf162725 	if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0)
1954126Szf162725 		return (WPA_CIPHER_TKIP);
1964126Szf162725 	if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0)
1974126Szf162725 		return (WPA_CIPHER_CCMP);
1984126Szf162725 	if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0)
1994126Szf162725 		return (WPA_CIPHER_WEP104);
2004126Szf162725 	return (0);
2014126Szf162725 }
2024126Szf162725 
2034126Szf162725 static int
2044126Szf162725 rsn_key_mgmt_to_bitfield(uint8_t *s)
2054126Szf162725 {
2064126Szf162725 	if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0)
2074126Szf162725 		return (WPA_KEY_MGMT_IEEE8021X);
2084126Szf162725 	if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) ==
2094126Szf162725 	    0)
2104126Szf162725 		return (WPA_KEY_MGMT_PSK);
2114126Szf162725 	return (0);
2124126Szf162725 }
2134126Szf162725 
2144126Szf162725 static void
2154126Szf162725 pmksa_cache_free_entry(struct wpa_supplicant *wpa_s,
2164126Szf162725 	struct rsn_pmksa_cache *entry)
2174126Szf162725 {
2184126Szf162725 	wpa_s->pmksa_count--;
2194126Szf162725 	if (wpa_s->cur_pmksa == entry) {
2204126Szf162725 		wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA entry");
2214126Szf162725 		wpa_s->cur_pmksa = NULL;
2224126Szf162725 	}
2234126Szf162725 	free(entry);
2244126Szf162725 }
2254126Szf162725 
2264126Szf162725 /* ARGSUSED */
2274126Szf162725 static void
2284126Szf162725 pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
2294126Szf162725 {
2304126Szf162725 	struct wpa_supplicant *wpa_s = eloop_ctx;
2314126Szf162725 	time_t now;
2324126Szf162725 
2334126Szf162725 	(void) time(&now);
2344126Szf162725 	while (wpa_s->pmksa && wpa_s->pmksa->expiration <= now) {
2354126Szf162725 		struct rsn_pmksa_cache *entry = wpa_s->pmksa;
2364126Szf162725 		wpa_s->pmksa = entry->next;
2374126Szf162725 		wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
2384126Szf162725 		    MACSTR, MAC2STR(entry->aa));
2394126Szf162725 		pmksa_cache_free_entry(wpa_s, entry);
2404126Szf162725 	}
2414126Szf162725 
2424126Szf162725 	pmksa_cache_set_expiration(wpa_s);
2434126Szf162725 }
2444126Szf162725 
2454126Szf162725 static void
2464126Szf162725 pmksa_cache_set_expiration(struct wpa_supplicant *wpa_s)
2474126Szf162725 {
2484126Szf162725 	int sec;
2494126Szf162725 	eloop_cancel_timeout(pmksa_cache_expire, wpa_s, NULL);
2504126Szf162725 	if (wpa_s->pmksa == NULL)
2514126Szf162725 		return;
2524126Szf162725 	sec = wpa_s->pmksa->expiration - time(NULL);
2534126Szf162725 	if (sec < 0)
2544126Szf162725 		sec = 0;
2554126Szf162725 	(void) eloop_register_timeout(sec + 1, 0, pmksa_cache_expire,
2564126Szf162725 	    wpa_s, NULL);
2574126Szf162725 }
2584126Szf162725 
2594126Szf162725 void
2604126Szf162725 pmksa_cache_free(struct wpa_supplicant *wpa_s)
2614126Szf162725 {
2624126Szf162725 	struct rsn_pmksa_cache *entry, *prev;
2634126Szf162725 
2644126Szf162725 	entry = wpa_s->pmksa;
2654126Szf162725 	wpa_s->pmksa = NULL;
2664126Szf162725 	while (entry) {
2674126Szf162725 		prev = entry;
2684126Szf162725 		entry = entry->next;
2694126Szf162725 		free(prev);
2704126Szf162725 	}
2714126Szf162725 	pmksa_cache_set_expiration(wpa_s);
2724126Szf162725 	wpa_s->cur_pmksa = NULL;
2734126Szf162725 }
2744126Szf162725 
2754126Szf162725 struct rsn_pmksa_cache *
2764126Szf162725 pmksa_cache_get(struct wpa_supplicant *wpa_s,
2774126Szf162725 		uint8_t *aa, uint8_t *pmkid)
2784126Szf162725 {
2794126Szf162725 	struct rsn_pmksa_cache *entry = wpa_s->pmksa;
2804126Szf162725 	while (entry) {
2814126Szf162725 		if ((aa == NULL ||
2824126Szf162725 		    memcmp(entry->aa, aa, IEEE80211_ADDR_LEN) == 0) &&
2834126Szf162725 		    (pmkid == NULL ||
2844126Szf162725 		    memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
2854126Szf162725 			return (entry);
2864126Szf162725 		entry = entry->next;
2874126Szf162725 	}
2884126Szf162725 	return (NULL);
2894126Szf162725 }
2904126Szf162725 
2914126Szf162725 int
2924126Szf162725 pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf, size_t len)
2934126Szf162725 {
2944126Szf162725 	int i, j;
2954126Szf162725 	char *pos = buf;
2964126Szf162725 	struct rsn_pmksa_cache *entry;
2974126Szf162725 	time_t now;
2984126Szf162725 
2994126Szf162725 	(void) time(&now);
3004126Szf162725 	pos += snprintf(pos, buf + len - pos,
3014126Szf162725 	    "Index / AA / PMKID / expiration (in seconds)\n");
3024126Szf162725 	i = 0;
3034126Szf162725 	entry = wpa_s->pmksa;
3044126Szf162725 	while (entry) {
3054126Szf162725 		i++;
3064126Szf162725 		pos += snprintf(pos, buf + len - pos, "%d " MACSTR " ",
3074126Szf162725 		    i, MAC2STR(entry->aa));
3084126Szf162725 		for (j = 0; j < PMKID_LEN; j++)
3094126Szf162725 			pos += snprintf(pos, buf + len - pos, "%02x",
3104126Szf162725 			    entry->pmkid[j]);
3114126Szf162725 		pos += snprintf(pos, buf + len - pos, " %d\n",
3124126Szf162725 		    (int)(entry->expiration - now));
3134126Szf162725 		entry = entry->next;
3144126Szf162725 	}
3154126Szf162725 	return (pos - buf);
3164126Szf162725 }
3174126Szf162725 
3184126Szf162725 void
3194126Szf162725 pmksa_candidate_free(struct wpa_supplicant *wpa_s)
3204126Szf162725 {
3214126Szf162725 	struct rsn_pmksa_candidate *entry, *prev;
3224126Szf162725 
3234126Szf162725 	entry = wpa_s->pmksa_candidates;
3244126Szf162725 	wpa_s->pmksa_candidates = NULL;
3254126Szf162725 	while (entry) {
3264126Szf162725 		prev = entry;
3274126Szf162725 		entry = entry->next;
3284126Szf162725 		free(prev);
3294126Szf162725 	}
3304126Szf162725 }
3314126Szf162725 
3324126Szf162725 /* ARGSUSED */
3334126Szf162725 static int
3344126Szf162725 wpa_parse_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
3354126Szf162725     size_t wpa_ie_len, struct wpa_ie_data *data)
3364126Szf162725 {
3374126Szf162725 	struct wpa_ie_hdr *hdr;
3384126Szf162725 	uint8_t *pos;
3394126Szf162725 	int left;
3404126Szf162725 	int i, count;
3414126Szf162725 
3424126Szf162725 	data->proto = WPA_PROTO_WPA;
3434126Szf162725 	data->pairwise_cipher = WPA_CIPHER_TKIP;
3444126Szf162725 	data->group_cipher = WPA_CIPHER_TKIP;
3454126Szf162725 	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
3464126Szf162725 	data->capabilities = 0;
3474126Szf162725 
3484126Szf162725 	if (wpa_ie_len == 0) {
3494126Szf162725 		/* No WPA IE - fail silently */
3504126Szf162725 		return (-1);
3514126Szf162725 	}
3524126Szf162725 
3534126Szf162725 	if (wpa_ie_len < sizeof (struct wpa_ie_hdr)) {
3544126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
3554126Szf162725 		    "wpa_parse_wpa_ie_wpa", wpa_ie_len);
3564126Szf162725 		return (-1);
3574126Szf162725 	}
3584126Szf162725 
3594126Szf162725 	hdr = (struct wpa_ie_hdr *)wpa_ie;
3604126Szf162725 
3614126Szf162725 	if (hdr->elem_id != GENERIC_INFO_ELEM ||
3624126Szf162725 	    hdr->len != wpa_ie_len - 2 ||
363*6411Szf162725 	    memcmp(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN) != 0 ||
3644126Szf162725 	    LE_16(hdr->version) != WPA_VERSION) {
3654126Szf162725 		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
3664126Szf162725 		    "wpa_parse_wpa_ie_wpa");
3674126Szf162725 		return (-1);
3684126Szf162725 	}
3694126Szf162725 
3704126Szf162725 	pos = (uint8_t *)(hdr + 1);
3714126Szf162725 	left = wpa_ie_len - sizeof (*hdr);
3724126Szf162725 
3734126Szf162725 	if (left >= WPA_SELECTOR_LEN) {
3744126Szf162725 		data->group_cipher = wpa_selector_to_bitfield(pos);
3754126Szf162725 		pos += WPA_SELECTOR_LEN;
3764126Szf162725 		left -= WPA_SELECTOR_LEN;
3774126Szf162725 	} else if (left > 0) {
3784126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
3794126Szf162725 		    "wpa_parse_wpa_ie_wpa", left);
3804126Szf162725 		return (-1);
3814126Szf162725 	}
3824126Szf162725 
3834126Szf162725 	if (left >= 2) {
3844126Szf162725 		data->pairwise_cipher = 0;
3854126Szf162725 		count = pos[0] | (pos[1] << 8);
3864126Szf162725 		pos += 2;
3874126Szf162725 		left -= 2;
3884126Szf162725 		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
3894126Szf162725 			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
3904126Szf162725 			    "count %u left %u",
3914126Szf162725 			    "wpa_parse_wpa_ie_wpa", count, left);
3924126Szf162725 			return (-1);
3934126Szf162725 		}
3944126Szf162725 		for (i = 0; i < count; i++) {
3954126Szf162725 			data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
3964126Szf162725 			pos += WPA_SELECTOR_LEN;
3974126Szf162725 			left -= WPA_SELECTOR_LEN;
3984126Szf162725 		}
3994126Szf162725 	} else if (left == 1) {
4004126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
4014126Szf162725 		    "wpa_parse_wpa_ie_wpa");
4024126Szf162725 		return (-1);
4034126Szf162725 	}
4044126Szf162725 
4054126Szf162725 	if (left >= 2) {
4064126Szf162725 		data->key_mgmt = 0;
4074126Szf162725 		count = pos[0] | (pos[1] << 8);
4084126Szf162725 		pos += 2;
4094126Szf162725 		left -= 2;
4104126Szf162725 		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
4114126Szf162725 			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
4124126Szf162725 			    "count %u left %u",
4134126Szf162725 			    "wpa_parse_wpa_ie_wpa", count, left);
4144126Szf162725 			return (-1);
4154126Szf162725 		}
4164126Szf162725 		for (i = 0; i < count; i++) {
4174126Szf162725 			data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
4184126Szf162725 			pos += WPA_SELECTOR_LEN;
4194126Szf162725 			left -= WPA_SELECTOR_LEN;
4204126Szf162725 		}
4214126Szf162725 	} else if (left == 1) {
4224126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
4234126Szf162725 		    "wpa_parse_wpa_ie_wpa");
4244126Szf162725 		return (-1);
4254126Szf162725 	}
4264126Szf162725 
4274126Szf162725 	if (left >= 2) {
4284126Szf162725 		data->capabilities = pos[0] | (pos[1] << 8);
4294126Szf162725 		pos += 2;
4304126Szf162725 		left -= 2;
4314126Szf162725 	}
4324126Szf162725 
4334126Szf162725 	if (left > 0) {
4344126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes",
4354126Szf162725 		    "wpa_parse_wpa_ie_wpa", left);
4364126Szf162725 		return (-1);
4374126Szf162725 	}
4384126Szf162725 
4394126Szf162725 	return (0);
4404126Szf162725 }
4414126Szf162725 
4424126Szf162725 /* ARGSUSED */
4434126Szf162725 static int
4444126Szf162725 wpa_parse_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie,
4454126Szf162725     size_t rsn_ie_len, struct wpa_ie_data *data)
4464126Szf162725 {
4474126Szf162725 	struct rsn_ie_hdr *hdr;
4484126Szf162725 	uint8_t *pos;
4494126Szf162725 	int left;
4504126Szf162725 	int i, count;
4514126Szf162725 
4524126Szf162725 	data->proto = WPA_PROTO_RSN;
4534126Szf162725 	data->pairwise_cipher = WPA_CIPHER_CCMP;
4544126Szf162725 	data->group_cipher = WPA_CIPHER_CCMP;
4554126Szf162725 	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
4564126Szf162725 	data->capabilities = 0;
4574126Szf162725 
4584126Szf162725 	if (rsn_ie_len == 0) {
4594126Szf162725 		/* No RSN IE - fail silently */
4604126Szf162725 		return (-1);
4614126Szf162725 	}
4624126Szf162725 
4634126Szf162725 	if (rsn_ie_len < sizeof (struct rsn_ie_hdr)) {
4644126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
4654126Szf162725 		    "wpa_parse_wpa_ie_rsn", rsn_ie_len);
4664126Szf162725 		return (-1);
4674126Szf162725 	}
4684126Szf162725 
4694126Szf162725 	hdr = (struct rsn_ie_hdr *)rsn_ie;
4704126Szf162725 
4714126Szf162725 	if (hdr->elem_id != RSN_INFO_ELEM ||
4724126Szf162725 	    hdr->len != rsn_ie_len - 2 ||
4734126Szf162725 	    LE_16(hdr->version) != RSN_VERSION) {
4744126Szf162725 		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
4754126Szf162725 		    "wpa_parse_wpa_ie_rsn");
4764126Szf162725 		return (-1);
4774126Szf162725 	}
4784126Szf162725 
4794126Szf162725 	pos = (uint8_t *)(hdr + 1);
4804126Szf162725 	left = rsn_ie_len - sizeof (*hdr);
4814126Szf162725 
4824126Szf162725 	if (left >= RSN_SELECTOR_LEN) {
4834126Szf162725 		data->group_cipher = rsn_selector_to_bitfield(pos);
4844126Szf162725 		pos += RSN_SELECTOR_LEN;
4854126Szf162725 		left -= RSN_SELECTOR_LEN;
4864126Szf162725 	} else if (left > 0) {
4874126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
4884126Szf162725 		    "wpa_parse_wpa_ie_rsn", left);
4894126Szf162725 		return (-1);
4904126Szf162725 	}
4914126Szf162725 
4924126Szf162725 	if (left >= 2) {
4934126Szf162725 		data->pairwise_cipher = 0;
4944126Szf162725 		count = pos[0] | (pos[1] << 8);
4954126Szf162725 		pos += 2;
4964126Szf162725 		left -= 2;
4974126Szf162725 		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
4984126Szf162725 			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
4994126Szf162725 			    "count %u left %u",
5004126Szf162725 			    "wpa_parse_wpa_ie_rsn", count, left);
5014126Szf162725 			return (-1);
5024126Szf162725 		}
5034126Szf162725 		for (i = 0; i < count; i++) {
5044126Szf162725 			data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
5054126Szf162725 			pos += RSN_SELECTOR_LEN;
5064126Szf162725 			left -= RSN_SELECTOR_LEN;
5074126Szf162725 		}
5084126Szf162725 	} else if (left == 1) {
5094126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
5104126Szf162725 		    "wpa_parse_wpa_ie_rsn");
5114126Szf162725 		return (-1);
5124126Szf162725 	}
5134126Szf162725 
5144126Szf162725 	if (left >= 2) {
5154126Szf162725 		data->key_mgmt = 0;
5164126Szf162725 		count = pos[0] | (pos[1] << 8);
5174126Szf162725 		pos += 2;
5184126Szf162725 		left -= 2;
5194126Szf162725 		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
5204126Szf162725 			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
5214126Szf162725 			    "count %u left %u",
5224126Szf162725 			    "wpa_parse_wpa_ie_rsn", count, left);
5234126Szf162725 			return (-1);
5244126Szf162725 		}
5254126Szf162725 		for (i = 0; i < count; i++) {
5264126Szf162725 			data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
5274126Szf162725 			pos += RSN_SELECTOR_LEN;
5284126Szf162725 			left -= RSN_SELECTOR_LEN;
5294126Szf162725 		}
5304126Szf162725 	} else if (left == 1) {
5314126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
5324126Szf162725 		    "wpa_parse_wpa_ie_rsn");
5334126Szf162725 		return (-1);
5344126Szf162725 	}
5354126Szf162725 
5364126Szf162725 	if (left >= 2) {
5374126Szf162725 		data->capabilities = pos[0] | (pos[1] << 8);
5384126Szf162725 		pos += 2;
5394126Szf162725 		left -= 2;
5404126Szf162725 	}
5414126Szf162725 
5424126Szf162725 	if (left > 0) {
5434126Szf162725 		/*
5444126Szf162725 		 * RSN IE could include PMKID data, but Authenticator should
5454126Szf162725 		 * never include it, so no need to parse it in the Supplicant.
5464126Szf162725 		 */
5474126Szf162725 		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
5484126Szf162725 		    "wpa_parse_wpa_ie_rsn", left);
5494126Szf162725 	}
5504126Szf162725 
5514126Szf162725 	return (0);
5524126Szf162725 }
5534126Szf162725 
5544126Szf162725 int
5554126Szf162725 wpa_parse_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
5564126Szf162725     size_t wpa_ie_len, struct wpa_ie_data *data)
5574126Szf162725 {
5584126Szf162725 	if (wpa_ie_len >= 1 && wpa_ie[0] == RSN_INFO_ELEM)
5594126Szf162725 		return (wpa_parse_wpa_ie_rsn(wpa_s, wpa_ie, wpa_ie_len, data));
5604126Szf162725 	else
5614126Szf162725 		return (wpa_parse_wpa_ie_wpa(wpa_s, wpa_ie, wpa_ie_len, data));
5624126Szf162725 }
5634126Szf162725 
5644126Szf162725 static int
5654126Szf162725 wpa_gen_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
5664126Szf162725 {
5674126Szf162725 	uint8_t *pos;
5684126Szf162725 	struct wpa_ie_hdr *hdr;
5694126Szf162725 
5704126Szf162725 	hdr = (struct wpa_ie_hdr *)wpa_ie;
5714126Szf162725 	hdr->elem_id = GENERIC_INFO_ELEM;
572*6411Szf162725 	(void) memcpy(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN);
5734126Szf162725 	hdr->version = LE_16(WPA_VERSION);
5744126Szf162725 	pos = (uint8_t *)(hdr + 1);
5754126Szf162725 
5764126Szf162725 	if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
5774126Szf162725 		(void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
5784126Szf162725 	} else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
5794126Szf162725 		(void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
5804126Szf162725 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
5814126Szf162725 		(void) memcpy(pos, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN);
5824126Szf162725 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
5834126Szf162725 		(void) memcpy(pos, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN);
5844126Szf162725 	} else {
5854126Szf162725 		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
5864126Szf162725 		    wpa_s->group_cipher);
5874126Szf162725 		return (-1);
5884126Szf162725 	}
5894126Szf162725 	pos += WPA_SELECTOR_LEN;
5904126Szf162725 
5914126Szf162725 	*pos++ = 1;
5924126Szf162725 	*pos++ = 0;
5934126Szf162725 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
5944126Szf162725 		(void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
5954126Szf162725 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
5964126Szf162725 		(void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
5974126Szf162725 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
5984126Szf162725 		(void) memcpy(pos, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN);
5994126Szf162725 	} else {
6004126Szf162725 		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
6014126Szf162725 		    wpa_s->pairwise_cipher);
6024126Szf162725 		return (-1);
6034126Szf162725 	}
6044126Szf162725 	pos += WPA_SELECTOR_LEN;
6054126Szf162725 
6064126Szf162725 	*pos++ = 1;
6074126Szf162725 	*pos++ = 0;
6084126Szf162725 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
6094126Szf162725 		(void) memcpy(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X,
6104126Szf162725 		    WPA_SELECTOR_LEN);
6114126Szf162725 	} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
6124126Szf162725 		(void) memcpy(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X,
6134126Szf162725 		    WPA_SELECTOR_LEN);
6144126Szf162725 	} else {
6154126Szf162725 		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
6164126Szf162725 		    wpa_s->key_mgmt);
6174126Szf162725 		return (-1);
6184126Szf162725 	}
6194126Szf162725 	pos += WPA_SELECTOR_LEN;
6204126Szf162725 
6214126Szf162725 	/*
6224126Szf162725 	 * WPA Capabilities; use defaults, so no need to include it
6234126Szf162725 	 */
6244126Szf162725 	hdr->len = (pos - wpa_ie) - 2;
6254126Szf162725 
6264126Szf162725 	return (pos - wpa_ie);
6274126Szf162725 }
6284126Szf162725 
6294126Szf162725 static int
6304126Szf162725 wpa_gen_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie)
6314126Szf162725 {
6324126Szf162725 	uint8_t *pos;
6334126Szf162725 	struct rsn_ie_hdr *hdr;
6344126Szf162725 
6354126Szf162725 	hdr = (struct rsn_ie_hdr *)rsn_ie;
6364126Szf162725 	hdr->elem_id = RSN_INFO_ELEM;
6374126Szf162725 	hdr->version = LE_16(RSN_VERSION);
6384126Szf162725 	pos = (uint8_t *)(hdr + 1);
6394126Szf162725 
6404126Szf162725 	if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
6414126Szf162725 		(void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
6424126Szf162725 	} else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
6434126Szf162725 		(void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
6444126Szf162725 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
6454126Szf162725 		(void) memcpy(pos, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN);
6464126Szf162725 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
6474126Szf162725 		(void) memcpy(pos, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN);
6484126Szf162725 	} else {
6494126Szf162725 		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
6504126Szf162725 		    wpa_s->group_cipher);
6514126Szf162725 		return (-1);
6524126Szf162725 	}
6534126Szf162725 	pos += RSN_SELECTOR_LEN;
6544126Szf162725 
6554126Szf162725 	*pos++ = 1;
6564126Szf162725 	*pos++ = 0;
6574126Szf162725 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
6584126Szf162725 		(void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
6594126Szf162725 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
6604126Szf162725 		(void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
6614126Szf162725 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
6624126Szf162725 		(void) memcpy(pos, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN);
6634126Szf162725 	} else {
6644126Szf162725 		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
6654126Szf162725 		    wpa_s->pairwise_cipher);
6664126Szf162725 		return (-1);
6674126Szf162725 	}
6684126Szf162725 	pos += RSN_SELECTOR_LEN;
6694126Szf162725 
6704126Szf162725 	*pos++ = 1;
6714126Szf162725 	*pos++ = 0;
6724126Szf162725 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
6734126Szf162725 		(void) memcpy(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X,
6744126Szf162725 		    RSN_SELECTOR_LEN);
6754126Szf162725 	} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
6764126Szf162725 		(void) memcpy(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X,
6774126Szf162725 		    RSN_SELECTOR_LEN);
6784126Szf162725 	} else {
6794126Szf162725 		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
6804126Szf162725 		    wpa_s->key_mgmt);
6814126Szf162725 		return (-1);
6824126Szf162725 	}
6834126Szf162725 	pos += RSN_SELECTOR_LEN;
6844126Szf162725 
6854126Szf162725 	/* RSN Capabilities */
6864126Szf162725 	*pos++ = 0;
6874126Szf162725 	*pos++ = 0;
6884126Szf162725 
6894126Szf162725 	if (wpa_s->cur_pmksa) {
6904126Szf162725 		/* PMKID Count (2 octets, little endian) */
6914126Szf162725 		*pos++ = 1;
6924126Szf162725 		*pos++ = 0;
6934126Szf162725 		/* PMKID */
6944126Szf162725 		(void) memcpy(pos, wpa_s->cur_pmksa->pmkid, PMKID_LEN);
6954126Szf162725 		pos += PMKID_LEN;
6964126Szf162725 	}
6974126Szf162725 
6984126Szf162725 	hdr->len = (pos - rsn_ie) - 2;
6994126Szf162725 
7004126Szf162725 	return (pos - rsn_ie);
7014126Szf162725 }
7024126Szf162725 
7034126Szf162725 int
7044126Szf162725 wpa_gen_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
7054126Szf162725 {
7064126Szf162725 	if (wpa_s->proto == WPA_PROTO_RSN)
7074126Szf162725 		return (wpa_gen_wpa_ie_rsn(wpa_s, wpa_ie));
7084126Szf162725 	else
7094126Szf162725 		return (wpa_gen_wpa_ie_wpa(wpa_s, wpa_ie));
7104126Szf162725 }
7114126Szf162725 
7124126Szf162725 static void
7134126Szf162725 wpa_pmk_to_ptk(uint8_t *pmk, uint8_t *addr1, uint8_t *addr2,
7144126Szf162725     uint8_t *nonce1, uint8_t *nonce2, uint8_t *ptk, size_t ptk_len)
7154126Szf162725 {
7164126Szf162725 	uint8_t data[2 * IEEE80211_ADDR_LEN + 2 * WPA_PMK_LEN];
7174126Szf162725 
7184126Szf162725 	/*
7194126Szf162725 	 * PTK = PRF-X(PMK, "Pairwise key expansion",
7204126Szf162725 	 * 	Min(AA, SA) || Max(AA, SA) ||
7214126Szf162725 	 * 	Min(ANonce, SNonce) || Max(ANonce, SNonce))
7224126Szf162725 	 */
7234126Szf162725 
7244126Szf162725 	if (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) < 0) {
7254126Szf162725 		(void) memcpy(data, addr1, IEEE80211_ADDR_LEN);
7264126Szf162725 		(void) memcpy(data + IEEE80211_ADDR_LEN, addr2,
7274126Szf162725 		    IEEE80211_ADDR_LEN);
7284126Szf162725 	} else {
7294126Szf162725 		(void) memcpy(data, addr2, IEEE80211_ADDR_LEN);
7304126Szf162725 		(void) memcpy(data + IEEE80211_ADDR_LEN, addr1,
7314126Szf162725 		    IEEE80211_ADDR_LEN);
7324126Szf162725 	}
7334126Szf162725 
7344126Szf162725 	if (memcmp(nonce1, nonce2, WPA_PMK_LEN) < 0) {
7354126Szf162725 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce1,
7364126Szf162725 		    WPA_PMK_LEN);
7374126Szf162725 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
7384126Szf162725 		    nonce2, WPA_PMK_LEN);
7394126Szf162725 	} else {
7404126Szf162725 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce2,
7414126Szf162725 		    WPA_PMK_LEN);
7424126Szf162725 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
7434126Szf162725 		    nonce1, WPA_PMK_LEN);
7444126Szf162725 	}
7454126Szf162725 
7464126Szf162725 	sha1_prf(pmk, WPA_PMK_LEN, "Pairwise key expansion", data,
7474126Szf162725 	    sizeof (data), ptk, ptk_len);
7484126Szf162725 
7494126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: PMK", pmk, WPA_PMK_LEN);
7504126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
7514126Szf162725 }
7524126Szf162725 
7534126Szf162725 struct wpa_ssid *
7544126Szf162725 wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
7554126Szf162725 {
7564126Szf162725 	struct wpa_ssid *entry;
7574126Szf162725 	uint8_t ssid[MAX_ESSID_LENGTH];
7584126Szf162725 	int ssid_len;
7594126Szf162725 	uint8_t bssid[IEEE80211_ADDR_LEN];
7604126Szf162725 
7614126Szf162725 	(void) memset(ssid, 0, MAX_ESSID_LENGTH);
7625895Syz147064 	ssid_len = wpa_s->driver->get_ssid(wpa_s->linkid, (char *)ssid);
7634126Szf162725 	if (ssid_len < 0) {
7644126Szf162725 		wpa_printf(MSG_WARNING, "Could not read SSID from driver.");
7654126Szf162725 		return (NULL);
7664126Szf162725 	}
7674126Szf162725 
7685895Syz147064 	if (wpa_s->driver->get_bssid(wpa_s->linkid, (char *)bssid) < 0) {
7694126Szf162725 		wpa_printf(MSG_WARNING, "Could not read BSSID from driver.");
7704126Szf162725 		return (NULL);
7714126Szf162725 	}
7724126Szf162725 
7734126Szf162725 	entry = wpa_s->conf->ssid;
7744126Szf162725 	wpa_printf(MSG_DEBUG, "entry len=%d ssid=%s,"
7754126Szf162725 	    " driver len=%d ssid=%s",
7764126Szf162725 	    entry->ssid_len, entry->ssid, ssid_len, ssid);
7774126Szf162725 
7784126Szf162725 	if (ssid_len == entry->ssid_len &&
7794126Szf162725 	    memcmp(ssid, entry->ssid, ssid_len) == 0 &&
7804126Szf162725 	    (!entry->bssid_set ||
7814126Szf162725 	    memcmp(bssid, entry->bssid, IEEE80211_ADDR_LEN) == 0))
7824126Szf162725 		return (entry);
7834126Szf162725 
7844126Szf162725 	return (NULL);
7854126Szf162725 }
7864126Szf162725 
7874126Szf162725 static void
7884126Szf162725 wpa_eapol_key_mic(uint8_t *key, int ver, uint8_t *buf, size_t len, uint8_t *mic)
7894126Szf162725 {
7904126Szf162725 	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
7914126Szf162725 		hmac_md5(key, 16, buf, len, mic);
7924126Szf162725 	} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
7934126Szf162725 		uint8_t hash[SHA1_MAC_LEN];
7944126Szf162725 		hmac_sha1(key, 16, buf, len, hash);
7954126Szf162725 		(void) memcpy(mic, hash, MD5_MAC_LEN);
7964126Szf162725 	}
7974126Szf162725 }
7984126Szf162725 
7994126Szf162725 void
8004126Szf162725 wpa_supplicant_key_request(struct wpa_supplicant *wpa_s,
8014126Szf162725 	int error, int pairwise)
8024126Szf162725 {
8034126Szf162725 	int rlen;
8044126Szf162725 	struct ieee802_1x_hdr *hdr;
8054126Szf162725 	struct wpa_eapol_key *reply;
8064126Szf162725 	unsigned char *rbuf;
8074126Szf162725 	struct l2_ethhdr *ethhdr;
8084126Szf162725 	int key_info, ver;
8094126Szf162725 	uint8_t bssid[IEEE80211_ADDR_LEN];
8104126Szf162725 
8114126Szf162725 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP)
8124126Szf162725 		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
8134126Szf162725 	else
8144126Szf162725 		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
8154126Szf162725 
8165895Syz147064 	if (wpa_s->driver->get_bssid(wpa_s->linkid, (char *)bssid) < 0) {
8174126Szf162725 		wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
8184126Szf162725 		    "request");
8194126Szf162725 		return;
8204126Szf162725 	}
8214126Szf162725 
8224126Szf162725 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
8234126Szf162725 	rbuf = malloc(rlen);
8244126Szf162725 	if (rbuf == NULL)
8254126Szf162725 		return;
8264126Szf162725 
8274126Szf162725 	(void) memset(rbuf, 0, rlen);
8284126Szf162725 	ethhdr = (struct l2_ethhdr *)rbuf;
8294126Szf162725 	(void) memcpy(ethhdr->h_dest, bssid, IEEE80211_ADDR_LEN);
8304126Szf162725 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
8314126Szf162725 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
8324126Szf162725 
8334126Szf162725 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
8344126Szf162725 	hdr->version = wpa_s->conf->eapol_version;
8354126Szf162725 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
8364126Szf162725 	hdr->length = htons(sizeof (*reply));
8374126Szf162725 
8384126Szf162725 	reply = (struct wpa_eapol_key *)(hdr + 1);
8394126Szf162725 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
8405895Syz147064 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
8414126Szf162725 	key_info = WPA_KEY_INFO_REQUEST | ver;
8424126Szf162725 	if (wpa_s->ptk_set)
8434126Szf162725 		key_info |= WPA_KEY_INFO_MIC;
8444126Szf162725 	if (error)
8454126Szf162725 		key_info |= WPA_KEY_INFO_ERROR;
8464126Szf162725 	if (pairwise)
8474126Szf162725 		key_info |= WPA_KEY_INFO_KEY_TYPE;
8484126Szf162725 	reply->key_info = BE_16(key_info);
8494126Szf162725 	reply->key_length = 0;
8504126Szf162725 	(void) memcpy(reply->replay_counter, wpa_s->request_counter,
8515895Syz147064 	    WPA_REPLAY_COUNTER_LEN);
8524126Szf162725 	inc_byte_array(wpa_s->request_counter, WPA_REPLAY_COUNTER_LEN);
8534126Szf162725 
8544126Szf162725 	reply->key_data_length = BE_16(0);
8554126Szf162725 
8564126Szf162725 	if (key_info & WPA_KEY_INFO_MIC) {
8574126Szf162725 		wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
8584126Szf162725 		    rlen - sizeof (*ethhdr), reply->key_mic);
8594126Szf162725 	}
8604126Szf162725 
8614126Szf162725 	wpa_printf(MSG_INFO, "WPA: Sending EAPOL-Key Request (error=%d "
8624126Szf162725 	    "pairwise=%d ptk_set=%d len=%d)",
8634126Szf162725 	    error, pairwise, wpa_s->ptk_set, rlen);
8644126Szf162725 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key Request", rbuf, rlen);
8654126Szf162725 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
8664126Szf162725 	free(rbuf);
8674126Szf162725 }
8684126Szf162725 
8694126Szf162725 static void
8704126Szf162725 wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
8714126Szf162725     unsigned char *src_addr, struct wpa_eapol_key *key, int ver)
8724126Szf162725 {
8734126Szf162725 	int rlen;
8744126Szf162725 	struct ieee802_1x_hdr *hdr;
8754126Szf162725 	struct wpa_eapol_key *reply;
8764126Szf162725 	unsigned char *rbuf;
8774126Szf162725 	struct l2_ethhdr *ethhdr;
8784126Szf162725 	struct wpa_ssid *ssid;
8794126Szf162725 	struct wpa_ptk *ptk;
8804126Szf162725 	uint8_t buf[8], wpa_ie_buf[80], *wpa_ie, *pmkid = NULL;
8814126Szf162725 	int wpa_ie_len;
8824126Szf162725 
8834126Szf162725 	wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
8844126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from "
8854126Szf162725 	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
8864126Szf162725 
8874126Szf162725 	ssid = wpa_supplicant_get_ssid(wpa_s);
8884126Szf162725 	if (ssid == NULL) {
8894126Szf162725 		wpa_printf(MSG_WARNING,
8904126Szf162725 		    "WPA: No SSID info found (msg 1 of 4).");
8914126Szf162725 		return;
8924126Szf162725 	}
8934126Szf162725 
8944126Szf162725 	if (wpa_s->proto == WPA_PROTO_RSN) {
8954126Szf162725 		/* RSN: msg 1/4 should contain PMKID for the selected PMK */
8964126Szf162725 		uint8_t *pos = (uint8_t *)(key + 1);
8974126Szf162725 		uint8_t *end = pos + BE_16(key->key_data_length);
8984126Szf162725 
8994126Szf162725 		wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
9004126Szf162725 		    pos, BE_16(key->key_data_length));
9014126Szf162725 
9024126Szf162725 		while (pos + 1 < end) {
9034126Szf162725 			if (pos + 2 + pos[1] > end) {
9044126Szf162725 				wpa_printf(MSG_DEBUG, "RSN: key data "
9054126Szf162725 				    "underflow (ie=%d len=%d)",
9064126Szf162725 				    pos[0], pos[1]);
9074126Szf162725 				break;
9084126Szf162725 			}
9094126Szf162725 			if (pos[0] == GENERIC_INFO_ELEM &&
9105895Syz147064 			    pos + 1 + RSN_SELECTOR_LEN < end &&
9115895Syz147064 			    pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
9125895Syz147064 			    memcmp(pos + 2, RSN_KEY_DATA_PMKID,
9135895Syz147064 			    RSN_SELECTOR_LEN) == 0) {
9144126Szf162725 				pmkid = pos + 2 + RSN_SELECTOR_LEN;
9154126Szf162725 				wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
9164126Szf162725 				    "Authenticator", pmkid, PMKID_LEN);
9174126Szf162725 				break;
9184126Szf162725 			} else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0)
9194126Szf162725 				break;
9204126Szf162725 			pos += 2 + pos[1];
9214126Szf162725 		}
9224126Szf162725 	}
9234126Szf162725 
9244126Szf162725 	wpa_ie = wpa_ie_buf;
9254126Szf162725 	wpa_ie_len = wpa_gen_wpa_ie(wpa_s, wpa_ie);
9264126Szf162725 	if (wpa_ie_len < 0) {
9274126Szf162725 		wpa_printf(MSG_WARNING, "WPA: Failed to generate "
9284126Szf162725 		    "WPA IE (for msg 2 of 4).");
9294126Szf162725 		return;
9304126Szf162725 	}
9314126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
9324126Szf162725 
9334126Szf162725 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply) + wpa_ie_len;
9344126Szf162725 	rbuf = malloc(rlen);
9354126Szf162725 	if (rbuf == NULL)
9364126Szf162725 		return;
9374126Szf162725 
9384126Szf162725 	(void) memset(rbuf, 0, rlen);
9394126Szf162725 	ethhdr = (struct l2_ethhdr *)rbuf;
9404126Szf162725 	(void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
9414126Szf162725 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
9424126Szf162725 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
9434126Szf162725 
9444126Szf162725 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
9454126Szf162725 	hdr->version = wpa_s->conf->eapol_version;
9464126Szf162725 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
9474126Szf162725 	hdr->length = htons(sizeof (*reply) + wpa_ie_len);
9484126Szf162725 
9494126Szf162725 	reply = (struct wpa_eapol_key *)(hdr + 1);
9504126Szf162725 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
9515895Syz147064 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
9525895Syz147064 	reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
9534126Szf162725 	reply->key_length = key->key_length;
9544126Szf162725 	(void) memcpy(reply->replay_counter, key->replay_counter,
9555895Syz147064 	    WPA_REPLAY_COUNTER_LEN);
9564126Szf162725 
9574126Szf162725 	reply->key_data_length = BE_16(wpa_ie_len);
9584126Szf162725 	(void) memcpy(reply + 1, wpa_ie, wpa_ie_len);
9594126Szf162725 
9604126Szf162725 	if (wpa_s->renew_snonce) {
9614126Szf162725 		if (random_get_pseudo_bytes(wpa_s->snonce, WPA_NONCE_LEN)) {
9624126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Failed to get "
9634126Szf162725 			    "random data for SNonce");
9644126Szf162725 			free(rbuf);
9654126Szf162725 			return;
9664126Szf162725 		}
9674126Szf162725 
9684126Szf162725 		wpa_s->renew_snonce = 0;
9694126Szf162725 		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
9704126Szf162725 		    wpa_s->snonce, WPA_NONCE_LEN);
9714126Szf162725 	}
9724126Szf162725 	(void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN);
9734126Szf162725 	ptk = &wpa_s->tptk;
9744126Szf162725 	(void) memcpy(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN);
9754126Szf162725 
9764126Szf162725 	wpa_pmk_to_ptk(wpa_s->pmk, wpa_s->own_addr, src_addr,
9774126Szf162725 	    wpa_s->snonce, key->key_nonce, (uint8_t *)ptk, sizeof (*ptk));
9784126Szf162725 
9794126Szf162725 	/*
9804126Szf162725 	 * Supplicant: swap tx/rx Mic keys
9814126Szf162725 	 */
9824126Szf162725 	(void) memcpy(buf, ptk->u.auth.tx_mic_key, 8);
9834126Szf162725 	(void) memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
9844126Szf162725 	(void) memcpy(ptk->u.auth.rx_mic_key, buf, 8);
9854126Szf162725 	wpa_s->tptk_set = 1;
9864126Szf162725 	wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, (uint8_t *)hdr,
9875895Syz147064 	    rlen - sizeof (*ethhdr), reply->key_mic);
9884126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: EAPOL-Key MIC", reply->key_mic, 16);
9894126Szf162725 
9904126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
9914126Szf162725 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/4", rbuf, rlen);
9924126Szf162725 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
9934126Szf162725 
9944126Szf162725 	free(rbuf);
9954126Szf162725 }
9964126Szf162725 
9974126Szf162725 static void
9984126Szf162725 wpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant *wpa_s,
9994126Szf162725     unsigned char *src_addr, struct wpa_eapol_key *key,
10004126Szf162725     uint8_t *gtk, int gtk_len)
10014126Szf162725 {
10024126Szf162725 	int keyidx, tx, key_rsc_len = 0, alg;
10034126Szf162725 
10044126Szf162725 	wpa_hexdump(MSG_DEBUG,
10054126Szf162725 	    "WPA: received GTK in pairwise handshake", gtk, gtk_len);
10064126Szf162725 
10074126Szf162725 	keyidx = gtk[0] & 0x3;
10084126Szf162725 	tx = !!(gtk[0] & BIT(2));
10094126Szf162725 	if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
10104126Szf162725 		/*
10114126Szf162725 		 * Ignore Tx bit in GTK IE if a pairwise key is used.
10124126Szf162725 		 * One AP seemed to set this bit (incorrectly, since Tx
10134126Szf162725 		 * is only when doing Group Key only APs) and without
10144126Szf162725 		 * this workaround, the data connection does not work
10154126Szf162725 		 * because wpa_supplicant configured non-zero keyidx to
10164126Szf162725 		 * be used for unicast.
10174126Szf162725 		 */
10184126Szf162725 		wpa_printf(MSG_INFO, "RSN: Tx bit set for GTK IE, but "
10194126Szf162725 		    "pairwise keys are used - ignore Tx bit");
10204126Szf162725 		tx = 0;
10214126Szf162725 	}
10224126Szf162725 
10234126Szf162725 	gtk += 2;
10244126Szf162725 	gtk_len -= 2;
10254126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, gtk_len);
10264126Szf162725 
10274126Szf162725 	switch (wpa_s->group_cipher) {
10284126Szf162725 	case WPA_CIPHER_CCMP:
10294126Szf162725 		if (gtk_len != 16) {
10304126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP"
10314126Szf162725 			    " Group Cipher key length %d.", gtk_len);
10324126Szf162725 			return;
10334126Szf162725 		}
10344126Szf162725 		key_rsc_len = 6;
10354126Szf162725 		alg = WPA_ALG_CCMP;
10364126Szf162725 		break;
10374126Szf162725 	case WPA_CIPHER_TKIP:
10384126Szf162725 		if (gtk_len != 32) {
10394126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP"
10404126Szf162725 			    " Group Cipher key length %d.", gtk_len);
10414126Szf162725 			return;
10424126Szf162725 		}
10434126Szf162725 		key_rsc_len = 6;
10444126Szf162725 		alg = WPA_ALG_TKIP;
10454126Szf162725 		break;
10464126Szf162725 	case WPA_CIPHER_WEP104:
10474126Szf162725 		if (gtk_len != 13) {
10484126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported "
10494126Szf162725 			    "WEP104 Group Cipher key length " "%d.", gtk_len);
10504126Szf162725 			return;
10514126Szf162725 		}
10524126Szf162725 		alg = WPA_ALG_WEP;
10534126Szf162725 		break;
10544126Szf162725 	case WPA_CIPHER_WEP40:
10554126Szf162725 		if (gtk_len != 5) {
10564126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported "
10574126Szf162725 			    "WEP40 Group Cipher key length %d.", gtk_len);
10584126Szf162725 			return;
10594126Szf162725 		}
10604126Szf162725 		alg = WPA_ALG_WEP;
10614126Szf162725 		break;
10624126Szf162725 	default:
10634126Szf162725 		wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher "
10644126Szf162725 		    "%d", wpa_s->group_cipher);
10654126Szf162725 		return;
10664126Szf162725 	}
10674126Szf162725 
10684126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "
10694126Szf162725 	    "(keyidx=%d tx=%d).", keyidx, tx);
10704126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len);
10714126Szf162725 	if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
10724126Szf162725 		uint8_t tmpbuf[8];
10734126Szf162725 		/*
10744126Szf162725 		 * Swap Tx/Rx keys for Michael MIC
10754126Szf162725 		 */
10764126Szf162725 		(void) memcpy(tmpbuf, gtk + 16, 8);
10774126Szf162725 		(void) memcpy(gtk + 16, gtk + 24, 8);
10784126Szf162725 		(void) memcpy(gtk + 24, tmpbuf, 8);
10794126Szf162725 	}
10804126Szf162725 	if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
10815895Syz147064 		if (wpa_s->driver->set_key(wpa_s->linkid, alg,
10824126Szf162725 		    (uint8_t *)"\xff\xff\xff\xff\xff\xff",
10834126Szf162725 		    keyidx, 1, key->key_rsc,
10844126Szf162725 		    key_rsc_len, gtk, gtk_len) < 0)
10854126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Failed to set "
10864126Szf162725 			    "GTK to the driver (Group only).");
10875895Syz147064 	} else if (wpa_s->driver->set_key(wpa_s->linkid, alg,
10885895Syz147064 	    (uint8_t *)"\xff\xff\xff\xff\xff\xff", keyidx, tx,
10895895Syz147064 	    key->key_rsc, key_rsc_len, gtk, gtk_len) < 0) {
10904126Szf162725 		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "
10914126Szf162725 		    "the driver.");
10924126Szf162725 	}
10934126Szf162725 
10944126Szf162725 	wpa_printf(MSG_INFO, "WPA: Key negotiation completed with "
10955895Syz147064 	    MACSTR, MAC2STR(src_addr));
10964126Szf162725 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
10974126Szf162725 	wpa_supplicant_cancel_auth_timeout(wpa_s);
10984126Szf162725 	wpa_s->wpa_state = WPA_COMPLETED;
10994126Szf162725 }
11004126Szf162725 
11014126Szf162725 static void
11024126Szf162725 wpa_supplicant_process_3_of_4(struct wpa_supplicant *wpa_s,
11034126Szf162725     unsigned char *src_addr, struct wpa_eapol_key *key,
11044126Szf162725     int extra_len, int ver)
11054126Szf162725 {
11064126Szf162725 	int rlen;
11074126Szf162725 	struct ieee802_1x_hdr *hdr;
11084126Szf162725 	struct wpa_eapol_key *reply;
11094126Szf162725 	unsigned char *rbuf;
11104126Szf162725 	struct l2_ethhdr *ethhdr;
11114126Szf162725 	int key_info, ie_len = 0, keylen, gtk_len = 0;
11124126Szf162725 	uint8_t *ie = NULL, *gtk = NULL, *key_rsc;
11134126Szf162725 	uint8_t null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
11144126Szf162725 
11154126Szf162725 	wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
11164126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from "
11174126Szf162725 	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
11184126Szf162725 
11194126Szf162725 	key_info = BE_16(key->key_info);
11204126Szf162725 
11214126Szf162725 	if (wpa_s->proto == WPA_PROTO_RSN) {
11224126Szf162725 		uint8_t *pos = (uint8_t *)(key + 1);
11234126Szf162725 		uint8_t *end = pos + BE_16(key->key_data_length);
11244126Szf162725 		while (pos + 1 < end) {
11254126Szf162725 			if (pos + 2 + pos[1] > end) {
11264126Szf162725 				wpa_printf(MSG_DEBUG, "RSN: key data "
11274126Szf162725 				    "underflow (ie=%d len=%d)",
11284126Szf162725 				    pos[0], pos[1]);
11294126Szf162725 				break;
11304126Szf162725 			}
11314126Szf162725 			if (*pos == RSN_INFO_ELEM) {
11324126Szf162725 				ie = pos;
11334126Szf162725 				ie_len = pos[1] + 2;
11344126Szf162725 			} else if (pos[0] == GENERIC_INFO_ELEM &&
11355895Syz147064 			    pos + 1 + RSN_SELECTOR_LEN < end &&
11365895Syz147064 			    pos[1] > RSN_SELECTOR_LEN + 2 &&
11375895Syz147064 			    memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY,
11385895Syz147064 			    RSN_SELECTOR_LEN) == 0) {
11394126Szf162725 				if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
11404126Szf162725 					wpa_printf(MSG_WARNING, "WPA: GTK IE "
11414126Szf162725 					    "in unencrypted key data");
11424126Szf162725 					return;
11434126Szf162725 				}
11444126Szf162725 				gtk = pos + 2 + RSN_SELECTOR_LEN;
11454126Szf162725 				gtk_len = pos[1] - RSN_SELECTOR_LEN;
11464126Szf162725 			} else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0)
11474126Szf162725 				break;
11484126Szf162725 
11494126Szf162725 			pos += 2 + pos[1];
11504126Szf162725 		}
11514126Szf162725 	} else {
11524126Szf162725 		ie = (uint8_t *)(key + 1);
11534126Szf162725 		ie_len = BE_16(key->key_data_length);
11544126Szf162725 		if (ie_len > extra_len) {
11554126Szf162725 			wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"
11564126Szf162725 			    " ie_len=%d > extra_len=%d",
11574126Szf162725 			    ie_len, extra_len);
11584126Szf162725 			return;
11594126Szf162725 		}
11604126Szf162725 	}
11614126Szf162725 
11624126Szf162725 	if (wpa_s->ap_wpa_ie &&
11634126Szf162725 	    (wpa_s->ap_wpa_ie_len != ie_len ||
11645895Syz147064 	    memcmp(wpa_s->ap_wpa_ie, ie, ie_len) != 0)) {
11654126Szf162725 		wpa_printf(MSG_WARNING, "WPA: WPA IE in 3/4 msg does not match"
11664126Szf162725 		    " with WPA IE in Beacon/ProbeResp (src=" MACSTR ")",
11674126Szf162725 		    MAC2STR(src_addr));
11684126Szf162725 		wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
11694126Szf162725 		    wpa_s->ap_wpa_ie, wpa_s->ap_wpa_ie_len);
11704126Szf162725 		wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg", ie, ie_len);
11714126Szf162725 		wpa_supplicant_disassociate(wpa_s, REASON_IE_IN_4WAY_DIFFERS);
11724126Szf162725 		wpa_supplicant_req_scan(wpa_s, 0, 0);
11734126Szf162725 		return;
11744126Szf162725 	}
11754126Szf162725 
11764126Szf162725 	if (memcmp(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
11774126Szf162725 		wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way "
11784126Szf162725 		    "Handshake differs from 3 of 4-Way Handshake - drop"
11794126Szf162725 		    " packet (src=" MACSTR ")", MAC2STR(src_addr));
11804126Szf162725 		return;
11814126Szf162725 	}
11824126Szf162725 
11834126Szf162725 	keylen = BE_16(key->key_length);
11844126Szf162725 	switch (wpa_s->pairwise_cipher) {
11854126Szf162725 	case WPA_CIPHER_CCMP:
11864126Szf162725 		if (keylen != 16) {
11874126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "
11884126Szf162725 			    "%d (src=" MACSTR ")",
11894126Szf162725 			    keylen, MAC2STR(src_addr));
11904126Szf162725 			return;
11914126Szf162725 		}
11924126Szf162725 		break;
11934126Szf162725 	case WPA_CIPHER_TKIP:
11944126Szf162725 		if (keylen != 32) {
11954126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length "
11964126Szf162725 			    "%d (src=" MACSTR ")",
11974126Szf162725 			    keylen, MAC2STR(src_addr));
11984126Szf162725 			return;
11994126Szf162725 		}
12004126Szf162725 		break;
12014126Szf162725 	}
12024126Szf162725 
12034126Szf162725 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
12044126Szf162725 	rbuf = malloc(rlen);
12054126Szf162725 	if (rbuf == NULL)
12064126Szf162725 		return;
12074126Szf162725 
12084126Szf162725 	(void) memset(rbuf, 0, rlen);
12094126Szf162725 	ethhdr = (struct l2_ethhdr *)rbuf;
12104126Szf162725 	(void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
12114126Szf162725 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
12124126Szf162725 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
12134126Szf162725 
12144126Szf162725 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
12154126Szf162725 	hdr->version = wpa_s->conf->eapol_version;
12164126Szf162725 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
12174126Szf162725 	hdr->length = htons(sizeof (*reply));
12184126Szf162725 
12194126Szf162725 	reply = (struct wpa_eapol_key *)(hdr + 1);
12204126Szf162725 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
12215895Syz147064 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
12224126Szf162725 	reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE |
12235895Syz147064 	    WPA_KEY_INFO_MIC | (key_info & WPA_KEY_INFO_SECURE));
12244126Szf162725 	reply->key_length = key->key_length;
12254126Szf162725 	(void) memcpy(reply->replay_counter, key->replay_counter,
12265895Syz147064 	    WPA_REPLAY_COUNTER_LEN);
12274126Szf162725 
12284126Szf162725 	reply->key_data_length = BE_16(0);
12294126Szf162725 
12304126Szf162725 	(void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN);
12314126Szf162725 	wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
12324126Szf162725 	    rlen - sizeof (*ethhdr), reply->key_mic);
12334126Szf162725 
12344126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
12354126Szf162725 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 4/4", rbuf, rlen);
12364126Szf162725 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
12374126Szf162725 
12384126Szf162725 	free(rbuf);
12394126Szf162725 
12404126Szf162725 	/*
12414126Szf162725 	 * SNonce was successfully used in msg 3/4, so mark it to be renewed
12424126Szf162725 	 * for the next 4-Way Handshake. If msg 3 is received again, the old
12434126Szf162725 	 * SNonce will still be used to avoid changing PTK.
12444126Szf162725 	 */
12454126Szf162725 	wpa_s->renew_snonce = 1;
12464126Szf162725 
12474126Szf162725 	if (key_info & WPA_KEY_INFO_INSTALL) {
12484126Szf162725 		int alg, keylen, rsclen;
12494126Szf162725 		wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.");
12504126Szf162725 		switch (wpa_s->pairwise_cipher) {
12514126Szf162725 		case WPA_CIPHER_CCMP:
12524126Szf162725 			alg = WPA_ALG_CCMP;
12534126Szf162725 			keylen = 16;
12544126Szf162725 			rsclen = 6;
12554126Szf162725 			break;
12564126Szf162725 		case WPA_CIPHER_TKIP:
12574126Szf162725 			alg = WPA_ALG_TKIP;
12584126Szf162725 			keylen = 32;
12594126Szf162725 			rsclen = 6;
12604126Szf162725 			break;
12614126Szf162725 		case WPA_CIPHER_NONE:
12624126Szf162725 			wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: "
12634126Szf162725 			    "NONE - do not use pairwise keys");
12644126Szf162725 			return;
12654126Szf162725 		default:
12664126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise "
12674126Szf162725 			    "cipher %d", wpa_s->pairwise_cipher);
12684126Szf162725 			return;
12694126Szf162725 		}
12704126Szf162725 		if (wpa_s->proto == WPA_PROTO_RSN) {
12714126Szf162725 			key_rsc = null_rsc;
12724126Szf162725 		} else {
12734126Szf162725 			key_rsc = key->key_rsc;
12744126Szf162725 			wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
12754126Szf162725 		}
12764126Szf162725 
12775895Syz147064 		if (wpa_s->driver->set_key(wpa_s->linkid, alg, src_addr,
12784126Szf162725 		    0, 1, key_rsc, rsclen,
12794126Szf162725 		    (uint8_t *)&wpa_s->ptk.tk1, keylen) < 0) {
12804126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the"
12814126Szf162725 			    " driver.");
12824126Szf162725 		}
12834126Szf162725 	}
12844126Szf162725 
12854126Szf162725 	wpa_printf(MSG_DEBUG, "%s: key_info=%x gtk=%p\n",
12864126Szf162725 	    "wpa_supplicant_process_3_of_4", key_info, gtk);
12874126Szf162725 	wpa_s->wpa_state = WPA_GROUP_HANDSHAKE;
12884126Szf162725 
12894126Szf162725 	if (gtk)
12904126Szf162725 		wpa_supplicant_process_3_of_4_gtk(wpa_s,
12914126Szf162725 		    src_addr, key, gtk, gtk_len);
12924126Szf162725 }
12934126Szf162725 
12944126Szf162725 static void
12954126Szf162725 wpa_supplicant_process_1_of_2(struct wpa_supplicant *wpa_s,
12964126Szf162725     unsigned char *src_addr, struct wpa_eapol_key *key,
12974126Szf162725     int extra_len, int ver)
12984126Szf162725 {
12994126Szf162725 	int rlen;
13004126Szf162725 	struct ieee802_1x_hdr *hdr;
13014126Szf162725 	struct wpa_eapol_key *reply;
13024126Szf162725 	unsigned char *rbuf;
13034126Szf162725 	struct l2_ethhdr *ethhdr;
13044126Szf162725 	int key_info, keylen, keydatalen, maxkeylen, keyidx, key_rsc_len = 0;
13054126Szf162725 	int alg, tx;
13064126Szf162725 	uint8_t ek[32], tmpbuf[8], gtk[32];
13074126Szf162725 	uint8_t *gtk_ie = NULL;
13084126Szf162725 	size_t gtk_ie_len = 0;
13094126Szf162725 
13104126Szf162725 	wpa_s->wpa_state = WPA_GROUP_HANDSHAKE;
13114126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of Group Key Handshake from "
13124126Szf162725 	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
13134126Szf162725 
13144126Szf162725 	key_info = BE_16(key->key_info);
13154126Szf162725 	keydatalen = BE_16(key->key_data_length);
13164126Szf162725 
13174126Szf162725 	if (wpa_s->proto == WPA_PROTO_RSN) {
13184126Szf162725 		uint8_t *pos = (uint8_t *)(key + 1);
13194126Szf162725 		uint8_t *end = pos + keydatalen;
13204126Szf162725 		while (pos + 1 < end) {
13214126Szf162725 			if (pos + 2 + pos[1] > end) {
13224126Szf162725 				wpa_printf(MSG_DEBUG, "RSN: key data "
13234126Szf162725 				    "underflow (ie=%d len=%d)",
13244126Szf162725 				    pos[0], pos[1]);
13254126Szf162725 				break;
13264126Szf162725 			}
13274126Szf162725 			if (pos[0] == GENERIC_INFO_ELEM &&
13284126Szf162725 			    pos + 1 + RSN_SELECTOR_LEN < end &&
13294126Szf162725 			    pos[1] > RSN_SELECTOR_LEN + 2 &&
13304126Szf162725 			    memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY,
13314126Szf162725 			    RSN_SELECTOR_LEN) == 0) {
13324126Szf162725 				if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
13334126Szf162725 					wpa_printf(MSG_WARNING, "WPA: GTK IE "
13344126Szf162725 					    "in unencrypted key data");
13354126Szf162725 					return;
13364126Szf162725 				}
13374126Szf162725 				gtk_ie = pos + 2 + RSN_SELECTOR_LEN;
13384126Szf162725 				gtk_ie_len = pos[1] - RSN_SELECTOR_LEN;
13394126Szf162725 				break;
13405895Syz147064 			} else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0) {
13414126Szf162725 				break;
13425895Syz147064 			}
13434126Szf162725 
13444126Szf162725 			pos += 2 + pos[1];
13454126Szf162725 		}
13464126Szf162725 
13474126Szf162725 		if (gtk_ie == NULL) {
13484126Szf162725 			wpa_printf(MSG_INFO, "WPA: No GTK IE in Group Key "
13494126Szf162725 			    "message 1/2");
13504126Szf162725 			return;
13514126Szf162725 		}
13524126Szf162725 		maxkeylen = keylen = gtk_ie_len - 2;
13534126Szf162725 	} else {
13544126Szf162725 		keylen = BE_16(key->key_length);
13554126Szf162725 		maxkeylen = keydatalen;
13564126Szf162725 		if (keydatalen > extra_len) {
13574126Szf162725 			wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"
13584126Szf162725 			    " key_data_length=%d > extra_len=%d",
13594126Szf162725 			    keydatalen, extra_len);
13604126Szf162725 			return;
13614126Szf162725 		}
13624126Szf162725 		if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES)
13634126Szf162725 			maxkeylen -= 8;
13644126Szf162725 	}
13654126Szf162725 
13664126Szf162725 	switch (wpa_s->group_cipher) {
13674126Szf162725 	case WPA_CIPHER_CCMP:
13684126Szf162725 		if (keylen != 16 || maxkeylen < 16) {
13694126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP Group "
13704126Szf162725 			    "Cipher key length %d (%d).", keylen, maxkeylen);
13714126Szf162725 			return;
13724126Szf162725 		}
13734126Szf162725 		key_rsc_len = 6;
13744126Szf162725 		alg = WPA_ALG_CCMP;
13754126Szf162725 		break;
13764126Szf162725 	case WPA_CIPHER_TKIP:
13774126Szf162725 		if (keylen != 32 || maxkeylen < 32) {
13784126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP Group "
13794126Szf162725 			    "Cipher key length %d (%d).", keylen, maxkeylen);
13804126Szf162725 			return;
13814126Szf162725 		}
13824126Szf162725 		key_rsc_len = 6; /* key->key_data; */
13834126Szf162725 		alg = WPA_ALG_TKIP;
13844126Szf162725 		break;
13854126Szf162725 	case WPA_CIPHER_WEP104:
13864126Szf162725 		if (keylen != 13 || maxkeylen < 13) {
13874126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported WEP104 Group"
13884126Szf162725 			    " Cipher key length %d (%d).", keylen, maxkeylen);
13894126Szf162725 			return;
13904126Szf162725 		}
13914126Szf162725 		alg = WPA_ALG_WEP;
13924126Szf162725 		break;
13934126Szf162725 	case WPA_CIPHER_WEP40:
13944126Szf162725 		if (keylen != 5 || maxkeylen < 5) {
13954126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported WEP40 Group "
13964126Szf162725 			    "Cipher key length %d (%d).", keylen, maxkeylen);
13974126Szf162725 			return;
13984126Szf162725 		}
13994126Szf162725 		alg = WPA_ALG_WEP;
14004126Szf162725 		break;
14014126Szf162725 	default:
14024126Szf162725 		wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher %d",
14034126Szf162725 		    wpa_s->group_cipher);
14044126Szf162725 		return;
14054126Szf162725 	}
14064126Szf162725 
14074126Szf162725 	if (wpa_s->proto == WPA_PROTO_RSN) {
14084126Szf162725 		wpa_hexdump(MSG_DEBUG,
14094126Szf162725 		    "WPA: received GTK in group key handshake",
14104126Szf162725 		    gtk_ie, gtk_ie_len);
14114126Szf162725 		keyidx = gtk_ie[0] & 0x3;
14124126Szf162725 		tx = !!(gtk_ie[0] & BIT(2));
14134126Szf162725 		if (gtk_ie_len - 2 > sizeof (gtk)) {
14144126Szf162725 			wpa_printf(MSG_INFO, "WPA: Too long GTK in GTK IE "
14154126Szf162725 			    "(len=%d)", gtk_ie_len - 2);
14164126Szf162725 			return;
14174126Szf162725 		}
14184126Szf162725 		(void) memcpy(gtk, gtk_ie + 2, gtk_ie_len - 2);
14194126Szf162725 	} else {
14204126Szf162725 		keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
14215895Syz147064 		    WPA_KEY_INFO_KEY_INDEX_SHIFT;
14224126Szf162725 		if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
14234126Szf162725 			(void) memcpy(ek, key->key_iv, 16);
14244126Szf162725 			(void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16);
14254126Szf162725 			rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen);
14264126Szf162725 			(void) memcpy(gtk, key + 1, keylen);
14274126Szf162725 		} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
14284126Szf162725 			if (keydatalen % 8) {
14294126Szf162725 				wpa_printf(MSG_WARNING, "WPA: Unsupported "
14304126Szf162725 				    "AES-WRAP len %d", keydatalen);
14314126Szf162725 				return;
14324126Szf162725 			}
14334126Szf162725 			if (aes_unwrap(wpa_s->ptk.encr_key, maxkeylen / 8,
14345895Syz147064 			    (uint8_t *)(key + 1), gtk)) {
14354126Szf162725 				wpa_printf(MSG_WARNING, "WPA: AES unwrap "
14364126Szf162725 				    "failed - could not decrypt GTK");
14374126Szf162725 				return;
14384126Szf162725 			}
14394126Szf162725 		}
14404126Szf162725 		tx = !!(key_info & WPA_KEY_INFO_TXRX);
14414126Szf162725 		if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
14424126Szf162725 			/*
14434126Szf162725 			 * Ignore Tx bit in Group Key message if a pairwise key
14444126Szf162725 			 * is used. Some APs seem to setting this bit
14454126Szf162725 			 * (incorrectly, since Tx is only when doing Group Key
14464126Szf162725 			 * only APs) and without this workaround, the data
14474126Szf162725 			 * connection does not work because wpa_supplicant
14484126Szf162725 			 * configured non-zero keyidx to be used for unicast.
14494126Szf162725 			 */
14504126Szf162725 			wpa_printf(MSG_INFO, "WPA: Tx bit set for GTK, but "
14514126Szf162725 			    "pairwise keys are used - ignore Tx bit");
14524126Szf162725 			tx = 0;
14534126Szf162725 		}
14544126Szf162725 	}
14554126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, keylen);
14564126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver (keyidx=%d "
14574126Szf162725 	    "tx=%d).", keyidx, tx);
14584126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len);
14594126Szf162725 	if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
14604126Szf162725 		/*
14614126Szf162725 		 * Swap Tx/Rx keys for Michael MIC
14624126Szf162725 		 */
14634126Szf162725 		(void) memcpy(tmpbuf, gtk + 16, 8);
14644126Szf162725 		(void) memcpy(gtk + 16, gtk + 24, 8);
14654126Szf162725 		(void) memcpy(gtk + 24, tmpbuf, 8);
14664126Szf162725 	}
14674126Szf162725 	if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
14685895Syz147064 		if (wpa_s->driver->set_key(wpa_s->linkid, alg,
14694126Szf162725 		    (uint8_t *)"\xff\xff\xff\xff\xff\xff",
14704126Szf162725 		    keyidx, 1, key->key_rsc,
14714126Szf162725 		    key_rsc_len, gtk, keylen) < 0)
14724126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the"
14734126Szf162725 			    " driver (Group only).");
14745895Syz147064 	} else if (wpa_s->driver->set_key(wpa_s->linkid, alg,
14754126Szf162725 	    (uint8_t *)"\xff\xff\xff\xff\xff\xff",
14764126Szf162725 	    keyidx, tx,
14774126Szf162725 	    key->key_rsc, key_rsc_len,
14784126Szf162725 	    gtk, keylen) < 0) {
14794126Szf162725 		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the "
14804126Szf162725 		    "driver.");
14814126Szf162725 	}
14824126Szf162725 
14834126Szf162725 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
14844126Szf162725 	rbuf = malloc(rlen);
14854126Szf162725 	if (rbuf == NULL)
14864126Szf162725 		return;
14874126Szf162725 
14884126Szf162725 	(void) memset(rbuf, 0, rlen);
14894126Szf162725 	ethhdr = (struct l2_ethhdr *)rbuf;
14904126Szf162725 	(void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
14914126Szf162725 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
14924126Szf162725 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
14934126Szf162725 
14944126Szf162725 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
14954126Szf162725 	hdr->version = wpa_s->conf->eapol_version;
14964126Szf162725 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
14974126Szf162725 	hdr->length = htons(sizeof (*reply));
14984126Szf162725 
14994126Szf162725 	reply = (struct wpa_eapol_key *)(hdr + 1);
15004126Szf162725 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
15014126Szf162725 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
15024126Szf162725 	reply->key_info =
15034126Szf162725 	    BE_16(ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE |
15044126Szf162725 	    (key_info & WPA_KEY_INFO_KEY_INDEX_MASK));
15054126Szf162725 	reply->key_length = key->key_length;
15064126Szf162725 	(void) memcpy(reply->replay_counter, key->replay_counter,
15074126Szf162725 	    WPA_REPLAY_COUNTER_LEN);
15084126Szf162725 
15094126Szf162725 	reply->key_data_length = BE_16(0);
15104126Szf162725 
15114126Szf162725 	wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
15124126Szf162725 	    rlen - sizeof (*ethhdr), reply->key_mic);
15134126Szf162725 
15144126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
15154126Szf162725 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/2", rbuf, rlen);
15164126Szf162725 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
15174126Szf162725 	free(rbuf);
15184126Szf162725 
15194126Szf162725 	wpa_printf(MSG_INFO, "WPA: Key negotiation completed with " MACSTR,
15204126Szf162725 	    MAC2STR(src_addr));
15214126Szf162725 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
15224126Szf162725 	wpa_supplicant_cancel_auth_timeout(wpa_s);
15234126Szf162725 	wpa_s->wpa_state = WPA_COMPLETED;
15244126Szf162725 	wpa_printf(MSG_INFO, "-----------------------------------\n");
15254126Szf162725 }
15264126Szf162725 
15274126Szf162725 static int
15284126Szf162725 wpa_supplicant_verify_eapol_key_mic(struct wpa_supplicant *wpa_s,
15294126Szf162725     struct wpa_eapol_key *key, int ver, uint8_t *buf, size_t len)
15304126Szf162725 {
15314126Szf162725 	uint8_t mic[16];
15324126Szf162725 	int ok = 0;
15334126Szf162725 
15344126Szf162725 	(void) memcpy(mic, key->key_mic, 16);
15354126Szf162725 	if (wpa_s->tptk_set) {
15364126Szf162725 		(void) memset(key->key_mic, 0, 16);
15374126Szf162725 		wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, buf, len,
15384126Szf162725 		    key->key_mic);
15394126Szf162725 		if (memcmp(mic, key->key_mic, 16) != 0) {
15404126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
15414126Szf162725 			    "when using TPTK - ignoring TPTK");
15424126Szf162725 		} else {
15434126Szf162725 			ok = 1;
15444126Szf162725 			wpa_s->tptk_set = 0;
15454126Szf162725 			wpa_s->ptk_set = 1;
15464126Szf162725 			(void) memcpy(&wpa_s->ptk, &wpa_s->tptk,
15474126Szf162725 			    sizeof (wpa_s->ptk));
15484126Szf162725 		}
15494126Szf162725 	}
15504126Szf162725 
15514126Szf162725 	if (!ok && wpa_s->ptk_set) {
15524126Szf162725 		(void) memset(key->key_mic, 0, 16);
15534126Szf162725 		wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, buf, len,
15544126Szf162725 		    key->key_mic);
15554126Szf162725 		if (memcmp(mic, key->key_mic, 16) != 0) {
15564126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
15574126Szf162725 			    "- dropping packet");
15584126Szf162725 			return (-1);
15594126Szf162725 		}
15604126Szf162725 		ok = 1;
15614126Szf162725 	}
15624126Szf162725 
15634126Szf162725 	if (!ok) {
15644126Szf162725 		wpa_printf(MSG_WARNING, "WPA: Could not verify EAPOL-Key MIC "
15654126Szf162725 		    "- dropping packet");
15664126Szf162725 		return (-1);
15674126Szf162725 	}
15684126Szf162725 
15694126Szf162725 	(void) memcpy(wpa_s->rx_replay_counter, key->replay_counter,
15704126Szf162725 	    WPA_REPLAY_COUNTER_LEN);
15714126Szf162725 	wpa_s->rx_replay_counter_set = 1;
15724126Szf162725 
15734126Szf162725 	return (0);
15744126Szf162725 }
15754126Szf162725 
15764126Szf162725 /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
15774126Szf162725 static int
15784126Szf162725 wpa_supplicant_decrypt_key_data(struct wpa_supplicant *wpa_s,
15794126Szf162725 	struct wpa_eapol_key *key, int ver)
15804126Szf162725 {
15814126Szf162725 	int keydatalen = BE_16(key->key_data_length);
15824126Szf162725 
15834126Szf162725 	wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
15844126Szf162725 	    (uint8_t *)(key + 1), keydatalen);
15854126Szf162725 	if (!wpa_s->ptk_set) {
15864126Szf162725 		wpa_printf(MSG_WARNING, "WPA: PTK not available, "
15874126Szf162725 		    "cannot decrypt EAPOL-Key key data.");
15884126Szf162725 		return (-1);
15894126Szf162725 	}
15904126Szf162725 
15914126Szf162725 	/*
15924126Szf162725 	 * Decrypt key data here so that this operation does not need
15934126Szf162725 	 * to be implemented separately for each message type.
15944126Szf162725 	 */
15954126Szf162725 	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
15964126Szf162725 		uint8_t ek[32];
15974126Szf162725 		(void) memcpy(ek, key->key_iv, 16);
15984126Szf162725 		(void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16);
15994126Szf162725 		rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen);
16004126Szf162725 	} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
16014126Szf162725 		uint8_t *buf;
16024126Szf162725 		if (keydatalen % 8) {
16034126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Unsupported "
16044126Szf162725 			    "AES-WRAP len %d", keydatalen);
16054126Szf162725 			return (-1);
16064126Szf162725 		}
16074126Szf162725 		keydatalen -= 8; /* AES-WRAP adds 8 bytes */
16084126Szf162725 		buf = malloc(keydatalen);
16094126Szf162725 		if (buf == NULL) {
16104126Szf162725 			wpa_printf(MSG_WARNING, "WPA: No memory for "
16114126Szf162725 			    "AES-UNWRAP buffer");
16124126Szf162725 			return (-1);
16134126Szf162725 		}
16144126Szf162725 		if (aes_unwrap(wpa_s->ptk.encr_key, keydatalen / 8,
16154126Szf162725 		    (uint8_t *)(key + 1), buf)) {
16164126Szf162725 			free(buf);
16174126Szf162725 			wpa_printf(MSG_WARNING, "WPA: AES unwrap failed - "
16184126Szf162725 			    "could not decrypt EAPOL-Key key data");
16194126Szf162725 			return (-1);
16204126Szf162725 		}
16214126Szf162725 		(void) memcpy(key + 1, buf, keydatalen);
16224126Szf162725 		free(buf);
16234126Szf162725 		key->key_data_length = BE_16(keydatalen);
16244126Szf162725 	}
16254126Szf162725 	wpa_hexdump(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
16264126Szf162725 	    (uint8_t *)(key + 1), keydatalen);
16274126Szf162725 
16284126Szf162725 	return (0);
16294126Szf162725 }
16304126Szf162725 
16314126Szf162725 static void
16324126Szf162725 wpa_sm_rx_eapol(struct wpa_supplicant *wpa_s,
16334126Szf162725     unsigned char *src_addr, unsigned char *buf, size_t len)
16344126Szf162725 {
16354126Szf162725 	size_t plen, data_len, extra_len;
16364126Szf162725 	struct ieee802_1x_hdr *hdr;
16374126Szf162725 	struct wpa_eapol_key *key;
16384126Szf162725 	int key_info, ver;
16394126Szf162725 
16404126Szf162725 	wpa_printf(MSG_DEBUG, "WPA: EAPOL frame len %u\n ", len);
16414126Szf162725 
16424126Szf162725 	hdr = (struct ieee802_1x_hdr *)buf;
16434126Szf162725 	key = (struct wpa_eapol_key *)(hdr + 1);
16444126Szf162725 	wpa_printf(MSG_DEBUG, "hdr_len=%u, key_len=%u",
16454126Szf162725 	    sizeof (*hdr), sizeof (*key));
16464126Szf162725 	if (len < sizeof (*hdr) + sizeof (*key)) {
16474126Szf162725 		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short, len %u, "
16484126Szf162725 		    "expecting at least %u",
16494126Szf162725 		    len, sizeof (*hdr) + sizeof (*key));
16504126Szf162725 		return;
16514126Szf162725 	}
16524126Szf162725 	plen = ntohs(hdr->length);
16534126Szf162725 	data_len = plen + sizeof (*hdr);
16544126Szf162725 	wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d",
16554126Szf162725 	    hdr->version, hdr->type, plen);
16564126Szf162725 
16574126Szf162725 	if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
16584126Szf162725 		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame (type %u) discarded, "
16594126Szf162725 		    "not a Key frame", hdr->type);
16604126Szf162725 		return;
16614126Szf162725 	}
16624126Szf162725 	if (plen > len - sizeof (*hdr) || plen < sizeof (*key)) {
16634126Szf162725 		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %u "
16644126Szf162725 		    "invalid (frame size %u)", plen, len);
16654126Szf162725 		return;
16664126Szf162725 	}
16674126Szf162725 
16684126Szf162725 	wpa_printf(MSG_DEBUG, "  EAPOL-Key type=%d", key->type);
16694126Szf162725 	if (key->type != EAPOL_KEY_TYPE_WPA && key->type !=
16704126Szf162725 	    EAPOL_KEY_TYPE_RSN) {
16714126Szf162725 		wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key type (%d) unknown, "
16724126Szf162725 		    "discarded", key->type);
16734126Szf162725 		return;
16744126Szf162725 	}
16754126Szf162725 
16764126Szf162725 	wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
16774126Szf162725 	if (data_len < len) {
16784126Szf162725 		wpa_printf(MSG_DEBUG, "WPA: ignoring %d bytes after the IEEE "
16794126Szf162725 		    "802.1X data", len - data_len);
16804126Szf162725 	}
16814126Szf162725 	key_info = BE_16(key->key_info);
16824126Szf162725 	ver = key_info & WPA_KEY_INFO_TYPE_MASK;
16834126Szf162725 	if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
16844126Szf162725 	    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
16854126Szf162725 		wpa_printf(MSG_INFO, "WPA: Unsupported EAPOL-Key descriptor "
16864126Szf162725 		    "version %d.", ver);
16874126Szf162725 		return;
16884126Szf162725 	}
16894126Szf162725 
16904126Szf162725 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP &&
16914126Szf162725 	    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
16924126Szf162725 		wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key "
16934126Szf162725 		    "descriptor version (%d) is not 2.", ver);
16944126Szf162725 		if (wpa_s->group_cipher != WPA_CIPHER_CCMP &&
16954126Szf162725 		    !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
16964126Szf162725 			/*
16974126Szf162725 			 * Earlier versions of IEEE 802.11i did not explicitly
16984126Szf162725 			 * require version 2 descriptor for all EAPOL-Key
16994126Szf162725 			 * packets, so allow group keys to use version 1 if
17004126Szf162725 			 * CCMP is not used for them.
17014126Szf162725 			 */
17024126Szf162725 			wpa_printf(MSG_INFO, "WPA: Backwards compatibility: "
17034126Szf162725 			    "allow invalid version for non-CCMP group keys");
17044126Szf162725 		} else
17054126Szf162725 			return;
17064126Szf162725 	}
17074126Szf162725 
17084126Szf162725 	if (wpa_s->rx_replay_counter_set &&
17094126Szf162725 	    memcmp(key->replay_counter, wpa_s->rx_replay_counter,
17104126Szf162725 	    WPA_REPLAY_COUNTER_LEN) <= 0) {
17114126Szf162725 		wpa_printf(MSG_WARNING, "WPA: EAPOL-Key Replay Counter did not"
17124126Szf162725 		    " increase - dropping packet");
17134126Szf162725 		return;
17144126Szf162725 	}
17154126Szf162725 
17164126Szf162725 	if (!(key_info & WPA_KEY_INFO_ACK)) {
17174126Szf162725 		wpa_printf(MSG_INFO, "WPA: No Ack bit in key_info");
17184126Szf162725 		return;
17194126Szf162725 	}
17204126Szf162725 
17214126Szf162725 	if (key_info & WPA_KEY_INFO_REQUEST) {
17224126Szf162725 		wpa_printf(MSG_INFO, "WPA: EAPOL-Key with Request bit - "
17234126Szf162725 		    "dropped");
17244126Szf162725 		return;
17254126Szf162725 	}
17264126Szf162725 
17274126Szf162725 	if ((key_info & WPA_KEY_INFO_MIC) &&
17285895Syz147064 	    wpa_supplicant_verify_eapol_key_mic(wpa_s, key, ver, buf,
17295895Syz147064 	    data_len)) {
17304126Szf162725 		return;
17315895Syz147064 	}
17324126Szf162725 
17334126Szf162725 	extra_len = data_len - sizeof (*hdr) - sizeof (*key);
17344126Szf162725 
17354126Szf162725 	if (wpa_s->proto == WPA_PROTO_RSN &&
17364126Szf162725 	    (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) &&
17374126Szf162725 	    wpa_supplicant_decrypt_key_data(wpa_s, key, ver))
17384126Szf162725 		return;
17394126Szf162725 
17404126Szf162725 	if (key_info & WPA_KEY_INFO_KEY_TYPE) {
17414126Szf162725 		if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
17424126Szf162725 			wpa_printf(MSG_WARNING, "WPA: Ignored EAPOL-Key "
17434126Szf162725 			    "(Pairwise) with non-zero key index");
17444126Szf162725 			return;
17454126Szf162725 		}
17464126Szf162725 		if (key_info & WPA_KEY_INFO_MIC) {
17474126Szf162725 			/* 3/4 4-Way Handshake */
17484126Szf162725 			wpa_supplicant_process_3_of_4(wpa_s, src_addr, key,
17494126Szf162725 			    extra_len, ver);
17504126Szf162725 		} else {
17514126Szf162725 			/* 1/4 4-Way Handshake */
17524126Szf162725 			wpa_supplicant_process_1_of_4(wpa_s, src_addr, key,
17534126Szf162725 			    ver);
17544126Szf162725 		}
17554126Szf162725 	} else {
17564126Szf162725 		if (key_info & WPA_KEY_INFO_MIC) {
17574126Szf162725 			/* 1/2 Group Key Handshake */
17584126Szf162725 			wpa_supplicant_process_1_of_2(wpa_s, src_addr, key,
17594126Szf162725 			    extra_len, ver);
17604126Szf162725 		} else {
17614126Szf162725 			wpa_printf(MSG_WARNING, "WPA: EAPOL-Key (Group) "
17624126Szf162725 			    "without Mic bit - dropped");
17634126Szf162725 		}
17644126Szf162725 	}
17654126Szf162725 }
17664126Szf162725 
17674126Szf162725 void
17684126Szf162725 wpa_supplicant_rx_eapol(void *ctx, unsigned char *src_addr,
17694126Szf162725     unsigned char *buf, size_t len)
17704126Szf162725 {
17714126Szf162725 	struct wpa_supplicant *wpa_s = ctx;
17724126Szf162725 
17734126Szf162725 	wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
17744126Szf162725 	wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
17754126Szf162725 
17764126Szf162725 	if (wpa_s->eapol_received == 0) {
17774126Szf162725 		/* Timeout for completing IEEE 802.1X and WPA authentication */
17784126Szf162725 		wpa_supplicant_req_auth_timeout(
17794126Szf162725 		    wpa_s, wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ?
17804126Szf162725 		    70 : 10, 0);
17814126Szf162725 	}
17824126Szf162725 	wpa_s->eapol_received++;
17834126Szf162725 
17844126Szf162725 	/*
17854126Szf162725 	 * Source address of the incoming EAPOL frame could be compared to the
17864126Szf162725 	 * current BSSID. However, it is possible that a centralized
17874126Szf162725 	 * Authenticator could be using another MAC address than the BSSID of
17884126Szf162725 	 * an AP, so just allow any address to be used for now. The replies are
17894126Szf162725 	 * still sent to the current BSSID (if available), though.
17904126Szf162725 	 */
17914126Szf162725 	wpa_sm_rx_eapol(wpa_s, src_addr, buf, len);
17924126Szf162725 }
1793