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