1a399b765Szf /*
2d62bc4baSyz  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3a399b765Szf  * Use is subject to license terms.
4a399b765Szf  */
5a399b765Szf 
6a399b765Szf /*
7a399b765Szf  * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
8a399b765Szf  * Sun elects to license this software under the BSD license.
9a399b765Szf  * See README for more details.
10a399b765Szf  */
11a399b765Szf 
12a399b765Szf #include <stdio.h>
13a399b765Szf #include <stdlib.h>
14a399b765Szf #include <string.h>
15a399b765Szf #include <time.h>
16a399b765Szf #include <netinet/in.h>
17a399b765Szf #include <sys/ethernet.h>
18a399b765Szf #include <fcntl.h>
19a399b765Szf #include <unistd.h>
20a399b765Szf 
21a399b765Szf #include "wpa_impl.h"
22a399b765Szf #include "wpa_enc.h"
23a399b765Szf #include "driver.h"
24a399b765Szf #include "eloop.h"
25a399b765Szf #include "l2_packet.h"
26a399b765Szf 
27a399b765Szf static void pmksa_cache_set_expiration(struct wpa_supplicant *);
28a399b765Szf 
29a399b765Szf /*
30a399b765Szf  * IEEE 802.11i/D3.0
31a399b765Szf  */
32a399b765Szf static const int WPA_SELECTOR_LEN = 4;
33fb91fd8aSzf static const uint8_t WPA_OUI_AND_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
34a399b765Szf static const uint8_t
35a399b765Szf WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] 		= { 0x00, 0x50, 0xf2, 1 };
36a399b765Szf static const uint8_t
37a399b765Szf WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] 		= { 0x00, 0x50, 0xf2, 2 };
38a399b765Szf static const uint8_t WPA_CIPHER_SUITE_NONE[]	= { 0x00, 0x50, 0xf2, 0 };
39a399b765Szf static const uint8_t WPA_CIPHER_SUITE_WEP40[]	= { 0x00, 0x50, 0xf2, 1 };
40a399b765Szf static const uint8_t WPA_CIPHER_SUITE_TKIP[]	= { 0x00, 0x50, 0xf2, 2 };
41a399b765Szf static const uint8_t WPA_CIPHER_SUITE_CCMP[]	= { 0x00, 0x50, 0xf2, 4 };
42a399b765Szf static const uint8_t WPA_CIPHER_SUITE_WEP104[]	= { 0x00, 0x50, 0xf2, 5 };
43a399b765Szf 
44a399b765Szf /*
45a399b765Szf  * WPA IE version 1
46a399b765Szf  * 00-50-f2:1 (OUI:OUI type)
47a399b765Szf  * 0x01 0x00 (version; little endian)
48a399b765Szf  * (all following fields are optional:)
49a399b765Szf  * Group Suite Selector (4 octets) (default: TKIP)
50a399b765Szf  * Pairwise Suite Count (2 octets, little endian) (default: 1)
51a399b765Szf  * Pairwise Suite List (4 * n octets) (default: TKIP)
52a399b765Szf  * Authenticated Key Management Suite Count (2 octets, little endian)
53a399b765Szf  * (default: 1)
54a399b765Szf  * Authenticated Key Management Suite List (4 * n octets)
55a399b765Szf  * (default: unspec 802.1x)
56a399b765Szf  * WPA Capabilities (2 octets, little endian) (default: 0)
57a399b765Szf  */
58a399b765Szf #pragma pack(1)
59a399b765Szf struct wpa_ie_hdr {
60a399b765Szf 	uint8_t		elem_id;
61a399b765Szf 	uint8_t		len;
62a399b765Szf 	uint8_t		oui[3];
63a399b765Szf 	uint8_t		oui_type;
64a399b765Szf 	uint16_t	version;
65a399b765Szf };
66a399b765Szf #pragma pack()
67a399b765Szf 
68a399b765Szf /*
69a399b765Szf  * IEEE 802.11i/D9.0
70a399b765Szf  */
71a399b765Szf static const int RSN_SELECTOR_LEN = 4;
72a399b765Szf static const uint16_t RSN_VERSION = 1;
73a399b765Szf static const uint8_t
74a399b765Szf RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]		= { 0x00, 0x0f, 0xac, 1 };
75a399b765Szf static const uint8_t
76a399b765Szf RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]		= { 0x00, 0x0f, 0xac, 2 };
77a399b765Szf static const uint8_t RSN_CIPHER_SUITE_NONE[]	= { 0x00, 0x0f, 0xac, 0 };
78a399b765Szf static const uint8_t RSN_CIPHER_SUITE_WEP40[]	= { 0x00, 0x0f, 0xac, 1 };
79a399b765Szf static const uint8_t RSN_CIPHER_SUITE_TKIP[]	= { 0x00, 0x0f, 0xac, 2 };
80a399b765Szf static const uint8_t RSN_CIPHER_SUITE_CCMP[]	= { 0x00, 0x0f, 0xac, 4 };
81a399b765Szf static const uint8_t RSN_CIPHER_SUITE_WEP104[]	= { 0x00, 0x0f, 0xac, 5 };
82a399b765Szf 
83a399b765Szf /*
84a399b765Szf  * EAPOL-Key Key Data Encapsulation
85a399b765Szf  * GroupKey and STAKey require encryption, otherwise, encryption is optional.
86a399b765Szf  */
87a399b765Szf static const uint8_t RSN_KEY_DATA_GROUPKEY[]	= { 0x00, 0x0f, 0xac, 1 };
88a399b765Szf static const uint8_t RSN_KEY_DATA_PMKID[]	= { 0x00, 0x0f, 0xac, 4 };
89a399b765Szf 
90a399b765Szf /*
91a399b765Szf  * 1/4: PMKID
92a399b765Szf  * 2/4: RSN IE
93a399b765Szf  * 3/4: one or two RSN IEs + GTK IE (encrypted)
94a399b765Szf  * 4/4: empty
95a399b765Szf  * 1/2: GTK IE (encrypted)
96a399b765Szf  * 2/2: empty
97a399b765Szf  */
98a399b765Szf 
99a399b765Szf /*
100a399b765Szf  * RSN IE version 1
101a399b765Szf  * 0x01 0x00 (version; little endian)
102a399b765Szf  * (all following fields are optional:)
103a399b765Szf  * Group Suite Selector (4 octets) (default: CCMP)
104a399b765Szf  * Pairwise Suite Count (2 octets, little endian) (default: 1)
105a399b765Szf  * Pairwise Suite List (4 * n octets) (default: CCMP)
106a399b765Szf  * Authenticated Key Management Suite Count (2 octets, little endian)
107a399b765Szf  *    (default: 1)
108a399b765Szf  * Authenticated Key Management Suite List (4 * n octets)
109a399b765Szf  *    (default: unspec 802.1x)
110a399b765Szf  * RSN Capabilities (2 octets, little endian) (default: 0)
111a399b765Szf  * PMKID Count (2 octets) (default: 0)
112a399b765Szf  * PMKID List (16 * n octets)
113a399b765Szf  */
114a399b765Szf #pragma pack(1)
115a399b765Szf struct rsn_ie_hdr {
116a399b765Szf 	uint8_t		elem_id; /* WLAN_EID_RSN */
117a399b765Szf 	uint8_t		len;
118a399b765Szf 	uint16_t	version;
119a399b765Szf };
120a399b765Szf #pragma pack()
121a399b765Szf 
122a399b765Szf static int
random_get_pseudo_bytes(uint8_t * ptr,size_t len)123a399b765Szf random_get_pseudo_bytes(uint8_t *ptr, size_t len)
124a399b765Szf {
125a399b765Szf 	int fd;
126a399b765Szf 	size_t resid = len;
127a399b765Szf 	size_t bytes;
128a399b765Szf 
129a399b765Szf 	fd = open("/dev/urandom", O_RDONLY);
130a399b765Szf 	if (fd == -1) {
131a399b765Szf 		wpa_printf(MSG_ERROR, "Could not open /dev/urandom.\n");
132a399b765Szf 		return (-1);
133a399b765Szf 	}
134a399b765Szf 
135a399b765Szf 	while (resid != 0) {
136a399b765Szf 		bytes = read(fd, ptr, resid);
137a399b765Szf 		ptr += bytes;
138a399b765Szf 		resid -= bytes;
139a399b765Szf 	}
140a399b765Szf 
141a399b765Szf 	(void) close(fd);
142a399b765Szf 
143a399b765Szf 	return (0);
144a399b765Szf }
145a399b765Szf 
146a399b765Szf static void
inc_byte_array(uint8_t * counter,size_t len)147a399b765Szf inc_byte_array(uint8_t *counter, size_t len)
148a399b765Szf {
149a399b765Szf 	int pos = len - 1;
150a399b765Szf 	while (pos >= 0) {
151a399b765Szf 		counter[pos]++;
152a399b765Szf 		if (counter[pos] != 0)
153a399b765Szf 			break;
154a399b765Szf 		pos--;
155a399b765Szf 	}
156a399b765Szf }
157a399b765Szf 
158a399b765Szf static int
wpa_selector_to_bitfield(uint8_t * s)159a399b765Szf wpa_selector_to_bitfield(uint8_t *s)
160a399b765Szf {
161a399b765Szf 	if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)
162a399b765Szf 		return (WPA_CIPHER_NONE);
163a399b765Szf 	if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0)
164a399b765Szf 		return (WPA_CIPHER_WEP40);
165a399b765Szf 	if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0)
166a399b765Szf 		return (WPA_CIPHER_TKIP);
167a399b765Szf 	if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0)
168a399b765Szf 		return (WPA_CIPHER_CCMP);
169a399b765Szf 	if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0)
170a399b765Szf 		return (WPA_CIPHER_WEP104);
171a399b765Szf 	return (0);
172a399b765Szf }
173a399b765Szf 
174a399b765Szf static int
wpa_key_mgmt_to_bitfield(uint8_t * s)175a399b765Szf wpa_key_mgmt_to_bitfield(uint8_t *s)
176a399b765Szf {
177a399b765Szf 	if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0)
178a399b765Szf 		return (WPA_KEY_MGMT_IEEE8021X);
179a399b765Szf 	if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) ==
180a399b765Szf 	    0)
181a399b765Szf 		return (WPA_KEY_MGMT_PSK);
182a399b765Szf 	return (0);
183a399b765Szf }
184a399b765Szf 
185a399b765Szf static int
rsn_selector_to_bitfield(uint8_t * s)186a399b765Szf rsn_selector_to_bitfield(uint8_t *s)
187a399b765Szf {
188a399b765Szf 	if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0)
189a399b765Szf 		return (WPA_CIPHER_NONE);
190a399b765Szf 	if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0)
191a399b765Szf 		return (WPA_CIPHER_WEP40);
192a399b765Szf 	if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0)
193a399b765Szf 		return (WPA_CIPHER_TKIP);
194a399b765Szf 	if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0)
195a399b765Szf 		return (WPA_CIPHER_CCMP);
196a399b765Szf 	if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0)
197a399b765Szf 		return (WPA_CIPHER_WEP104);
198a399b765Szf 	return (0);
199a399b765Szf }
200a399b765Szf 
201a399b765Szf static int
rsn_key_mgmt_to_bitfield(uint8_t * s)202a399b765Szf rsn_key_mgmt_to_bitfield(uint8_t *s)
203a399b765Szf {
204a399b765Szf 	if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0)
205a399b765Szf 		return (WPA_KEY_MGMT_IEEE8021X);
206a399b765Szf 	if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) ==
207a399b765Szf 	    0)
208a399b765Szf 		return (WPA_KEY_MGMT_PSK);
209a399b765Szf 	return (0);
210a399b765Szf }
211a399b765Szf 
212a399b765Szf static void
pmksa_cache_free_entry(struct wpa_supplicant * wpa_s,struct rsn_pmksa_cache * entry)213a399b765Szf pmksa_cache_free_entry(struct wpa_supplicant *wpa_s,
214a399b765Szf 	struct rsn_pmksa_cache *entry)
215a399b765Szf {
216a399b765Szf 	wpa_s->pmksa_count--;
217a399b765Szf 	if (wpa_s->cur_pmksa == entry) {
218a399b765Szf 		wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA entry");
219a399b765Szf 		wpa_s->cur_pmksa = NULL;
220a399b765Szf 	}
221a399b765Szf 	free(entry);
222a399b765Szf }
223a399b765Szf 
224a399b765Szf /* ARGSUSED */
225a399b765Szf static void
pmksa_cache_expire(void * eloop_ctx,void * timeout_ctx)226a399b765Szf pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
227a399b765Szf {
228a399b765Szf 	struct wpa_supplicant *wpa_s = eloop_ctx;
229a399b765Szf 	time_t now;
230a399b765Szf 
231a399b765Szf 	(void) time(&now);
232a399b765Szf 	while (wpa_s->pmksa && wpa_s->pmksa->expiration <= now) {
233a399b765Szf 		struct rsn_pmksa_cache *entry = wpa_s->pmksa;
234a399b765Szf 		wpa_s->pmksa = entry->next;
235a399b765Szf 		wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
236a399b765Szf 		    MACSTR, MAC2STR(entry->aa));
237a399b765Szf 		pmksa_cache_free_entry(wpa_s, entry);
238a399b765Szf 	}
239a399b765Szf 
240a399b765Szf 	pmksa_cache_set_expiration(wpa_s);
241a399b765Szf }
242a399b765Szf 
243a399b765Szf static void
pmksa_cache_set_expiration(struct wpa_supplicant * wpa_s)244a399b765Szf pmksa_cache_set_expiration(struct wpa_supplicant *wpa_s)
245a399b765Szf {
246a399b765Szf 	int sec;
247a399b765Szf 	eloop_cancel_timeout(pmksa_cache_expire, wpa_s, NULL);
248a399b765Szf 	if (wpa_s->pmksa == NULL)
249a399b765Szf 		return;
250a399b765Szf 	sec = wpa_s->pmksa->expiration - time(NULL);
251a399b765Szf 	if (sec < 0)
252a399b765Szf 		sec = 0;
253a399b765Szf 	(void) eloop_register_timeout(sec + 1, 0, pmksa_cache_expire,
254a399b765Szf 	    wpa_s, NULL);
255a399b765Szf }
256a399b765Szf 
257a399b765Szf void
pmksa_cache_free(struct wpa_supplicant * wpa_s)258a399b765Szf pmksa_cache_free(struct wpa_supplicant *wpa_s)
259a399b765Szf {
260a399b765Szf 	struct rsn_pmksa_cache *entry, *prev;
261a399b765Szf 
262a399b765Szf 	entry = wpa_s->pmksa;
263a399b765Szf 	wpa_s->pmksa = NULL;
264a399b765Szf 	while (entry) {
265a399b765Szf 		prev = entry;
266a399b765Szf 		entry = entry->next;
267a399b765Szf 		free(prev);
268a399b765Szf 	}
269a399b765Szf 	pmksa_cache_set_expiration(wpa_s);
270a399b765Szf 	wpa_s->cur_pmksa = NULL;
271a399b765Szf }
272a399b765Szf 
273a399b765Szf struct rsn_pmksa_cache *
pmksa_cache_get(struct wpa_supplicant * wpa_s,uint8_t * aa,uint8_t * pmkid)274a399b765Szf pmksa_cache_get(struct wpa_supplicant *wpa_s,
275a399b765Szf 		uint8_t *aa, uint8_t *pmkid)
276a399b765Szf {
277a399b765Szf 	struct rsn_pmksa_cache *entry = wpa_s->pmksa;
278a399b765Szf 	while (entry) {
279a399b765Szf 		if ((aa == NULL ||
280a399b765Szf 		    memcmp(entry->aa, aa, IEEE80211_ADDR_LEN) == 0) &&
281a399b765Szf 		    (pmkid == NULL ||
282a399b765Szf 		    memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
283a399b765Szf 			return (entry);
284a399b765Szf 		entry = entry->next;
285a399b765Szf 	}
286a399b765Szf 	return (NULL);
287a399b765Szf }
288a399b765Szf 
289a399b765Szf int
pmksa_cache_list(struct wpa_supplicant * wpa_s,char * buf,size_t len)290a399b765Szf pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf, size_t len)
291a399b765Szf {
292a399b765Szf 	int i, j;
293a399b765Szf 	char *pos = buf;
294a399b765Szf 	struct rsn_pmksa_cache *entry;
295a399b765Szf 	time_t now;
296a399b765Szf 
297a399b765Szf 	(void) time(&now);
298a399b765Szf 	pos += snprintf(pos, buf + len - pos,
299a399b765Szf 	    "Index / AA / PMKID / expiration (in seconds)\n");
300a399b765Szf 	i = 0;
301a399b765Szf 	entry = wpa_s->pmksa;
302a399b765Szf 	while (entry) {
303a399b765Szf 		i++;
304a399b765Szf 		pos += snprintf(pos, buf + len - pos, "%d " MACSTR " ",
305a399b765Szf 		    i, MAC2STR(entry->aa));
306a399b765Szf 		for (j = 0; j < PMKID_LEN; j++)
307a399b765Szf 			pos += snprintf(pos, buf + len - pos, "%02x",
308a399b765Szf 			    entry->pmkid[j]);
309a399b765Szf 		pos += snprintf(pos, buf + len - pos, " %d\n",
310a399b765Szf 		    (int)(entry->expiration - now));
311a399b765Szf 		entry = entry->next;
312a399b765Szf 	}
313a399b765Szf 	return (pos - buf);
314a399b765Szf }
315a399b765Szf 
316a399b765Szf void
pmksa_candidate_free(struct wpa_supplicant * wpa_s)317a399b765Szf pmksa_candidate_free(struct wpa_supplicant *wpa_s)
318a399b765Szf {
319a399b765Szf 	struct rsn_pmksa_candidate *entry, *prev;
320a399b765Szf 
321a399b765Szf 	entry = wpa_s->pmksa_candidates;
322a399b765Szf 	wpa_s->pmksa_candidates = NULL;
323a399b765Szf 	while (entry) {
324a399b765Szf 		prev = entry;
325a399b765Szf 		entry = entry->next;
326a399b765Szf 		free(prev);
327a399b765Szf 	}
328a399b765Szf }
329a399b765Szf 
330a399b765Szf /* ARGSUSED */
331a399b765Szf static int
wpa_parse_wpa_ie_wpa(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie,size_t wpa_ie_len,struct wpa_ie_data * data)332a399b765Szf wpa_parse_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
333a399b765Szf     size_t wpa_ie_len, struct wpa_ie_data *data)
334a399b765Szf {
335a399b765Szf 	struct wpa_ie_hdr *hdr;
336a399b765Szf 	uint8_t *pos;
337a399b765Szf 	int left;
338a399b765Szf 	int i, count;
339a399b765Szf 
340a399b765Szf 	data->proto = WPA_PROTO_WPA;
341a399b765Szf 	data->pairwise_cipher = WPA_CIPHER_TKIP;
342a399b765Szf 	data->group_cipher = WPA_CIPHER_TKIP;
343a399b765Szf 	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
344a399b765Szf 	data->capabilities = 0;
345a399b765Szf 
346a399b765Szf 	if (wpa_ie_len == 0) {
347a399b765Szf 		/* No WPA IE - fail silently */
348a399b765Szf 		return (-1);
349a399b765Szf 	}
350a399b765Szf 
351a399b765Szf 	if (wpa_ie_len < sizeof (struct wpa_ie_hdr)) {
352a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
353a399b765Szf 		    "wpa_parse_wpa_ie_wpa", wpa_ie_len);
354a399b765Szf 		return (-1);
355a399b765Szf 	}
356a399b765Szf 
357a399b765Szf 	hdr = (struct wpa_ie_hdr *)wpa_ie;
358a399b765Szf 
359a399b765Szf 	if (hdr->elem_id != GENERIC_INFO_ELEM ||
360a399b765Szf 	    hdr->len != wpa_ie_len - 2 ||
361fb91fd8aSzf 	    memcmp(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN) != 0 ||
362a399b765Szf 	    LE_16(hdr->version) != WPA_VERSION) {
363a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
364a399b765Szf 		    "wpa_parse_wpa_ie_wpa");
365a399b765Szf 		return (-1);
366a399b765Szf 	}
367a399b765Szf 
368a399b765Szf 	pos = (uint8_t *)(hdr + 1);
369a399b765Szf 	left = wpa_ie_len - sizeof (*hdr);
370a399b765Szf 
371a399b765Szf 	if (left >= WPA_SELECTOR_LEN) {
372a399b765Szf 		data->group_cipher = wpa_selector_to_bitfield(pos);
373a399b765Szf 		pos += WPA_SELECTOR_LEN;
374a399b765Szf 		left -= WPA_SELECTOR_LEN;
375a399b765Szf 	} else if (left > 0) {
376a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
377a399b765Szf 		    "wpa_parse_wpa_ie_wpa", left);
378a399b765Szf 		return (-1);
379a399b765Szf 	}
380a399b765Szf 
381a399b765Szf 	if (left >= 2) {
382a399b765Szf 		data->pairwise_cipher = 0;
383a399b765Szf 		count = pos[0] | (pos[1] << 8);
384a399b765Szf 		pos += 2;
385a399b765Szf 		left -= 2;
386a399b765Szf 		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
387a399b765Szf 			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
388a399b765Szf 			    "count %u left %u",
389a399b765Szf 			    "wpa_parse_wpa_ie_wpa", count, left);
390a399b765Szf 			return (-1);
391a399b765Szf 		}
392a399b765Szf 		for (i = 0; i < count; i++) {
393a399b765Szf 			data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
394a399b765Szf 			pos += WPA_SELECTOR_LEN;
395a399b765Szf 			left -= WPA_SELECTOR_LEN;
396a399b765Szf 		}
397a399b765Szf 	} else if (left == 1) {
398a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
399a399b765Szf 		    "wpa_parse_wpa_ie_wpa");
400a399b765Szf 		return (-1);
401a399b765Szf 	}
402a399b765Szf 
403a399b765Szf 	if (left >= 2) {
404a399b765Szf 		data->key_mgmt = 0;
405a399b765Szf 		count = pos[0] | (pos[1] << 8);
406a399b765Szf 		pos += 2;
407a399b765Szf 		left -= 2;
408a399b765Szf 		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
409a399b765Szf 			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
410a399b765Szf 			    "count %u left %u",
411a399b765Szf 			    "wpa_parse_wpa_ie_wpa", count, left);
412a399b765Szf 			return (-1);
413a399b765Szf 		}
414a399b765Szf 		for (i = 0; i < count; i++) {
415a399b765Szf 			data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
416a399b765Szf 			pos += WPA_SELECTOR_LEN;
417a399b765Szf 			left -= WPA_SELECTOR_LEN;
418a399b765Szf 		}
419a399b765Szf 	} else if (left == 1) {
420a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
421a399b765Szf 		    "wpa_parse_wpa_ie_wpa");
422a399b765Szf 		return (-1);
423a399b765Szf 	}
424a399b765Szf 
425a399b765Szf 	if (left >= 2) {
426a399b765Szf 		data->capabilities = pos[0] | (pos[1] << 8);
427a399b765Szf 		pos += 2;
428a399b765Szf 		left -= 2;
429a399b765Szf 	}
430a399b765Szf 
431a399b765Szf 	if (left > 0) {
432a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes",
433a399b765Szf 		    "wpa_parse_wpa_ie_wpa", left);
434a399b765Szf 		return (-1);
435a399b765Szf 	}
436a399b765Szf 
437a399b765Szf 	return (0);
438a399b765Szf }
439a399b765Szf 
440a399b765Szf /* ARGSUSED */
441a399b765Szf static int
wpa_parse_wpa_ie_rsn(struct wpa_supplicant * wpa_s,uint8_t * rsn_ie,size_t rsn_ie_len,struct wpa_ie_data * data)442a399b765Szf wpa_parse_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie,
443a399b765Szf     size_t rsn_ie_len, struct wpa_ie_data *data)
444a399b765Szf {
445a399b765Szf 	struct rsn_ie_hdr *hdr;
446a399b765Szf 	uint8_t *pos;
447a399b765Szf 	int left;
448a399b765Szf 	int i, count;
449a399b765Szf 
450a399b765Szf 	data->proto = WPA_PROTO_RSN;
451a399b765Szf 	data->pairwise_cipher = WPA_CIPHER_CCMP;
452a399b765Szf 	data->group_cipher = WPA_CIPHER_CCMP;
453a399b765Szf 	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
454a399b765Szf 	data->capabilities = 0;
455a399b765Szf 
456a399b765Szf 	if (rsn_ie_len == 0) {
457a399b765Szf 		/* No RSN IE - fail silently */
458a399b765Szf 		return (-1);
459a399b765Szf 	}
460a399b765Szf 
461a399b765Szf 	if (rsn_ie_len < sizeof (struct rsn_ie_hdr)) {
462a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
463a399b765Szf 		    "wpa_parse_wpa_ie_rsn", rsn_ie_len);
464a399b765Szf 		return (-1);
465a399b765Szf 	}
466a399b765Szf 
467a399b765Szf 	hdr = (struct rsn_ie_hdr *)rsn_ie;
468a399b765Szf 
469a399b765Szf 	if (hdr->elem_id != RSN_INFO_ELEM ||
470a399b765Szf 	    hdr->len != rsn_ie_len - 2 ||
471a399b765Szf 	    LE_16(hdr->version) != RSN_VERSION) {
472a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
473a399b765Szf 		    "wpa_parse_wpa_ie_rsn");
474a399b765Szf 		return (-1);
475a399b765Szf 	}
476a399b765Szf 
477a399b765Szf 	pos = (uint8_t *)(hdr + 1);
478a399b765Szf 	left = rsn_ie_len - sizeof (*hdr);
479a399b765Szf 
480a399b765Szf 	if (left >= RSN_SELECTOR_LEN) {
481a399b765Szf 		data->group_cipher = rsn_selector_to_bitfield(pos);
482a399b765Szf 		pos += RSN_SELECTOR_LEN;
483a399b765Szf 		left -= RSN_SELECTOR_LEN;
484a399b765Szf 	} else if (left > 0) {
485a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
486a399b765Szf 		    "wpa_parse_wpa_ie_rsn", left);
487a399b765Szf 		return (-1);
488a399b765Szf 	}
489a399b765Szf 
490a399b765Szf 	if (left >= 2) {
491a399b765Szf 		data->pairwise_cipher = 0;
492a399b765Szf 		count = pos[0] | (pos[1] << 8);
493a399b765Szf 		pos += 2;
494a399b765Szf 		left -= 2;
495a399b765Szf 		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
496a399b765Szf 			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
497a399b765Szf 			    "count %u left %u",
498a399b765Szf 			    "wpa_parse_wpa_ie_rsn", count, left);
499a399b765Szf 			return (-1);
500a399b765Szf 		}
501a399b765Szf 		for (i = 0; i < count; i++) {
502a399b765Szf 			data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
503a399b765Szf 			pos += RSN_SELECTOR_LEN;
504a399b765Szf 			left -= RSN_SELECTOR_LEN;
505a399b765Szf 		}
506a399b765Szf 	} else if (left == 1) {
507a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
508a399b765Szf 		    "wpa_parse_wpa_ie_rsn");
509a399b765Szf 		return (-1);
510a399b765Szf 	}
511a399b765Szf 
512a399b765Szf 	if (left >= 2) {
513a399b765Szf 		data->key_mgmt = 0;
514a399b765Szf 		count = pos[0] | (pos[1] << 8);
515a399b765Szf 		pos += 2;
516a399b765Szf 		left -= 2;
517a399b765Szf 		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
518a399b765Szf 			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
519a399b765Szf 			    "count %u left %u",
520a399b765Szf 			    "wpa_parse_wpa_ie_rsn", count, left);
521a399b765Szf 			return (-1);
522a399b765Szf 		}
523a399b765Szf 		for (i = 0; i < count; i++) {
524a399b765Szf 			data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
525a399b765Szf 			pos += RSN_SELECTOR_LEN;
526a399b765Szf 			left -= RSN_SELECTOR_LEN;
527a399b765Szf 		}
528a399b765Szf 	} else if (left == 1) {
529a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
530a399b765Szf 		    "wpa_parse_wpa_ie_rsn");
531a399b765Szf 		return (-1);
532a399b765Szf 	}
533a399b765Szf 
534a399b765Szf 	if (left >= 2) {
535a399b765Szf 		data->capabilities = pos[0] | (pos[1] << 8);
536a399b765Szf 		pos += 2;
537a399b765Szf 		left -= 2;
538a399b765Szf 	}
539a399b765Szf 
540a399b765Szf 	if (left > 0) {
541a399b765Szf 		/*
542a399b765Szf 		 * RSN IE could include PMKID data, but Authenticator should
543a399b765Szf 		 * never include it, so no need to parse it in the Supplicant.
544a399b765Szf 		 */
545a399b765Szf 		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
546a399b765Szf 		    "wpa_parse_wpa_ie_rsn", left);
547a399b765Szf 	}
548a399b765Szf 
549a399b765Szf 	return (0);
550a399b765Szf }
551a399b765Szf 
552a399b765Szf int
wpa_parse_wpa_ie(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie,size_t wpa_ie_len,struct wpa_ie_data * data)553a399b765Szf wpa_parse_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
554a399b765Szf     size_t wpa_ie_len, struct wpa_ie_data *data)
555a399b765Szf {
556a399b765Szf 	if (wpa_ie_len >= 1 && wpa_ie[0] == RSN_INFO_ELEM)
557a399b765Szf 		return (wpa_parse_wpa_ie_rsn(wpa_s, wpa_ie, wpa_ie_len, data));
558a399b765Szf 	else
559a399b765Szf 		return (wpa_parse_wpa_ie_wpa(wpa_s, wpa_ie, wpa_ie_len, data));
560a399b765Szf }
561a399b765Szf 
562a399b765Szf static int
wpa_gen_wpa_ie_wpa(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie)563a399b765Szf wpa_gen_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
564a399b765Szf {
565a399b765Szf 	uint8_t *pos;
566a399b765Szf 	struct wpa_ie_hdr *hdr;
567a399b765Szf 
568a399b765Szf 	hdr = (struct wpa_ie_hdr *)wpa_ie;
569a399b765Szf 	hdr->elem_id = GENERIC_INFO_ELEM;
570fb91fd8aSzf 	(void) memcpy(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN);
571a399b765Szf 	hdr->version = LE_16(WPA_VERSION);
572a399b765Szf 	pos = (uint8_t *)(hdr + 1);
573a399b765Szf 
574a399b765Szf 	if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
575a399b765Szf 		(void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
576a399b765Szf 	} else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
577a399b765Szf 		(void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
578a399b765Szf 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
579a399b765Szf 		(void) memcpy(pos, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN);
580a399b765Szf 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
581a399b765Szf 		(void) memcpy(pos, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN);
582a399b765Szf 	} else {
583a399b765Szf 		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
584a399b765Szf 		    wpa_s->group_cipher);
585a399b765Szf 		return (-1);
586a399b765Szf 	}
587a399b765Szf 	pos += WPA_SELECTOR_LEN;
588a399b765Szf 
589a399b765Szf 	*pos++ = 1;
590a399b765Szf 	*pos++ = 0;
591a399b765Szf 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
592a399b765Szf 		(void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
593a399b765Szf 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
594a399b765Szf 		(void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
595a399b765Szf 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
596a399b765Szf 		(void) memcpy(pos, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN);
597a399b765Szf 	} else {
598a399b765Szf 		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
599a399b765Szf 		    wpa_s->pairwise_cipher);
600a399b765Szf 		return (-1);
601a399b765Szf 	}
602a399b765Szf 	pos += WPA_SELECTOR_LEN;
603a399b765Szf 
604a399b765Szf 	*pos++ = 1;
605a399b765Szf 	*pos++ = 0;
606a399b765Szf 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
607a399b765Szf 		(void) memcpy(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X,
608a399b765Szf 		    WPA_SELECTOR_LEN);
609a399b765Szf 	} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
610a399b765Szf 		(void) memcpy(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X,
611a399b765Szf 		    WPA_SELECTOR_LEN);
612a399b765Szf 	} else {
613a399b765Szf 		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
614a399b765Szf 		    wpa_s->key_mgmt);
615a399b765Szf 		return (-1);
616a399b765Szf 	}
617a399b765Szf 	pos += WPA_SELECTOR_LEN;
618a399b765Szf 
619a399b765Szf 	/*
620a399b765Szf 	 * WPA Capabilities; use defaults, so no need to include it
621a399b765Szf 	 */
622a399b765Szf 	hdr->len = (pos - wpa_ie) - 2;
623a399b765Szf 
624a399b765Szf 	return (pos - wpa_ie);
625a399b765Szf }
626a399b765Szf 
627a399b765Szf static int
wpa_gen_wpa_ie_rsn(struct wpa_supplicant * wpa_s,uint8_t * rsn_ie)628a399b765Szf wpa_gen_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie)
629a399b765Szf {
630a399b765Szf 	uint8_t *pos;
631a399b765Szf 	struct rsn_ie_hdr *hdr;
632a399b765Szf 
633a399b765Szf 	hdr = (struct rsn_ie_hdr *)rsn_ie;
634a399b765Szf 	hdr->elem_id = RSN_INFO_ELEM;
635a399b765Szf 	hdr->version = LE_16(RSN_VERSION);
636a399b765Szf 	pos = (uint8_t *)(hdr + 1);
637a399b765Szf 
638a399b765Szf 	if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
639a399b765Szf 		(void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
640a399b765Szf 	} else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
641a399b765Szf 		(void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
642a399b765Szf 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
643a399b765Szf 		(void) memcpy(pos, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN);
644a399b765Szf 	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
645a399b765Szf 		(void) memcpy(pos, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN);
646a399b765Szf 	} else {
647a399b765Szf 		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
648a399b765Szf 		    wpa_s->group_cipher);
649a399b765Szf 		return (-1);
650a399b765Szf 	}
651a399b765Szf 	pos += RSN_SELECTOR_LEN;
652a399b765Szf 
653a399b765Szf 	*pos++ = 1;
654a399b765Szf 	*pos++ = 0;
655a399b765Szf 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
656a399b765Szf 		(void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
657a399b765Szf 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
658a399b765Szf 		(void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
659a399b765Szf 	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
660a399b765Szf 		(void) memcpy(pos, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN);
661a399b765Szf 	} else {
662a399b765Szf 		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
663a399b765Szf 		    wpa_s->pairwise_cipher);
664a399b765Szf 		return (-1);
665a399b765Szf 	}
666a399b765Szf 	pos += RSN_SELECTOR_LEN;
667a399b765Szf 
668a399b765Szf 	*pos++ = 1;
669a399b765Szf 	*pos++ = 0;
670a399b765Szf 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
671a399b765Szf 		(void) memcpy(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X,
672a399b765Szf 		    RSN_SELECTOR_LEN);
673a399b765Szf 	} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
674a399b765Szf 		(void) memcpy(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X,
675a399b765Szf 		    RSN_SELECTOR_LEN);
676a399b765Szf 	} else {
677a399b765Szf 		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
678a399b765Szf 		    wpa_s->key_mgmt);
679a399b765Szf 		return (-1);
680a399b765Szf 	}
681a399b765Szf 	pos += RSN_SELECTOR_LEN;
682a399b765Szf 
683a399b765Szf 	/* RSN Capabilities */
684a399b765Szf 	*pos++ = 0;
685a399b765Szf 	*pos++ = 0;
686a399b765Szf 
687a399b765Szf 	if (wpa_s->cur_pmksa) {
688a399b765Szf 		/* PMKID Count (2 octets, little endian) */
689a399b765Szf 		*pos++ = 1;
690a399b765Szf 		*pos++ = 0;
691a399b765Szf 		/* PMKID */
692a399b765Szf 		(void) memcpy(pos, wpa_s->cur_pmksa->pmkid, PMKID_LEN);
693a399b765Szf 		pos += PMKID_LEN;
694a399b765Szf 	}
695a399b765Szf 
696a399b765Szf 	hdr->len = (pos - rsn_ie) - 2;
697a399b765Szf 
698a399b765Szf 	return (pos - rsn_ie);
699a399b765Szf }
700a399b765Szf 
701a399b765Szf int
wpa_gen_wpa_ie(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie)702a399b765Szf wpa_gen_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
703a399b765Szf {
704a399b765Szf 	if (wpa_s->proto == WPA_PROTO_RSN)
705a399b765Szf 		return (wpa_gen_wpa_ie_rsn(wpa_s, wpa_ie));
706a399b765Szf 	else
707a399b765Szf 		return (wpa_gen_wpa_ie_wpa(wpa_s, wpa_ie));
708a399b765Szf }
709a399b765Szf 
710a399b765Szf static void
wpa_pmk_to_ptk(uint8_t * pmk,uint8_t * addr1,uint8_t * addr2,uint8_t * nonce1,uint8_t * nonce2,uint8_t * ptk,size_t ptk_len)711a399b765Szf wpa_pmk_to_ptk(uint8_t *pmk, uint8_t *addr1, uint8_t *addr2,
712a399b765Szf     uint8_t *nonce1, uint8_t *nonce2, uint8_t *ptk, size_t ptk_len)
713a399b765Szf {
714a399b765Szf 	uint8_t data[2 * IEEE80211_ADDR_LEN + 2 * WPA_PMK_LEN];
715a399b765Szf 
716a399b765Szf 	/*
717a399b765Szf 	 * PTK = PRF-X(PMK, "Pairwise key expansion",
718a399b765Szf 	 * 	Min(AA, SA) || Max(AA, SA) ||
719a399b765Szf 	 * 	Min(ANonce, SNonce) || Max(ANonce, SNonce))
720a399b765Szf 	 */
721a399b765Szf 
722a399b765Szf 	if (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) < 0) {
723a399b765Szf 		(void) memcpy(data, addr1, IEEE80211_ADDR_LEN);
724a399b765Szf 		(void) memcpy(data + IEEE80211_ADDR_LEN, addr2,
725a399b765Szf 		    IEEE80211_ADDR_LEN);
726a399b765Szf 	} else {
727a399b765Szf 		(void) memcpy(data, addr2, IEEE80211_ADDR_LEN);
728a399b765Szf 		(void) memcpy(data + IEEE80211_ADDR_LEN, addr1,
729a399b765Szf 		    IEEE80211_ADDR_LEN);
730a399b765Szf 	}
731a399b765Szf 
732a399b765Szf 	if (memcmp(nonce1, nonce2, WPA_PMK_LEN) < 0) {
733a399b765Szf 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce1,
734a399b765Szf 		    WPA_PMK_LEN);
735a399b765Szf 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
736a399b765Szf 		    nonce2, WPA_PMK_LEN);
737a399b765Szf 	} else {
738a399b765Szf 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce2,
739a399b765Szf 		    WPA_PMK_LEN);
740a399b765Szf 		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
741a399b765Szf 		    nonce1, WPA_PMK_LEN);
742a399b765Szf 	}
743a399b765Szf 
744a399b765Szf 	sha1_prf(pmk, WPA_PMK_LEN, "Pairwise key expansion", data,
745a399b765Szf 	    sizeof (data), ptk, ptk_len);
746a399b765Szf 
747a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: PMK", pmk, WPA_PMK_LEN);
748a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
749a399b765Szf }
750a399b765Szf 
751a399b765Szf struct wpa_ssid *
wpa_supplicant_get_ssid(struct wpa_supplicant * wpa_s)752a399b765Szf wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
753a399b765Szf {
754a399b765Szf 	struct wpa_ssid *entry;
755a399b765Szf 	uint8_t ssid[MAX_ESSID_LENGTH];
756a399b765Szf 	int ssid_len;
757a399b765Szf 	uint8_t bssid[IEEE80211_ADDR_LEN];
758a399b765Szf 
759a399b765Szf 	(void) memset(ssid, 0, MAX_ESSID_LENGTH);
760*4ac67f02SAnurag S. Maskey 	ssid_len = wpa_s->driver->get_ssid(wpa_s->handle, wpa_s->linkid,
761*4ac67f02SAnurag S. Maskey 	    (char *)ssid);
762a399b765Szf 	if (ssid_len < 0) {
763a399b765Szf 		wpa_printf(MSG_WARNING, "Could not read SSID from driver.");
764a399b765Szf 		return (NULL);
765a399b765Szf 	}
766a399b765Szf 
767*4ac67f02SAnurag S. Maskey 	if (wpa_s->driver->get_bssid(wpa_s->handle, wpa_s->linkid,
768*4ac67f02SAnurag S. Maskey 	    (char *)bssid) < 0) {
769a399b765Szf 		wpa_printf(MSG_WARNING, "Could not read BSSID from driver.");
770a399b765Szf 		return (NULL);
771a399b765Szf 	}
772a399b765Szf 
773a399b765Szf 	entry = wpa_s->conf->ssid;
774a399b765Szf 	wpa_printf(MSG_DEBUG, "entry len=%d ssid=%s,"
775a399b765Szf 	    " driver len=%d ssid=%s",
776a399b765Szf 	    entry->ssid_len, entry->ssid, ssid_len, ssid);
777a399b765Szf 
778a399b765Szf 	if (ssid_len == entry->ssid_len &&
779a399b765Szf 	    memcmp(ssid, entry->ssid, ssid_len) == 0 &&
780a399b765Szf 	    (!entry->bssid_set ||
781a399b765Szf 	    memcmp(bssid, entry->bssid, IEEE80211_ADDR_LEN) == 0))
782a399b765Szf 		return (entry);
783a399b765Szf 
784a399b765Szf 	return (NULL);
785a399b765Szf }
786a399b765Szf 
787a399b765Szf static void
wpa_eapol_key_mic(uint8_t * key,int ver,uint8_t * buf,size_t len,uint8_t * mic)788a399b765Szf wpa_eapol_key_mic(uint8_t *key, int ver, uint8_t *buf, size_t len, uint8_t *mic)
789a399b765Szf {
790a399b765Szf 	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
791a399b765Szf 		hmac_md5(key, 16, buf, len, mic);
792a399b765Szf 	} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
793a399b765Szf 		uint8_t hash[SHA1_MAC_LEN];
794a399b765Szf 		hmac_sha1(key, 16, buf, len, hash);
795a399b765Szf 		(void) memcpy(mic, hash, MD5_MAC_LEN);
796a399b765Szf 	}
797a399b765Szf }
798a399b765Szf 
799a399b765Szf void
wpa_supplicant_key_request(struct wpa_supplicant * wpa_s,int error,int pairwise)800a399b765Szf wpa_supplicant_key_request(struct wpa_supplicant *wpa_s,
801a399b765Szf 	int error, int pairwise)
802a399b765Szf {
803a399b765Szf 	int rlen;
804a399b765Szf 	struct ieee802_1x_hdr *hdr;
805a399b765Szf 	struct wpa_eapol_key *reply;
806a399b765Szf 	unsigned char *rbuf;
807a399b765Szf 	struct l2_ethhdr *ethhdr;
808a399b765Szf 	int key_info, ver;
809a399b765Szf 	uint8_t bssid[IEEE80211_ADDR_LEN];
810a399b765Szf 
811a399b765Szf 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP)
812a399b765Szf 		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
813a399b765Szf 	else
814a399b765Szf 		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
815a399b765Szf 
816*4ac67f02SAnurag S. Maskey 	if (wpa_s->driver->get_bssid(wpa_s->handle, wpa_s->linkid,
817*4ac67f02SAnurag S. Maskey 	    (char *)bssid) < 0) {
818a399b765Szf 		wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
819a399b765Szf 		    "request");
820a399b765Szf 		return;
821a399b765Szf 	}
822a399b765Szf 
823a399b765Szf 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
824a399b765Szf 	rbuf = malloc(rlen);
825a399b765Szf 	if (rbuf == NULL)
826a399b765Szf 		return;
827a399b765Szf 
828a399b765Szf 	(void) memset(rbuf, 0, rlen);
829a399b765Szf 	ethhdr = (struct l2_ethhdr *)rbuf;
830a399b765Szf 	(void) memcpy(ethhdr->h_dest, bssid, IEEE80211_ADDR_LEN);
831a399b765Szf 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
832a399b765Szf 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
833a399b765Szf 
834a399b765Szf 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
835a399b765Szf 	hdr->version = wpa_s->conf->eapol_version;
836a399b765Szf 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
837a399b765Szf 	hdr->length = htons(sizeof (*reply));
838a399b765Szf 
839a399b765Szf 	reply = (struct wpa_eapol_key *)(hdr + 1);
840a399b765Szf 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
841d62bc4baSyz 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
842a399b765Szf 	key_info = WPA_KEY_INFO_REQUEST | ver;
843a399b765Szf 	if (wpa_s->ptk_set)
844a399b765Szf 		key_info |= WPA_KEY_INFO_MIC;
845a399b765Szf 	if (error)
846a399b765Szf 		key_info |= WPA_KEY_INFO_ERROR;
847a399b765Szf 	if (pairwise)
848a399b765Szf 		key_info |= WPA_KEY_INFO_KEY_TYPE;
849a399b765Szf 	reply->key_info = BE_16(key_info);
850a399b765Szf 	reply->key_length = 0;
851a399b765Szf 	(void) memcpy(reply->replay_counter, wpa_s->request_counter,
852d62bc4baSyz 	    WPA_REPLAY_COUNTER_LEN);
853a399b765Szf 	inc_byte_array(wpa_s->request_counter, WPA_REPLAY_COUNTER_LEN);
854a399b765Szf 
855a399b765Szf 	reply->key_data_length = BE_16(0);
856a399b765Szf 
857a399b765Szf 	if (key_info & WPA_KEY_INFO_MIC) {
858a399b765Szf 		wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
859a399b765Szf 		    rlen - sizeof (*ethhdr), reply->key_mic);
860a399b765Szf 	}
861a399b765Szf 
862a399b765Szf 	wpa_printf(MSG_INFO, "WPA: Sending EAPOL-Key Request (error=%d "
863a399b765Szf 	    "pairwise=%d ptk_set=%d len=%d)",
864a399b765Szf 	    error, pairwise, wpa_s->ptk_set, rlen);
865a399b765Szf 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key Request", rbuf, rlen);
866a399b765Szf 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
867a399b765Szf 	free(rbuf);
868a399b765Szf }
869a399b765Szf 
870a399b765Szf static void
wpa_supplicant_process_1_of_4(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,int ver)871a399b765Szf wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
872a399b765Szf     unsigned char *src_addr, struct wpa_eapol_key *key, int ver)
873a399b765Szf {
874a399b765Szf 	int rlen;
875a399b765Szf 	struct ieee802_1x_hdr *hdr;
876a399b765Szf 	struct wpa_eapol_key *reply;
877a399b765Szf 	unsigned char *rbuf;
878a399b765Szf 	struct l2_ethhdr *ethhdr;
879a399b765Szf 	struct wpa_ssid *ssid;
880a399b765Szf 	struct wpa_ptk *ptk;
881a399b765Szf 	uint8_t buf[8], wpa_ie_buf[80], *wpa_ie, *pmkid = NULL;
882a399b765Szf 	int wpa_ie_len;
883a399b765Szf 
884a399b765Szf 	wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
885a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from "
886a399b765Szf 	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
887a399b765Szf 
888a399b765Szf 	ssid = wpa_supplicant_get_ssid(wpa_s);
889a399b765Szf 	if (ssid == NULL) {
890a399b765Szf 		wpa_printf(MSG_WARNING,
891a399b765Szf 		    "WPA: No SSID info found (msg 1 of 4).");
892a399b765Szf 		return;
893a399b765Szf 	}
894a399b765Szf 
895a399b765Szf 	if (wpa_s->proto == WPA_PROTO_RSN) {
896a399b765Szf 		/* RSN: msg 1/4 should contain PMKID for the selected PMK */
897a399b765Szf 		uint8_t *pos = (uint8_t *)(key + 1);
898a399b765Szf 		uint8_t *end = pos + BE_16(key->key_data_length);
899a399b765Szf 
900a399b765Szf 		wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
901a399b765Szf 		    pos, BE_16(key->key_data_length));
902a399b765Szf 
903a399b765Szf 		while (pos + 1 < end) {
904a399b765Szf 			if (pos + 2 + pos[1] > end) {
905a399b765Szf 				wpa_printf(MSG_DEBUG, "RSN: key data "
906a399b765Szf 				    "underflow (ie=%d len=%d)",
907a399b765Szf 				    pos[0], pos[1]);
908a399b765Szf 				break;
909a399b765Szf 			}
910a399b765Szf 			if (pos[0] == GENERIC_INFO_ELEM &&
911d62bc4baSyz 			    pos + 1 + RSN_SELECTOR_LEN < end &&
912d62bc4baSyz 			    pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
913d62bc4baSyz 			    memcmp(pos + 2, RSN_KEY_DATA_PMKID,
914d62bc4baSyz 			    RSN_SELECTOR_LEN) == 0) {
915a399b765Szf 				pmkid = pos + 2 + RSN_SELECTOR_LEN;
916a399b765Szf 				wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
917a399b765Szf 				    "Authenticator", pmkid, PMKID_LEN);
918a399b765Szf 				break;
919a399b765Szf 			} else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0)
920a399b765Szf 				break;
921a399b765Szf 			pos += 2 + pos[1];
922a399b765Szf 		}
923a399b765Szf 	}
924a399b765Szf 
925a399b765Szf 	wpa_ie = wpa_ie_buf;
926a399b765Szf 	wpa_ie_len = wpa_gen_wpa_ie(wpa_s, wpa_ie);
927a399b765Szf 	if (wpa_ie_len < 0) {
928a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: Failed to generate "
929a399b765Szf 		    "WPA IE (for msg 2 of 4).");
930a399b765Szf 		return;
931a399b765Szf 	}
932a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
933a399b765Szf 
934a399b765Szf 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply) + wpa_ie_len;
935a399b765Szf 	rbuf = malloc(rlen);
936a399b765Szf 	if (rbuf == NULL)
937a399b765Szf 		return;
938a399b765Szf 
939a399b765Szf 	(void) memset(rbuf, 0, rlen);
940a399b765Szf 	ethhdr = (struct l2_ethhdr *)rbuf;
941a399b765Szf 	(void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
942a399b765Szf 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
943a399b765Szf 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
944a399b765Szf 
945a399b765Szf 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
946a399b765Szf 	hdr->version = wpa_s->conf->eapol_version;
947a399b765Szf 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
948a399b765Szf 	hdr->length = htons(sizeof (*reply) + wpa_ie_len);
949a399b765Szf 
950a399b765Szf 	reply = (struct wpa_eapol_key *)(hdr + 1);
951a399b765Szf 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
952d62bc4baSyz 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
953d62bc4baSyz 	reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
954a399b765Szf 	reply->key_length = key->key_length;
955a399b765Szf 	(void) memcpy(reply->replay_counter, key->replay_counter,
956d62bc4baSyz 	    WPA_REPLAY_COUNTER_LEN);
957a399b765Szf 
958a399b765Szf 	reply->key_data_length = BE_16(wpa_ie_len);
959a399b765Szf 	(void) memcpy(reply + 1, wpa_ie, wpa_ie_len);
960a399b765Szf 
961a399b765Szf 	if (wpa_s->renew_snonce) {
962a399b765Szf 		if (random_get_pseudo_bytes(wpa_s->snonce, WPA_NONCE_LEN)) {
963a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Failed to get "
964a399b765Szf 			    "random data for SNonce");
965a399b765Szf 			free(rbuf);
966a399b765Szf 			return;
967a399b765Szf 		}
968a399b765Szf 
969a399b765Szf 		wpa_s->renew_snonce = 0;
970a399b765Szf 		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
971a399b765Szf 		    wpa_s->snonce, WPA_NONCE_LEN);
972a399b765Szf 	}
973a399b765Szf 	(void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN);
974a399b765Szf 	ptk = &wpa_s->tptk;
975a399b765Szf 	(void) memcpy(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN);
976a399b765Szf 
977a399b765Szf 	wpa_pmk_to_ptk(wpa_s->pmk, wpa_s->own_addr, src_addr,
978a399b765Szf 	    wpa_s->snonce, key->key_nonce, (uint8_t *)ptk, sizeof (*ptk));
979a399b765Szf 
980a399b765Szf 	/*
981a399b765Szf 	 * Supplicant: swap tx/rx Mic keys
982a399b765Szf 	 */
983a399b765Szf 	(void) memcpy(buf, ptk->u.auth.tx_mic_key, 8);
984a399b765Szf 	(void) memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
985a399b765Szf 	(void) memcpy(ptk->u.auth.rx_mic_key, buf, 8);
986a399b765Szf 	wpa_s->tptk_set = 1;
987a399b765Szf 	wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, (uint8_t *)hdr,
988d62bc4baSyz 	    rlen - sizeof (*ethhdr), reply->key_mic);
989a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: EAPOL-Key MIC", reply->key_mic, 16);
990a399b765Szf 
991a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
992a399b765Szf 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/4", rbuf, rlen);
993a399b765Szf 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
994a399b765Szf 
995a399b765Szf 	free(rbuf);
996a399b765Szf }
997a399b765Szf 
998a399b765Szf static void
wpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,uint8_t * gtk,int gtk_len)999a399b765Szf wpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant *wpa_s,
1000a399b765Szf     unsigned char *src_addr, struct wpa_eapol_key *key,
1001a399b765Szf     uint8_t *gtk, int gtk_len)
1002a399b765Szf {
1003a399b765Szf 	int keyidx, tx, key_rsc_len = 0, alg;
1004a399b765Szf 
1005a399b765Szf 	wpa_hexdump(MSG_DEBUG,
1006a399b765Szf 	    "WPA: received GTK in pairwise handshake", gtk, gtk_len);
1007a399b765Szf 
1008a399b765Szf 	keyidx = gtk[0] & 0x3;
1009a399b765Szf 	tx = !!(gtk[0] & BIT(2));
1010a399b765Szf 	if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
1011a399b765Szf 		/*
1012a399b765Szf 		 * Ignore Tx bit in GTK IE if a pairwise key is used.
1013a399b765Szf 		 * One AP seemed to set this bit (incorrectly, since Tx
1014a399b765Szf 		 * is only when doing Group Key only APs) and without
1015a399b765Szf 		 * this workaround, the data connection does not work
1016a399b765Szf 		 * because wpa_supplicant configured non-zero keyidx to
1017a399b765Szf 		 * be used for unicast.
1018a399b765Szf 		 */
1019a399b765Szf 		wpa_printf(MSG_INFO, "RSN: Tx bit set for GTK IE, but "
1020a399b765Szf 		    "pairwise keys are used - ignore Tx bit");
1021a399b765Szf 		tx = 0;
1022a399b765Szf 	}
1023a399b765Szf 
1024a399b765Szf 	gtk += 2;
1025a399b765Szf 	gtk_len -= 2;
1026a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, gtk_len);
1027a399b765Szf 
1028a399b765Szf 	switch (wpa_s->group_cipher) {
1029a399b765Szf 	case WPA_CIPHER_CCMP:
1030a399b765Szf 		if (gtk_len != 16) {
1031a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP"
1032a399b765Szf 			    " Group Cipher key length %d.", gtk_len);
1033a399b765Szf 			return;
1034a399b765Szf 		}
1035a399b765Szf 		key_rsc_len = 6;
1036a399b765Szf 		alg = WPA_ALG_CCMP;
1037a399b765Szf 		break;
1038a399b765Szf 	case WPA_CIPHER_TKIP:
1039a399b765Szf 		if (gtk_len != 32) {
1040a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP"
1041a399b765Szf 			    " Group Cipher key length %d.", gtk_len);
1042a399b765Szf 			return;
1043a399b765Szf 		}
1044a399b765Szf 		key_rsc_len = 6;
1045a399b765Szf 		alg = WPA_ALG_TKIP;
1046a399b765Szf 		break;
1047a399b765Szf 	case WPA_CIPHER_WEP104:
1048a399b765Szf 		if (gtk_len != 13) {
1049a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported "
1050a399b765Szf 			    "WEP104 Group Cipher key length " "%d.", gtk_len);
1051a399b765Szf 			return;
1052a399b765Szf 		}
1053a399b765Szf 		alg = WPA_ALG_WEP;
1054a399b765Szf 		break;
1055a399b765Szf 	case WPA_CIPHER_WEP40:
1056a399b765Szf 		if (gtk_len != 5) {
1057a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported "
1058a399b765Szf 			    "WEP40 Group Cipher key length %d.", gtk_len);
1059a399b765Szf 			return;
1060a399b765Szf 		}
1061a399b765Szf 		alg = WPA_ALG_WEP;
1062a399b765Szf 		break;
1063a399b765Szf 	default:
1064a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher "
1065a399b765Szf 		    "%d", wpa_s->group_cipher);
1066a399b765Szf 		return;
1067a399b765Szf 	}
1068a399b765Szf 
1069a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "
1070a399b765Szf 	    "(keyidx=%d tx=%d).", keyidx, tx);
1071a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len);
1072a399b765Szf 	if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
1073a399b765Szf 		uint8_t tmpbuf[8];
1074a399b765Szf 		/*
1075a399b765Szf 		 * Swap Tx/Rx keys for Michael MIC
1076a399b765Szf 		 */
1077a399b765Szf 		(void) memcpy(tmpbuf, gtk + 16, 8);
1078a399b765Szf 		(void) memcpy(gtk + 16, gtk + 24, 8);
1079a399b765Szf 		(void) memcpy(gtk + 24, tmpbuf, 8);
1080a399b765Szf 	}
1081a399b765Szf 	if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
1082*4ac67f02SAnurag S. Maskey 		if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1083a399b765Szf 		    (uint8_t *)"\xff\xff\xff\xff\xff\xff",
1084a399b765Szf 		    keyidx, 1, key->key_rsc,
1085a399b765Szf 		    key_rsc_len, gtk, gtk_len) < 0)
1086a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Failed to set "
1087a399b765Szf 			    "GTK to the driver (Group only).");
1088*4ac67f02SAnurag S. Maskey 	} else if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1089d62bc4baSyz 	    (uint8_t *)"\xff\xff\xff\xff\xff\xff", keyidx, tx,
1090d62bc4baSyz 	    key->key_rsc, key_rsc_len, gtk, gtk_len) < 0) {
1091a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "
1092a399b765Szf 		    "the driver.");
1093a399b765Szf 	}
1094a399b765Szf 
1095a399b765Szf 	wpa_printf(MSG_INFO, "WPA: Key negotiation completed with "
1096d62bc4baSyz 	    MACSTR, MAC2STR(src_addr));
1097a399b765Szf 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
1098a399b765Szf 	wpa_supplicant_cancel_auth_timeout(wpa_s);
1099a399b765Szf 	wpa_s->wpa_state = WPA_COMPLETED;
1100a399b765Szf }
1101a399b765Szf 
1102a399b765Szf static void
wpa_supplicant_process_3_of_4(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,int extra_len,int ver)1103a399b765Szf wpa_supplicant_process_3_of_4(struct wpa_supplicant *wpa_s,
1104a399b765Szf     unsigned char *src_addr, struct wpa_eapol_key *key,
1105a399b765Szf     int extra_len, int ver)
1106a399b765Szf {
1107a399b765Szf 	int rlen;
1108a399b765Szf 	struct ieee802_1x_hdr *hdr;
1109a399b765Szf 	struct wpa_eapol_key *reply;
1110a399b765Szf 	unsigned char *rbuf;
1111a399b765Szf 	struct l2_ethhdr *ethhdr;
1112a399b765Szf 	int key_info, ie_len = 0, keylen, gtk_len = 0;
1113a399b765Szf 	uint8_t *ie = NULL, *gtk = NULL, *key_rsc;
1114a399b765Szf 	uint8_t null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1115a399b765Szf 
1116a399b765Szf 	wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
1117a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from "
1118a399b765Szf 	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1119a399b765Szf 
1120a399b765Szf 	key_info = BE_16(key->key_info);
1121a399b765Szf 
1122a399b765Szf 	if (wpa_s->proto == WPA_PROTO_RSN) {
1123a399b765Szf 		uint8_t *pos = (uint8_t *)(key + 1);
1124a399b765Szf 		uint8_t *end = pos + BE_16(key->key_data_length);
1125a399b765Szf 		while (pos + 1 < end) {
1126a399b765Szf 			if (pos + 2 + pos[1] > end) {
1127a399b765Szf 				wpa_printf(MSG_DEBUG, "RSN: key data "
1128a399b765Szf 				    "underflow (ie=%d len=%d)",
1129a399b765Szf 				    pos[0], pos[1]);
1130a399b765Szf 				break;
1131a399b765Szf 			}
1132a399b765Szf 			if (*pos == RSN_INFO_ELEM) {
1133a399b765Szf 				ie = pos;
1134a399b765Szf 				ie_len = pos[1] + 2;
1135a399b765Szf 			} else if (pos[0] == GENERIC_INFO_ELEM &&
1136d62bc4baSyz 			    pos + 1 + RSN_SELECTOR_LEN < end &&
1137d62bc4baSyz 			    pos[1] > RSN_SELECTOR_LEN + 2 &&
1138d62bc4baSyz 			    memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY,
1139d62bc4baSyz 			    RSN_SELECTOR_LEN) == 0) {
1140a399b765Szf 				if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1141a399b765Szf 					wpa_printf(MSG_WARNING, "WPA: GTK IE "
1142a399b765Szf 					    "in unencrypted key data");
1143a399b765Szf 					return;
1144a399b765Szf 				}
1145a399b765Szf 				gtk = pos + 2 + RSN_SELECTOR_LEN;
1146a399b765Szf 				gtk_len = pos[1] - RSN_SELECTOR_LEN;
1147a399b765Szf 			} else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0)
1148a399b765Szf 				break;
1149a399b765Szf 
1150a399b765Szf 			pos += 2 + pos[1];
1151a399b765Szf 		}
1152a399b765Szf 	} else {
1153a399b765Szf 		ie = (uint8_t *)(key + 1);
1154a399b765Szf 		ie_len = BE_16(key->key_data_length);
1155a399b765Szf 		if (ie_len > extra_len) {
1156a399b765Szf 			wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"
1157a399b765Szf 			    " ie_len=%d > extra_len=%d",
1158a399b765Szf 			    ie_len, extra_len);
1159a399b765Szf 			return;
1160a399b765Szf 		}
1161a399b765Szf 	}
1162a399b765Szf 
1163a399b765Szf 	if (wpa_s->ap_wpa_ie &&
1164a399b765Szf 	    (wpa_s->ap_wpa_ie_len != ie_len ||
1165d62bc4baSyz 	    memcmp(wpa_s->ap_wpa_ie, ie, ie_len) != 0)) {
1166a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: WPA IE in 3/4 msg does not match"
1167a399b765Szf 		    " with WPA IE in Beacon/ProbeResp (src=" MACSTR ")",
1168a399b765Szf 		    MAC2STR(src_addr));
1169a399b765Szf 		wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
1170a399b765Szf 		    wpa_s->ap_wpa_ie, wpa_s->ap_wpa_ie_len);
1171a399b765Szf 		wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg", ie, ie_len);
1172a399b765Szf 		wpa_supplicant_disassociate(wpa_s, REASON_IE_IN_4WAY_DIFFERS);
1173a399b765Szf 		wpa_supplicant_req_scan(wpa_s, 0, 0);
1174a399b765Szf 		return;
1175a399b765Szf 	}
1176a399b765Szf 
1177a399b765Szf 	if (memcmp(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
1178a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way "
1179a399b765Szf 		    "Handshake differs from 3 of 4-Way Handshake - drop"
1180a399b765Szf 		    " packet (src=" MACSTR ")", MAC2STR(src_addr));
1181a399b765Szf 		return;
1182a399b765Szf 	}
1183a399b765Szf 
1184a399b765Szf 	keylen = BE_16(key->key_length);
1185a399b765Szf 	switch (wpa_s->pairwise_cipher) {
1186a399b765Szf 	case WPA_CIPHER_CCMP:
1187a399b765Szf 		if (keylen != 16) {
1188a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "
1189a399b765Szf 			    "%d (src=" MACSTR ")",
1190a399b765Szf 			    keylen, MAC2STR(src_addr));
1191a399b765Szf 			return;
1192a399b765Szf 		}
1193a399b765Szf 		break;
1194a399b765Szf 	case WPA_CIPHER_TKIP:
1195a399b765Szf 		if (keylen != 32) {
1196a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length "
1197a399b765Szf 			    "%d (src=" MACSTR ")",
1198a399b765Szf 			    keylen, MAC2STR(src_addr));
1199a399b765Szf 			return;
1200a399b765Szf 		}
1201a399b765Szf 		break;
1202a399b765Szf 	}
1203a399b765Szf 
1204a399b765Szf 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
1205a399b765Szf 	rbuf = malloc(rlen);
1206a399b765Szf 	if (rbuf == NULL)
1207a399b765Szf 		return;
1208a399b765Szf 
1209a399b765Szf 	(void) memset(rbuf, 0, rlen);
1210a399b765Szf 	ethhdr = (struct l2_ethhdr *)rbuf;
1211a399b765Szf 	(void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
1212a399b765Szf 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
1213a399b765Szf 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
1214a399b765Szf 
1215a399b765Szf 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
1216a399b765Szf 	hdr->version = wpa_s->conf->eapol_version;
1217a399b765Szf 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
1218a399b765Szf 	hdr->length = htons(sizeof (*reply));
1219a399b765Szf 
1220a399b765Szf 	reply = (struct wpa_eapol_key *)(hdr + 1);
1221a399b765Szf 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
1222d62bc4baSyz 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1223a399b765Szf 	reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE |
1224d62bc4baSyz 	    WPA_KEY_INFO_MIC | (key_info & WPA_KEY_INFO_SECURE));
1225a399b765Szf 	reply->key_length = key->key_length;
1226a399b765Szf 	(void) memcpy(reply->replay_counter, key->replay_counter,
1227d62bc4baSyz 	    WPA_REPLAY_COUNTER_LEN);
1228a399b765Szf 
1229a399b765Szf 	reply->key_data_length = BE_16(0);
1230a399b765Szf 
1231a399b765Szf 	(void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN);
1232a399b765Szf 	wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
1233a399b765Szf 	    rlen - sizeof (*ethhdr), reply->key_mic);
1234a399b765Szf 
1235a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
1236a399b765Szf 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 4/4", rbuf, rlen);
1237a399b765Szf 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
1238a399b765Szf 
1239a399b765Szf 	free(rbuf);
1240a399b765Szf 
1241a399b765Szf 	/*
1242a399b765Szf 	 * SNonce was successfully used in msg 3/4, so mark it to be renewed
1243a399b765Szf 	 * for the next 4-Way Handshake. If msg 3 is received again, the old
1244a399b765Szf 	 * SNonce will still be used to avoid changing PTK.
1245a399b765Szf 	 */
1246a399b765Szf 	wpa_s->renew_snonce = 1;
1247a399b765Szf 
1248a399b765Szf 	if (key_info & WPA_KEY_INFO_INSTALL) {
1249a399b765Szf 		int alg, keylen, rsclen;
1250a399b765Szf 		wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.");
1251a399b765Szf 		switch (wpa_s->pairwise_cipher) {
1252a399b765Szf 		case WPA_CIPHER_CCMP:
1253a399b765Szf 			alg = WPA_ALG_CCMP;
1254a399b765Szf 			keylen = 16;
1255a399b765Szf 			rsclen = 6;
1256a399b765Szf 			break;
1257a399b765Szf 		case WPA_CIPHER_TKIP:
1258a399b765Szf 			alg = WPA_ALG_TKIP;
1259a399b765Szf 			keylen = 32;
1260a399b765Szf 			rsclen = 6;
1261a399b765Szf 			break;
1262a399b765Szf 		case WPA_CIPHER_NONE:
1263a399b765Szf 			wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: "
1264a399b765Szf 			    "NONE - do not use pairwise keys");
1265a399b765Szf 			return;
1266a399b765Szf 		default:
1267a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise "
1268a399b765Szf 			    "cipher %d", wpa_s->pairwise_cipher);
1269a399b765Szf 			return;
1270a399b765Szf 		}
1271a399b765Szf 		if (wpa_s->proto == WPA_PROTO_RSN) {
1272a399b765Szf 			key_rsc = null_rsc;
1273a399b765Szf 		} else {
1274a399b765Szf 			key_rsc = key->key_rsc;
1275a399b765Szf 			wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
1276a399b765Szf 		}
1277a399b765Szf 
1278*4ac67f02SAnurag S. Maskey 		if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1279*4ac67f02SAnurag S. Maskey 		    src_addr, 0, 1, key_rsc, rsclen,
1280a399b765Szf 		    (uint8_t *)&wpa_s->ptk.tk1, keylen) < 0) {
1281a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the"
1282a399b765Szf 			    " driver.");
1283a399b765Szf 		}
1284a399b765Szf 	}
1285a399b765Szf 
1286a399b765Szf 	wpa_printf(MSG_DEBUG, "%s: key_info=%x gtk=%p\n",
1287a399b765Szf 	    "wpa_supplicant_process_3_of_4", key_info, gtk);
1288a399b765Szf 	wpa_s->wpa_state = WPA_GROUP_HANDSHAKE;
1289a399b765Szf 
1290a399b765Szf 	if (gtk)
1291a399b765Szf 		wpa_supplicant_process_3_of_4_gtk(wpa_s,
1292a399b765Szf 		    src_addr, key, gtk, gtk_len);
1293a399b765Szf }
1294a399b765Szf 
1295a399b765Szf static void
wpa_supplicant_process_1_of_2(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,int extra_len,int ver)1296a399b765Szf wpa_supplicant_process_1_of_2(struct wpa_supplicant *wpa_s,
1297a399b765Szf     unsigned char *src_addr, struct wpa_eapol_key *key,
1298a399b765Szf     int extra_len, int ver)
1299a399b765Szf {
1300a399b765Szf 	int rlen;
1301a399b765Szf 	struct ieee802_1x_hdr *hdr;
1302a399b765Szf 	struct wpa_eapol_key *reply;
1303a399b765Szf 	unsigned char *rbuf;
1304a399b765Szf 	struct l2_ethhdr *ethhdr;
1305a399b765Szf 	int key_info, keylen, keydatalen, maxkeylen, keyidx, key_rsc_len = 0;
1306a399b765Szf 	int alg, tx;
1307a399b765Szf 	uint8_t ek[32], tmpbuf[8], gtk[32];
1308a399b765Szf 	uint8_t *gtk_ie = NULL;
1309a399b765Szf 	size_t gtk_ie_len = 0;
1310a399b765Szf 
1311a399b765Szf 	wpa_s->wpa_state = WPA_GROUP_HANDSHAKE;
1312a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of Group Key Handshake from "
1313a399b765Szf 	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1314a399b765Szf 
1315a399b765Szf 	key_info = BE_16(key->key_info);
1316a399b765Szf 	keydatalen = BE_16(key->key_data_length);
1317a399b765Szf 
1318a399b765Szf 	if (wpa_s->proto == WPA_PROTO_RSN) {
1319a399b765Szf 		uint8_t *pos = (uint8_t *)(key + 1);
1320a399b765Szf 		uint8_t *end = pos + keydatalen;
1321a399b765Szf 		while (pos + 1 < end) {
1322a399b765Szf 			if (pos + 2 + pos[1] > end) {
1323a399b765Szf 				wpa_printf(MSG_DEBUG, "RSN: key data "
1324a399b765Szf 				    "underflow (ie=%d len=%d)",
1325a399b765Szf 				    pos[0], pos[1]);
1326a399b765Szf 				break;
1327a399b765Szf 			}
1328a399b765Szf 			if (pos[0] == GENERIC_INFO_ELEM &&
1329a399b765Szf 			    pos + 1 + RSN_SELECTOR_LEN < end &&
1330a399b765Szf 			    pos[1] > RSN_SELECTOR_LEN + 2 &&
1331a399b765Szf 			    memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY,
1332a399b765Szf 			    RSN_SELECTOR_LEN) == 0) {
1333a399b765Szf 				if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1334a399b765Szf 					wpa_printf(MSG_WARNING, "WPA: GTK IE "
1335a399b765Szf 					    "in unencrypted key data");
1336a399b765Szf 					return;
1337a399b765Szf 				}
1338a399b765Szf 				gtk_ie = pos + 2 + RSN_SELECTOR_LEN;
1339a399b765Szf 				gtk_ie_len = pos[1] - RSN_SELECTOR_LEN;
1340a399b765Szf 				break;
1341d62bc4baSyz 			} else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0) {
1342a399b765Szf 				break;
1343d62bc4baSyz 			}
1344a399b765Szf 
1345a399b765Szf 			pos += 2 + pos[1];
1346a399b765Szf 		}
1347a399b765Szf 
1348a399b765Szf 		if (gtk_ie == NULL) {
1349a399b765Szf 			wpa_printf(MSG_INFO, "WPA: No GTK IE in Group Key "
1350a399b765Szf 			    "message 1/2");
1351a399b765Szf 			return;
1352a399b765Szf 		}
1353a399b765Szf 		maxkeylen = keylen = gtk_ie_len - 2;
1354a399b765Szf 	} else {
1355a399b765Szf 		keylen = BE_16(key->key_length);
1356a399b765Szf 		maxkeylen = keydatalen;
1357a399b765Szf 		if (keydatalen > extra_len) {
1358a399b765Szf 			wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"
1359a399b765Szf 			    " key_data_length=%d > extra_len=%d",
1360a399b765Szf 			    keydatalen, extra_len);
1361a399b765Szf 			return;
1362a399b765Szf 		}
1363a399b765Szf 		if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES)
1364a399b765Szf 			maxkeylen -= 8;
1365a399b765Szf 	}
1366a399b765Szf 
1367a399b765Szf 	switch (wpa_s->group_cipher) {
1368a399b765Szf 	case WPA_CIPHER_CCMP:
1369a399b765Szf 		if (keylen != 16 || maxkeylen < 16) {
1370a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP Group "
1371a399b765Szf 			    "Cipher key length %d (%d).", keylen, maxkeylen);
1372a399b765Szf 			return;
1373a399b765Szf 		}
1374a399b765Szf 		key_rsc_len = 6;
1375a399b765Szf 		alg = WPA_ALG_CCMP;
1376a399b765Szf 		break;
1377a399b765Szf 	case WPA_CIPHER_TKIP:
1378a399b765Szf 		if (keylen != 32 || maxkeylen < 32) {
1379a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP Group "
1380a399b765Szf 			    "Cipher key length %d (%d).", keylen, maxkeylen);
1381a399b765Szf 			return;
1382a399b765Szf 		}
1383a399b765Szf 		key_rsc_len = 6; /* key->key_data; */
1384a399b765Szf 		alg = WPA_ALG_TKIP;
1385a399b765Szf 		break;
1386a399b765Szf 	case WPA_CIPHER_WEP104:
1387a399b765Szf 		if (keylen != 13 || maxkeylen < 13) {
1388a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported WEP104 Group"
1389a399b765Szf 			    " Cipher key length %d (%d).", keylen, maxkeylen);
1390a399b765Szf 			return;
1391a399b765Szf 		}
1392a399b765Szf 		alg = WPA_ALG_WEP;
1393a399b765Szf 		break;
1394a399b765Szf 	case WPA_CIPHER_WEP40:
1395a399b765Szf 		if (keylen != 5 || maxkeylen < 5) {
1396a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported WEP40 Group "
1397a399b765Szf 			    "Cipher key length %d (%d).", keylen, maxkeylen);
1398a399b765Szf 			return;
1399a399b765Szf 		}
1400a399b765Szf 		alg = WPA_ALG_WEP;
1401a399b765Szf 		break;
1402a399b765Szf 	default:
1403a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher %d",
1404a399b765Szf 		    wpa_s->group_cipher);
1405a399b765Szf 		return;
1406a399b765Szf 	}
1407a399b765Szf 
1408a399b765Szf 	if (wpa_s->proto == WPA_PROTO_RSN) {
1409a399b765Szf 		wpa_hexdump(MSG_DEBUG,
1410a399b765Szf 		    "WPA: received GTK in group key handshake",
1411a399b765Szf 		    gtk_ie, gtk_ie_len);
1412a399b765Szf 		keyidx = gtk_ie[0] & 0x3;
1413a399b765Szf 		tx = !!(gtk_ie[0] & BIT(2));
1414a399b765Szf 		if (gtk_ie_len - 2 > sizeof (gtk)) {
1415a399b765Szf 			wpa_printf(MSG_INFO, "WPA: Too long GTK in GTK IE "
1416a399b765Szf 			    "(len=%d)", gtk_ie_len - 2);
1417a399b765Szf 			return;
1418a399b765Szf 		}
1419a399b765Szf 		(void) memcpy(gtk, gtk_ie + 2, gtk_ie_len - 2);
1420a399b765Szf 	} else {
1421a399b765Szf 		keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1422d62bc4baSyz 		    WPA_KEY_INFO_KEY_INDEX_SHIFT;
1423a399b765Szf 		if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
1424a399b765Szf 			(void) memcpy(ek, key->key_iv, 16);
1425a399b765Szf 			(void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16);
1426a399b765Szf 			rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen);
1427a399b765Szf 			(void) memcpy(gtk, key + 1, keylen);
1428a399b765Szf 		} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1429a399b765Szf 			if (keydatalen % 8) {
1430a399b765Szf 				wpa_printf(MSG_WARNING, "WPA: Unsupported "
1431a399b765Szf 				    "AES-WRAP len %d", keydatalen);
1432a399b765Szf 				return;
1433a399b765Szf 			}
1434a399b765Szf 			if (aes_unwrap(wpa_s->ptk.encr_key, maxkeylen / 8,
1435d62bc4baSyz 			    (uint8_t *)(key + 1), gtk)) {
1436a399b765Szf 				wpa_printf(MSG_WARNING, "WPA: AES unwrap "
1437a399b765Szf 				    "failed - could not decrypt GTK");
1438a399b765Szf 				return;
1439a399b765Szf 			}
1440a399b765Szf 		}
1441a399b765Szf 		tx = !!(key_info & WPA_KEY_INFO_TXRX);
1442a399b765Szf 		if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
1443a399b765Szf 			/*
1444a399b765Szf 			 * Ignore Tx bit in Group Key message if a pairwise key
1445a399b765Szf 			 * is used. Some APs seem to setting this bit
1446a399b765Szf 			 * (incorrectly, since Tx is only when doing Group Key
1447a399b765Szf 			 * only APs) and without this workaround, the data
1448a399b765Szf 			 * connection does not work because wpa_supplicant
1449a399b765Szf 			 * configured non-zero keyidx to be used for unicast.
1450a399b765Szf 			 */
1451a399b765Szf 			wpa_printf(MSG_INFO, "WPA: Tx bit set for GTK, but "
1452a399b765Szf 			    "pairwise keys are used - ignore Tx bit");
1453a399b765Szf 			tx = 0;
1454a399b765Szf 		}
1455a399b765Szf 	}
1456a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, keylen);
1457a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver (keyidx=%d "
1458a399b765Szf 	    "tx=%d).", keyidx, tx);
1459a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len);
1460a399b765Szf 	if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
1461a399b765Szf 		/*
1462a399b765Szf 		 * Swap Tx/Rx keys for Michael MIC
1463a399b765Szf 		 */
1464a399b765Szf 		(void) memcpy(tmpbuf, gtk + 16, 8);
1465a399b765Szf 		(void) memcpy(gtk + 16, gtk + 24, 8);
1466a399b765Szf 		(void) memcpy(gtk + 24, tmpbuf, 8);
1467a399b765Szf 	}
1468a399b765Szf 	if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
1469*4ac67f02SAnurag S. Maskey 		if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1470a399b765Szf 		    (uint8_t *)"\xff\xff\xff\xff\xff\xff",
1471a399b765Szf 		    keyidx, 1, key->key_rsc,
1472a399b765Szf 		    key_rsc_len, gtk, keylen) < 0)
1473a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the"
1474a399b765Szf 			    " driver (Group only).");
1475*4ac67f02SAnurag S. Maskey 	} else if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1476a399b765Szf 	    (uint8_t *)"\xff\xff\xff\xff\xff\xff",
1477a399b765Szf 	    keyidx, tx,
1478a399b765Szf 	    key->key_rsc, key_rsc_len,
1479a399b765Szf 	    gtk, keylen) < 0) {
1480a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the "
1481a399b765Szf 		    "driver.");
1482a399b765Szf 	}
1483a399b765Szf 
1484a399b765Szf 	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
1485a399b765Szf 	rbuf = malloc(rlen);
1486a399b765Szf 	if (rbuf == NULL)
1487a399b765Szf 		return;
1488a399b765Szf 
1489a399b765Szf 	(void) memset(rbuf, 0, rlen);
1490a399b765Szf 	ethhdr = (struct l2_ethhdr *)rbuf;
1491a399b765Szf 	(void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
1492a399b765Szf 	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
1493a399b765Szf 	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
1494a399b765Szf 
1495a399b765Szf 	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
1496a399b765Szf 	hdr->version = wpa_s->conf->eapol_version;
1497a399b765Szf 	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
1498a399b765Szf 	hdr->length = htons(sizeof (*reply));
1499a399b765Szf 
1500a399b765Szf 	reply = (struct wpa_eapol_key *)(hdr + 1);
1501a399b765Szf 	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
1502a399b765Szf 	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1503a399b765Szf 	reply->key_info =
1504a399b765Szf 	    BE_16(ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE |
1505a399b765Szf 	    (key_info & WPA_KEY_INFO_KEY_INDEX_MASK));
1506a399b765Szf 	reply->key_length = key->key_length;
1507a399b765Szf 	(void) memcpy(reply->replay_counter, key->replay_counter,
1508a399b765Szf 	    WPA_REPLAY_COUNTER_LEN);
1509a399b765Szf 
1510a399b765Szf 	reply->key_data_length = BE_16(0);
1511a399b765Szf 
1512a399b765Szf 	wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
1513a399b765Szf 	    rlen - sizeof (*ethhdr), reply->key_mic);
1514a399b765Szf 
1515a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
1516a399b765Szf 	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/2", rbuf, rlen);
1517a399b765Szf 	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
1518a399b765Szf 	free(rbuf);
1519a399b765Szf 
1520a399b765Szf 	wpa_printf(MSG_INFO, "WPA: Key negotiation completed with " MACSTR,
1521a399b765Szf 	    MAC2STR(src_addr));
1522a399b765Szf 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
1523a399b765Szf 	wpa_supplicant_cancel_auth_timeout(wpa_s);
1524a399b765Szf 	wpa_s->wpa_state = WPA_COMPLETED;
1525a399b765Szf 	wpa_printf(MSG_INFO, "-----------------------------------\n");
1526a399b765Szf }
1527a399b765Szf 
1528a399b765Szf static int
wpa_supplicant_verify_eapol_key_mic(struct wpa_supplicant * wpa_s,struct wpa_eapol_key * key,int ver,uint8_t * buf,size_t len)1529a399b765Szf wpa_supplicant_verify_eapol_key_mic(struct wpa_supplicant *wpa_s,
1530a399b765Szf     struct wpa_eapol_key *key, int ver, uint8_t *buf, size_t len)
1531a399b765Szf {
1532a399b765Szf 	uint8_t mic[16];
1533a399b765Szf 	int ok = 0;
1534a399b765Szf 
1535a399b765Szf 	(void) memcpy(mic, key->key_mic, 16);
1536a399b765Szf 	if (wpa_s->tptk_set) {
1537a399b765Szf 		(void) memset(key->key_mic, 0, 16);
1538a399b765Szf 		wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, buf, len,
1539a399b765Szf 		    key->key_mic);
1540a399b765Szf 		if (memcmp(mic, key->key_mic, 16) != 0) {
1541a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
1542a399b765Szf 			    "when using TPTK - ignoring TPTK");
1543a399b765Szf 		} else {
1544a399b765Szf 			ok = 1;
1545a399b765Szf 			wpa_s->tptk_set = 0;
1546a399b765Szf 			wpa_s->ptk_set = 1;
1547a399b765Szf 			(void) memcpy(&wpa_s->ptk, &wpa_s->tptk,
1548a399b765Szf 			    sizeof (wpa_s->ptk));
1549a399b765Szf 		}
1550a399b765Szf 	}
1551a399b765Szf 
1552a399b765Szf 	if (!ok && wpa_s->ptk_set) {
1553a399b765Szf 		(void) memset(key->key_mic, 0, 16);
1554a399b765Szf 		wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, buf, len,
1555a399b765Szf 		    key->key_mic);
1556a399b765Szf 		if (memcmp(mic, key->key_mic, 16) != 0) {
1557a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
1558a399b765Szf 			    "- dropping packet");
1559a399b765Szf 			return (-1);
1560a399b765Szf 		}
1561a399b765Szf 		ok = 1;
1562a399b765Szf 	}
1563a399b765Szf 
1564a399b765Szf 	if (!ok) {
1565a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: Could not verify EAPOL-Key MIC "
1566a399b765Szf 		    "- dropping packet");
1567a399b765Szf 		return (-1);
1568a399b765Szf 	}
1569a399b765Szf 
1570a399b765Szf 	(void) memcpy(wpa_s->rx_replay_counter, key->replay_counter,
1571a399b765Szf 	    WPA_REPLAY_COUNTER_LEN);
1572a399b765Szf 	wpa_s->rx_replay_counter_set = 1;
1573a399b765Szf 
1574a399b765Szf 	return (0);
1575a399b765Szf }
1576a399b765Szf 
1577a399b765Szf /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
1578a399b765Szf static int
wpa_supplicant_decrypt_key_data(struct wpa_supplicant * wpa_s,struct wpa_eapol_key * key,int ver)1579a399b765Szf wpa_supplicant_decrypt_key_data(struct wpa_supplicant *wpa_s,
1580a399b765Szf 	struct wpa_eapol_key *key, int ver)
1581a399b765Szf {
1582a399b765Szf 	int keydatalen = BE_16(key->key_data_length);
1583a399b765Szf 
1584a399b765Szf 	wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
1585a399b765Szf 	    (uint8_t *)(key + 1), keydatalen);
1586a399b765Szf 	if (!wpa_s->ptk_set) {
1587a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: PTK not available, "
1588a399b765Szf 		    "cannot decrypt EAPOL-Key key data.");
1589a399b765Szf 		return (-1);
1590a399b765Szf 	}
1591a399b765Szf 
1592a399b765Szf 	/*
1593a399b765Szf 	 * Decrypt key data here so that this operation does not need
1594a399b765Szf 	 * to be implemented separately for each message type.
1595a399b765Szf 	 */
1596a399b765Szf 	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
1597a399b765Szf 		uint8_t ek[32];
1598a399b765Szf 		(void) memcpy(ek, key->key_iv, 16);
1599a399b765Szf 		(void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16);
1600a399b765Szf 		rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen);
1601a399b765Szf 	} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1602a399b765Szf 		uint8_t *buf;
1603a399b765Szf 		if (keydatalen % 8) {
1604a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Unsupported "
1605a399b765Szf 			    "AES-WRAP len %d", keydatalen);
1606a399b765Szf 			return (-1);
1607a399b765Szf 		}
1608a399b765Szf 		keydatalen -= 8; /* AES-WRAP adds 8 bytes */
1609a399b765Szf 		buf = malloc(keydatalen);
1610a399b765Szf 		if (buf == NULL) {
1611a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: No memory for "
1612a399b765Szf 			    "AES-UNWRAP buffer");
1613a399b765Szf 			return (-1);
1614a399b765Szf 		}
1615a399b765Szf 		if (aes_unwrap(wpa_s->ptk.encr_key, keydatalen / 8,
1616a399b765Szf 		    (uint8_t *)(key + 1), buf)) {
1617a399b765Szf 			free(buf);
1618a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: AES unwrap failed - "
1619a399b765Szf 			    "could not decrypt EAPOL-Key key data");
1620a399b765Szf 			return (-1);
1621a399b765Szf 		}
1622a399b765Szf 		(void) memcpy(key + 1, buf, keydatalen);
1623a399b765Szf 		free(buf);
1624a399b765Szf 		key->key_data_length = BE_16(keydatalen);
1625a399b765Szf 	}
1626a399b765Szf 	wpa_hexdump(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
1627a399b765Szf 	    (uint8_t *)(key + 1), keydatalen);
1628a399b765Szf 
1629a399b765Szf 	return (0);
1630a399b765Szf }
1631a399b765Szf 
1632a399b765Szf static void
wpa_sm_rx_eapol(struct wpa_supplicant * wpa_s,unsigned char * src_addr,unsigned char * buf,size_t len)1633a399b765Szf wpa_sm_rx_eapol(struct wpa_supplicant *wpa_s,
1634a399b765Szf     unsigned char *src_addr, unsigned char *buf, size_t len)
1635a399b765Szf {
1636a399b765Szf 	size_t plen, data_len, extra_len;
1637a399b765Szf 	struct ieee802_1x_hdr *hdr;
1638a399b765Szf 	struct wpa_eapol_key *key;
1639a399b765Szf 	int key_info, ver;
1640a399b765Szf 
1641a399b765Szf 	wpa_printf(MSG_DEBUG, "WPA: EAPOL frame len %u\n ", len);
1642a399b765Szf 
1643a399b765Szf 	hdr = (struct ieee802_1x_hdr *)buf;
1644a399b765Szf 	key = (struct wpa_eapol_key *)(hdr + 1);
1645a399b765Szf 	wpa_printf(MSG_DEBUG, "hdr_len=%u, key_len=%u",
1646a399b765Szf 	    sizeof (*hdr), sizeof (*key));
1647a399b765Szf 	if (len < sizeof (*hdr) + sizeof (*key)) {
1648a399b765Szf 		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short, len %u, "
1649a399b765Szf 		    "expecting at least %u",
1650a399b765Szf 		    len, sizeof (*hdr) + sizeof (*key));
1651a399b765Szf 		return;
1652a399b765Szf 	}
1653a399b765Szf 	plen = ntohs(hdr->length);
1654a399b765Szf 	data_len = plen + sizeof (*hdr);
1655a399b765Szf 	wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d",
1656a399b765Szf 	    hdr->version, hdr->type, plen);
1657a399b765Szf 
1658a399b765Szf 	if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
1659a399b765Szf 		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame (type %u) discarded, "
1660a399b765Szf 		    "not a Key frame", hdr->type);
1661a399b765Szf 		return;
1662a399b765Szf 	}
1663a399b765Szf 	if (plen > len - sizeof (*hdr) || plen < sizeof (*key)) {
1664a399b765Szf 		wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %u "
1665a399b765Szf 		    "invalid (frame size %u)", plen, len);
1666a399b765Szf 		return;
1667a399b765Szf 	}
1668a399b765Szf 
1669a399b765Szf 	wpa_printf(MSG_DEBUG, "  EAPOL-Key type=%d", key->type);
1670a399b765Szf 	if (key->type != EAPOL_KEY_TYPE_WPA && key->type !=
1671a399b765Szf 	    EAPOL_KEY_TYPE_RSN) {
1672a399b765Szf 		wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key type (%d) unknown, "
1673a399b765Szf 		    "discarded", key->type);
1674a399b765Szf 		return;
1675a399b765Szf 	}
1676a399b765Szf 
1677a399b765Szf 	wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
1678a399b765Szf 	if (data_len < len) {
1679a399b765Szf 		wpa_printf(MSG_DEBUG, "WPA: ignoring %d bytes after the IEEE "
1680a399b765Szf 		    "802.1X data", len - data_len);
1681a399b765Szf 	}
1682a399b765Szf 	key_info = BE_16(key->key_info);
1683a399b765Szf 	ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1684a399b765Szf 	if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1685a399b765Szf 	    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1686a399b765Szf 		wpa_printf(MSG_INFO, "WPA: Unsupported EAPOL-Key descriptor "
1687a399b765Szf 		    "version %d.", ver);
1688a399b765Szf 		return;
1689a399b765Szf 	}
1690a399b765Szf 
1691a399b765Szf 	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP &&
1692a399b765Szf 	    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1693a399b765Szf 		wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key "
1694a399b765Szf 		    "descriptor version (%d) is not 2.", ver);
1695a399b765Szf 		if (wpa_s->group_cipher != WPA_CIPHER_CCMP &&
1696a399b765Szf 		    !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
1697a399b765Szf 			/*
1698a399b765Szf 			 * Earlier versions of IEEE 802.11i did not explicitly
1699a399b765Szf 			 * require version 2 descriptor for all EAPOL-Key
1700a399b765Szf 			 * packets, so allow group keys to use version 1 if
1701a399b765Szf 			 * CCMP is not used for them.
1702a399b765Szf 			 */
1703a399b765Szf 			wpa_printf(MSG_INFO, "WPA: Backwards compatibility: "
1704a399b765Szf 			    "allow invalid version for non-CCMP group keys");
1705a399b765Szf 		} else
1706a399b765Szf 			return;
1707a399b765Szf 	}
1708a399b765Szf 
1709a399b765Szf 	if (wpa_s->rx_replay_counter_set &&
1710a399b765Szf 	    memcmp(key->replay_counter, wpa_s->rx_replay_counter,
1711a399b765Szf 	    WPA_REPLAY_COUNTER_LEN) <= 0) {
1712a399b765Szf 		wpa_printf(MSG_WARNING, "WPA: EAPOL-Key Replay Counter did not"
1713a399b765Szf 		    " increase - dropping packet");
1714a399b765Szf 		return;
1715a399b765Szf 	}
1716a399b765Szf 
1717a399b765Szf 	if (!(key_info & WPA_KEY_INFO_ACK)) {
1718a399b765Szf 		wpa_printf(MSG_INFO, "WPA: No Ack bit in key_info");
1719a399b765Szf 		return;
1720a399b765Szf 	}
1721a399b765Szf 
1722a399b765Szf 	if (key_info & WPA_KEY_INFO_REQUEST) {
1723a399b765Szf 		wpa_printf(MSG_INFO, "WPA: EAPOL-Key with Request bit - "
1724a399b765Szf 		    "dropped");
1725a399b765Szf 		return;
1726a399b765Szf 	}
1727a399b765Szf 
1728a399b765Szf 	if ((key_info & WPA_KEY_INFO_MIC) &&
1729d62bc4baSyz 	    wpa_supplicant_verify_eapol_key_mic(wpa_s, key, ver, buf,
1730d62bc4baSyz 	    data_len)) {
1731a399b765Szf 		return;
1732d62bc4baSyz 	}
1733a399b765Szf 
1734a399b765Szf 	extra_len = data_len - sizeof (*hdr) - sizeof (*key);
1735a399b765Szf 
1736a399b765Szf 	if (wpa_s->proto == WPA_PROTO_RSN &&
1737a399b765Szf 	    (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) &&
1738a399b765Szf 	    wpa_supplicant_decrypt_key_data(wpa_s, key, ver))
1739a399b765Szf 		return;
1740a399b765Szf 
1741a399b765Szf 	if (key_info & WPA_KEY_INFO_KEY_TYPE) {
1742a399b765Szf 		if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
1743a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: Ignored EAPOL-Key "
1744a399b765Szf 			    "(Pairwise) with non-zero key index");
1745a399b765Szf 			return;
1746a399b765Szf 		}
1747a399b765Szf 		if (key_info & WPA_KEY_INFO_MIC) {
1748a399b765Szf 			/* 3/4 4-Way Handshake */
1749a399b765Szf 			wpa_supplicant_process_3_of_4(wpa_s, src_addr, key,
1750a399b765Szf 			    extra_len, ver);
1751a399b765Szf 		} else {
1752a399b765Szf 			/* 1/4 4-Way Handshake */
1753a399b765Szf 			wpa_supplicant_process_1_of_4(wpa_s, src_addr, key,
1754a399b765Szf 			    ver);
1755a399b765Szf 		}
1756a399b765Szf 	} else {
1757a399b765Szf 		if (key_info & WPA_KEY_INFO_MIC) {
1758a399b765Szf 			/* 1/2 Group Key Handshake */
1759a399b765Szf 			wpa_supplicant_process_1_of_2(wpa_s, src_addr, key,
1760a399b765Szf 			    extra_len, ver);
1761a399b765Szf 		} else {
1762a399b765Szf 			wpa_printf(MSG_WARNING, "WPA: EAPOL-Key (Group) "
1763a399b765Szf 			    "without Mic bit - dropped");
1764a399b765Szf 		}
1765a399b765Szf 	}
1766a399b765Szf }
1767a399b765Szf 
1768a399b765Szf void
wpa_supplicant_rx_eapol(void * ctx,unsigned char * src_addr,unsigned char * buf,size_t len)1769a399b765Szf wpa_supplicant_rx_eapol(void *ctx, unsigned char *src_addr,
1770a399b765Szf     unsigned char *buf, size_t len)
1771a399b765Szf {
1772a399b765Szf 	struct wpa_supplicant *wpa_s = ctx;
1773a399b765Szf 
1774a399b765Szf 	wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
1775a399b765Szf 	wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
1776a399b765Szf 
1777a399b765Szf 	if (wpa_s->eapol_received == 0) {
1778a399b765Szf 		/* Timeout for completing IEEE 802.1X and WPA authentication */
1779a399b765Szf 		wpa_supplicant_req_auth_timeout(
1780a399b765Szf 		    wpa_s, wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ?
1781a399b765Szf 		    70 : 10, 0);
1782a399b765Szf 	}
1783a399b765Szf 	wpa_s->eapol_received++;
1784a399b765Szf 
1785a399b765Szf 	/*
1786a399b765Szf 	 * Source address of the incoming EAPOL frame could be compared to the
1787a399b765Szf 	 * current BSSID. However, it is possible that a centralized
1788a399b765Szf 	 * Authenticator could be using another MAC address than the BSSID of
1789a399b765Szf 	 * an AP, so just allow any address to be used for now. The replies are
1790a399b765Szf 	 * still sent to the current BSSID (if available), though.
1791a399b765Szf 	 */
1792a399b765Szf 	wpa_sm_rx_eapol(wpa_s, src_addr, buf, len);
1793a399b765Szf }
1794