1a399b76zf/*
2d62bc4byz * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3a399b76zf * Use is subject to license terms.
4a399b76zf */
5a399b76zf
6a399b76zf/*
7a399b76zf * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
8a399b76zf * Sun elects to license this software under the BSD license.
9a399b76zf * See README for more details.
10a399b76zf */
11a399b76zf
12a399b76zf#include <stdio.h>
13a399b76zf#include <stdlib.h>
14a399b76zf#include <string.h>
15a399b76zf#include <time.h>
16a399b76zf#include <netinet/in.h>
17a399b76zf#include <sys/ethernet.h>
18a399b76zf#include <fcntl.h>
19a399b76zf#include <unistd.h>
20a399b76zf
21a399b76zf#include "wpa_impl.h"
22a399b76zf#include "wpa_enc.h"
23a399b76zf#include "driver.h"
24a399b76zf#include "eloop.h"
25a399b76zf#include "l2_packet.h"
26a399b76zf
27a399b76zfstatic void pmksa_cache_set_expiration(struct wpa_supplicant *);
28a399b76zf
29a399b76zf/*
30a399b76zf * IEEE 802.11i/D3.0
31a399b76zf */
32a399b76zfstatic const int WPA_SELECTOR_LEN = 4;
33fb91fd8zfstatic const uint8_t WPA_OUI_AND_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
34a399b76zfstatic const uint8_t
35a399b76zfWPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] 		= { 0x00, 0x50, 0xf2, 1 };
36a399b76zfstatic const uint8_t
37a399b76zfWPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] 		= { 0x00, 0x50, 0xf2, 2 };
38a399b76zfstatic const uint8_t WPA_CIPHER_SUITE_NONE[]	= { 0x00, 0x50, 0xf2, 0 };
39a399b76zfstatic const uint8_t WPA_CIPHER_SUITE_WEP40[]	= { 0x00, 0x50, 0xf2, 1 };
40a399b76zfstatic const uint8_t WPA_CIPHER_SUITE_TKIP[]	= { 0x00, 0x50, 0xf2, 2 };
41a399b76zfstatic const uint8_t WPA_CIPHER_SUITE_CCMP[]	= { 0x00, 0x50, 0xf2, 4 };
42a399b76zfstatic const uint8_t WPA_CIPHER_SUITE_WEP104[]	= { 0x00, 0x50, 0xf2, 5 };
43a399b76zf
44a399b76zf/*
45a399b76zf * WPA IE version 1
46a399b76zf * 00-50-f2:1 (OUI:OUI type)
47a399b76zf * 0x01 0x00 (version; little endian)
48a399b76zf * (all following fields are optional:)
49a399b76zf * Group Suite Selector (4 octets) (default: TKIP)
50a399b76zf * Pairwise Suite Count (2 octets, little endian) (default: 1)
51a399b76zf * Pairwise Suite List (4 * n octets) (default: TKIP)
52a399b76zf * Authenticated Key Management Suite Count (2 octets, little endian)
53a399b76zf * (default: 1)
54a399b76zf * Authenticated Key Management Suite List (4 * n octets)
55a399b76zf * (default: unspec 802.1x)
56a399b76zf * WPA Capabilities (2 octets, little endian) (default: 0)
57a399b76zf */
58a399b76zf#pragma pack(1)
59a399b76zfstruct wpa_ie_hdr {
60a399b76zf	uint8_t		elem_id;
61a399b76zf	uint8_t		len;
62a399b76zf	uint8_t		oui[3];
63a399b76zf	uint8_t		oui_type;
64a399b76zf	uint16_t	version;
65a399b76zf};
66a399b76zf#pragma pack()
67a399b76zf
68a399b76zf/*
69a399b76zf * IEEE 802.11i/D9.0
70a399b76zf */
71a399b76zfstatic const int RSN_SELECTOR_LEN = 4;
72a399b76zfstatic const uint16_t RSN_VERSION = 1;
73a399b76zfstatic const uint8_t
74a399b76zfRSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]		= { 0x00, 0x0f, 0xac, 1 };
75a399b76zfstatic const uint8_t
76a399b76zfRSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]		= { 0x00, 0x0f, 0xac, 2 };
77a399b76zfstatic const uint8_t RSN_CIPHER_SUITE_NONE[]	= { 0x00, 0x0f, 0xac, 0 };
78a399b76zfstatic const uint8_t RSN_CIPHER_SUITE_WEP40[]	= { 0x00, 0x0f, 0xac, 1 };
79a399b76zfstatic const uint8_t RSN_CIPHER_SUITE_TKIP[]	= { 0x00, 0x0f, 0xac, 2 };
80a399b76zfstatic const uint8_t RSN_CIPHER_SUITE_CCMP[]	= { 0x00, 0x0f, 0xac, 4 };
81a399b76zfstatic const uint8_t RSN_CIPHER_SUITE_WEP104[]	= { 0x00, 0x0f, 0xac, 5 };
82a399b76zf
83a399b76zf/*
84a399b76zf * EAPOL-Key Key Data Encapsulation
85a399b76zf * GroupKey and STAKey require encryption, otherwise, encryption is optional.
86a399b76zf */
87a399b76zfstatic const uint8_t RSN_KEY_DATA_GROUPKEY[]	= { 0x00, 0x0f, 0xac, 1 };
88a399b76zfstatic const uint8_t RSN_KEY_DATA_PMKID[]	= { 0x00, 0x0f, 0xac, 4 };
89a399b76zf
90a399b76zf/*
91a399b76zf * 1/4: PMKID
92a399b76zf * 2/4: RSN IE
93a399b76zf * 3/4: one or two RSN IEs + GTK IE (encrypted)
94a399b76zf * 4/4: empty
95a399b76zf * 1/2: GTK IE (encrypted)
96a399b76zf * 2/2: empty
97a399b76zf */
98a399b76zf
99a399b76zf/*
100a399b76zf * RSN IE version 1
101a399b76zf * 0x01 0x00 (version; little endian)
102a399b76zf * (all following fields are optional:)
103a399b76zf * Group Suite Selector (4 octets) (default: CCMP)
104a399b76zf * Pairwise Suite Count (2 octets, little endian) (default: 1)
105a399b76zf * Pairwise Suite List (4 * n octets) (default: CCMP)
106a399b76zf * Authenticated Key Management Suite Count (2 octets, little endian)
107a399b76zf *    (default: 1)
108a399b76zf * Authenticated Key Management Suite List (4 * n octets)
109a399b76zf *    (default: unspec 802.1x)
110a399b76zf * RSN Capabilities (2 octets, little endian) (default: 0)
111a399b76zf * PMKID Count (2 octets) (default: 0)
112a399b76zf * PMKID List (16 * n octets)
113a399b76zf */
114a399b76zf#pragma pack(1)
115a399b76zfstruct rsn_ie_hdr {
116a399b76zf	uint8_t		elem_id; /* WLAN_EID_RSN */
117a399b76zf	uint8_t		len;
118a399b76zf	uint16_t	version;
119a399b76zf};
120a399b76zf#pragma pack()
121a399b76zf
122a399b76zfstatic int
123a399b76zfrandom_get_pseudo_bytes(uint8_t *ptr, size_t len)
124a399b76zf{
125a399b76zf	int fd;
126a399b76zf	size_t resid = len;
127a399b76zf	size_t bytes;
128a399b76zf
129a399b76zf	fd = open("/dev/urandom", O_RDONLY);
130a399b76zf	if (fd == -1) {
131a399b76zf		wpa_printf(MSG_ERROR, "Could not open /dev/urandom.\n");
132a399b76zf		return (-1);
133a399b76zf	}
134a399b76zf
135a399b76zf	while (resid != 0) {
136a399b76zf		bytes = read(fd, ptr, resid);
137a399b76zf		ptr += bytes;
138a399b76zf		resid -= bytes;
139a399b76zf	}
140a399b76zf
141a399b76zf	(void) close(fd);
142a399b76zf
143a399b76zf	return (0);
144a399b76zf}
145a399b76zf
146a399b76zfstatic void
147a399b76zfinc_byte_array(uint8_t *counter, size_t len)
148a399b76zf{
149a399b76zf	int pos = len - 1;
150a399b76zf	while (pos >= 0) {
151a399b76zf		counter[pos]++;
152a399b76zf		if (counter[pos] != 0)
153a399b76zf			break;
154a399b76zf		pos--;
155a399b76zf	}
156a399b76zf}
157a399b76zf
158a399b76zfstatic int
159a399b76zfwpa_selector_to_bitfield(uint8_t *s)
160a399b76zf{
161a399b76zf	if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)
162a399b76zf		return (WPA_CIPHER_NONE);
163a399b76zf	if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0)
164a399b76zf		return (WPA_CIPHER_WEP40);
165a399b76zf	if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0)
166a399b76zf		return (WPA_CIPHER_TKIP);
167a399b76zf	if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0)
168a399b76zf		return (WPA_CIPHER_CCMP);
169a399b76zf	if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0)
170a399b76zf		return (WPA_CIPHER_WEP104);
171a399b76zf	return (0);
172a399b76zf}
173a399b76zf
174a399b76zfstatic int
175a399b76zfwpa_key_mgmt_to_bitfield(uint8_t *s)
176a399b76zf{
177a399b76zf	if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0)
178a399b76zf		return (WPA_KEY_MGMT_IEEE8021X);
179a399b76zf	if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) ==
180a399b76zf	    0)
181a399b76zf		return (WPA_KEY_MGMT_PSK);
182a399b76zf	return (0);
183a399b76zf}
184a399b76zf
185a399b76zfstatic int
186a399b76zfrsn_selector_to_bitfield(uint8_t *s)
187a399b76zf{
188a399b76zf	if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0)
189a399b76zf		return (WPA_CIPHER_NONE);
190a399b76zf	if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0)
191a399b76zf		return (WPA_CIPHER_WEP40);
192a399b76zf	if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0)
193a399b76zf		return (WPA_CIPHER_TKIP);
194a399b76zf	if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0)
195a399b76zf		return (WPA_CIPHER_CCMP);
196a399b76zf	if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0)
197a399b76zf		return (WPA_CIPHER_WEP104);
198a399b76zf	return (0);
199a399b76zf}
200a399b76zf
201a399b76zfstatic int
202a399b76zfrsn_key_mgmt_to_bitfield(uint8_t *s)
203a399b76zf{
204a399b76zf	if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0)
205a399b76zf		return (WPA_KEY_MGMT_IEEE8021X);
206a399b76zf	if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) ==
207a399b76zf	    0)
208a399b76zf		return (WPA_KEY_MGMT_PSK);
209a399b76zf	return (0);
210a399b76zf}
211a399b76zf
212a399b76zfstatic void
213a399b76zfpmksa_cache_free_entry(struct wpa_supplicant *wpa_s,
214a399b76zf	struct rsn_pmksa_cache *entry)
215a399b76zf{
216a399b76zf	wpa_s->pmksa_count--;
217a399b76zf	if (wpa_s->cur_pmksa == entry) {
218a399b76zf		wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA entry");
219a399b76zf		wpa_s->cur_pmksa = NULL;
220a399b76zf	}
221a399b76zf	free(entry);
222a399b76zf}
223a399b76zf
224a399b76zf/* ARGSUSED */
225a399b76zfstatic void
226a399b76zfpmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
227a399b76zf{
228a399b76zf	struct wpa_supplicant *wpa_s = eloop_ctx;
229a399b76zf	time_t now;
230a399b76zf
231a399b76zf	(void) time(&now);
232a399b76zf	while (wpa_s->pmksa && wpa_s->pmksa->expiration <= now) {
233a399b76zf		struct rsn_pmksa_cache *entry = wpa_s->pmksa;
234a399b76zf		wpa_s->pmksa = entry->next;
235a399b76zf		wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
236a399b76zf		    MACSTR, MAC2STR(entry->aa));
237a399b76zf		pmksa_cache_free_entry(wpa_s, entry);
238a399b76zf	}
239a399b76zf
240a399b76zf	pmksa_cache_set_expiration(wpa_s);
241a399b76zf}
242a399b76zf
243a399b76zfstatic void
244a399b76zfpmksa_cache_set_expiration(struct wpa_supplicant *wpa_s)
245a399b76zf{
246a399b76zf	int sec;
247a399b76zf	eloop_cancel_timeout(pmksa_cache_expire, wpa_s, NULL);
248a399b76zf	if (wpa_s->pmksa == NULL)
249a399b76zf		return;
250a399b76zf	sec = wpa_s->pmksa->expiration - time(NULL);
251a399b76zf	if (sec < 0)
252a399b76zf		sec = 0;
253a399b76zf	(void) eloop_register_timeout(sec + 1, 0, pmksa_cache_expire,
254a399b76zf	    wpa_s, NULL);
255a399b76zf}
256a399b76zf
257a399b76zfvoid
258a399b76zfpmksa_cache_free(struct wpa_supplicant *wpa_s)
259a399b76zf{
260a399b76zf	struct rsn_pmksa_cache *entry, *prev;
261a399b76zf
262a399b76zf	entry = wpa_s->pmksa;
263a399b76zf	wpa_s->pmksa = NULL;
264a399b76zf	while (entry) {
265a399b76zf		prev = entry;
266a399b76zf		entry = entry->next;
267a399b76zf		free(prev);
268a399b76zf	}
269a399b76zf	pmksa_cache_set_expiration(wpa_s);
270a399b76zf	wpa_s->cur_pmksa = NULL;
271a399b76zf}
272a399b76zf
273a399b76zfstruct rsn_pmksa_cache *
274a399b76zfpmksa_cache_get(struct wpa_supplicant *wpa_s,
275a399b76zf		uint8_t *aa, uint8_t *pmkid)
276a399b76zf{
277a399b76zf	struct rsn_pmksa_cache *entry = wpa_s->pmksa;
278a399b76zf	while (entry) {
279a399b76zf		if ((aa == NULL ||
280a399b76zf		    memcmp(entry->aa, aa, IEEE80211_ADDR_LEN) == 0) &&
281a399b76zf		    (pmkid == NULL ||
282a399b76zf		    memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
283a399b76zf			return (entry);
284a399b76zf		entry = entry->next;
285a399b76zf	}
286a399b76zf	return (NULL);
287a399b76zf}
288a399b76zf
289a399b76zfint
290a399b76zfpmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf, size_t len)
291a399b76zf{
292a399b76zf	int i, j;
293a399b76zf	char *pos = buf;
294a399b76zf	struct rsn_pmksa_cache *entry;
295a399b76zf	time_t now;
296a399b76zf
297a399b76zf	(void) time(&now);
298a399b76zf	pos += snprintf(pos, buf + len - pos,
299a399b76zf	    "Index / AA / PMKID / expiration (in seconds)\n");
300a399b76zf	i = 0;
301a399b76zf	entry = wpa_s->pmksa;
302a399b76zf	while (entry) {
303a399b76zf		i++;
304a399b76zf		pos += snprintf(pos, buf + len - pos, "%d " MACSTR " ",
305a399b76zf		    i, MAC2STR(entry->aa));
306a399b76zf		for (j = 0; j < PMKID_LEN; j++)
307a399b76zf			pos += snprintf(pos, buf + len - pos, "%02x",
308a399b76zf			    entry->pmkid[j]);
309a399b76zf		pos += snprintf(pos, buf + len - pos, " %d\n",
310a399b76zf		    (int)(entry->expiration - now));
311a399b76zf		entry = entry->next;
312a399b76zf	}
313a399b76zf	return (pos - buf);
314a399b76zf}
315a399b76zf
316a399b76zfvoid
317a399b76zfpmksa_candidate_free(struct wpa_supplicant *wpa_s)
318a399b76zf{
319a399b76zf	struct rsn_pmksa_candidate *entry, *prev;
320a399b76zf
321a399b76zf	entry = wpa_s->pmksa_candidates;
322a399b76zf	wpa_s->pmksa_candidates = NULL;
323a399b76zf	while (entry) {
324a399b76zf		prev = entry;
325a399b76zf		entry = entry->next;
326a399b76zf		free(prev);
327a399b76zf	}
328a399b76zf}
329a399b76zf
330a399b76zf/* ARGSUSED */
331a399b76zfstatic int
332a399b76zfwpa_parse_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
333a399b76zf    size_t wpa_ie_len, struct wpa_ie_data *data)
334a399b76zf{
335a399b76zf	struct wpa_ie_hdr *hdr;
336a399b76zf	uint8_t *pos;
337a399b76zf	int left;
338a399b76zf	int i, count;
339a399b76zf
340a399b76zf	data->proto = WPA_PROTO_WPA;
341a399b76zf	data->pairwise_cipher = WPA_CIPHER_TKIP;
342a399b76zf	data->group_cipher = WPA_CIPHER_TKIP;
343a399b76zf	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
344a399b76zf	data->capabilities = 0;
345a399b76zf
346a399b76zf	if (wpa_ie_len == 0) {
347a399b76zf		/* No WPA IE - fail silently */
348a399b76zf		return (-1);
349a399b76zf	}
350a399b76zf
351a399b76zf	if (wpa_ie_len < sizeof (struct wpa_ie_hdr)) {
352a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
353a399b76zf		    "wpa_parse_wpa_ie_wpa", wpa_ie_len);
354a399b76zf		return (-1);
355a399b76zf	}
356a399b76zf
357a399b76zf	hdr = (struct wpa_ie_hdr *)wpa_ie;
358a399b76zf
359a399b76zf	if (hdr->elem_id != GENERIC_INFO_ELEM ||
360a399b76zf	    hdr->len != wpa_ie_len - 2 ||
361fb91fd8zf	    memcmp(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN) != 0 ||
362a399b76zf	    LE_16(hdr->version) != WPA_VERSION) {
363a399b76zf		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
364a399b76zf		    "wpa_parse_wpa_ie_wpa");
365a399b76zf		return (-1);
366a399b76zf	}
367a399b76zf
368a399b76zf	pos = (uint8_t *)(hdr + 1);
369a399b76zf	left = wpa_ie_len - sizeof (*hdr);
370a399b76zf
371a399b76zf	if (left >= WPA_SELECTOR_LEN) {
372a399b76zf		data->group_cipher = wpa_selector_to_bitfield(pos);
373a399b76zf		pos += WPA_SELECTOR_LEN;
374a399b76zf		left -= WPA_SELECTOR_LEN;
375a399b76zf	} else if (left > 0) {
376a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
377a399b76zf		    "wpa_parse_wpa_ie_wpa", left);
378a399b76zf		return (-1);
379a399b76zf	}
380a399b76zf
381a399b76zf	if (left >= 2) {
382a399b76zf		data->pairwise_cipher = 0;
383a399b76zf		count = pos[0] | (pos[1] << 8);
384a399b76zf		pos += 2;
385a399b76zf		left -= 2;
386a399b76zf		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
387a399b76zf			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
388a399b76zf			    "count %u left %u",
389a399b76zf			    "wpa_parse_wpa_ie_wpa", count, left);
390a399b76zf			return (-1);
391a399b76zf		}
392a399b76zf		for (i = 0; i < count; i++) {
393a399b76zf			data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
394a399b76zf			pos += WPA_SELECTOR_LEN;
395a399b76zf			left -= WPA_SELECTOR_LEN;
396a399b76zf		}
397a399b76zf	} else if (left == 1) {
398a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
399a399b76zf		    "wpa_parse_wpa_ie_wpa");
400a399b76zf		return (-1);
401a399b76zf	}
402a399b76zf
403a399b76zf	if (left >= 2) {
404a399b76zf		data->key_mgmt = 0;
405a399b76zf		count = pos[0] | (pos[1] << 8);
406a399b76zf		pos += 2;
407a399b76zf		left -= 2;
408a399b76zf		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
409a399b76zf			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
410a399b76zf			    "count %u left %u",
411a399b76zf			    "wpa_parse_wpa_ie_wpa", count, left);
412a399b76zf			return (-1);
413a399b76zf		}
414a399b76zf		for (i = 0; i < count; i++) {
415a399b76zf			data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
416a399b76zf			pos += WPA_SELECTOR_LEN;
417a399b76zf			left -= WPA_SELECTOR_LEN;
418a399b76zf		}
419a399b76zf	} else if (left == 1) {
420a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
421a399b76zf		    "wpa_parse_wpa_ie_wpa");
422a399b76zf		return (-1);
423a399b76zf	}
424a399b76zf
425a399b76zf	if (left >= 2) {
426a399b76zf		data->capabilities = pos[0] | (pos[1] << 8);
427a399b76zf		pos += 2;
428a399b76zf		left -= 2;
429a399b76zf	}
430a399b76zf
431a399b76zf	if (left > 0) {
432a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes",
433a399b76zf		    "wpa_parse_wpa_ie_wpa", left);
434a399b76zf		return (-1);
435a399b76zf	}
436a399b76zf
437a399b76zf	return (0);
438a399b76zf}
439a399b76zf
440a399b76zf/* ARGSUSED */
441a399b76zfstatic int
442a399b76zfwpa_parse_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie,
443a399b76zf    size_t rsn_ie_len, struct wpa_ie_data *data)
444a399b76zf{
445a399b76zf	struct rsn_ie_hdr *hdr;
446a399b76zf	uint8_t *pos;
447a399b76zf	int left;
448a399b76zf	int i, count;
449a399b76zf
450a399b76zf	data->proto = WPA_PROTO_RSN;
451a399b76zf	data->pairwise_cipher = WPA_CIPHER_CCMP;
452a399b76zf	data->group_cipher = WPA_CIPHER_CCMP;
453a399b76zf	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
454a399b76zf	data->capabilities = 0;
455a399b76zf
456a399b76zf	if (rsn_ie_len == 0) {
457a399b76zf		/* No RSN IE - fail silently */
458a399b76zf		return (-1);
459a399b76zf	}
460a399b76zf
461a399b76zf	if (rsn_ie_len < sizeof (struct rsn_ie_hdr)) {
462a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
463a399b76zf		    "wpa_parse_wpa_ie_rsn", rsn_ie_len);
464a399b76zf		return (-1);
465a399b76zf	}
466a399b76zf
467a399b76zf	hdr = (struct rsn_ie_hdr *)rsn_ie;
468a399b76zf
469a399b76zf	if (hdr->elem_id != RSN_INFO_ELEM ||
470a399b76zf	    hdr->len != rsn_ie_len - 2 ||
471a399b76zf	    LE_16(hdr->version) != RSN_VERSION) {
472a399b76zf		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
473a399b76zf		    "wpa_parse_wpa_ie_rsn");
474a399b76zf		return (-1);
475a399b76zf	}
476a399b76zf
477a399b76zf	pos = (uint8_t *)(hdr + 1);
478a399b76zf	left = rsn_ie_len - sizeof (*hdr);
479a399b76zf
480a399b76zf	if (left >= RSN_SELECTOR_LEN) {
481a399b76zf		data->group_cipher = rsn_selector_to_bitfield(pos);
482a399b76zf		pos += RSN_SELECTOR_LEN;
483a399b76zf		left -= RSN_SELECTOR_LEN;
484a399b76zf	} else if (left > 0) {
485a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
486a399b76zf		    "wpa_parse_wpa_ie_rsn", left);
487a399b76zf		return (-1);
488a399b76zf	}
489a399b76zf
490a399b76zf	if (left >= 2) {
491a399b76zf		data->pairwise_cipher = 0;
492a399b76zf		count = pos[0] | (pos[1] << 8);
493a399b76zf		pos += 2;
494a399b76zf		left -= 2;
495a399b76zf		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
496a399b76zf			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
497a399b76zf			    "count %u left %u",
498a399b76zf			    "wpa_parse_wpa_ie_rsn", count, left);
499a399b76zf			return (-1);
500a399b76zf		}
501a399b76zf		for (i = 0; i < count; i++) {
502a399b76zf			data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
503a399b76zf			pos += RSN_SELECTOR_LEN;
504a399b76zf			left -= RSN_SELECTOR_LEN;
505a399b76zf		}
506a399b76zf	} else if (left == 1) {
507a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
508a399b76zf		    "wpa_parse_wpa_ie_rsn");
509a399b76zf		return (-1);
510a399b76zf	}
511a399b76zf
512a399b76zf	if (left >= 2) {
513a399b76zf		data->key_mgmt = 0;
514a399b76zf		count = pos[0] | (pos[1] << 8);
515a399b76zf		pos += 2;
516a399b76zf		left -= 2;
517a399b76zf		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
518a399b76zf			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
519a399b76zf			    "count %u left %u",
520a399b76zf			    "wpa_parse_wpa_ie_rsn", count, left);
521a399b76zf			return (-1);
522a399b76zf		}
523a399b76zf		for (i = 0; i < count; i++) {
524a399b76zf			data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
525a399b76zf			pos += RSN_SELECTOR_LEN;
526a399b76zf			left -= RSN_SELECTOR_LEN;
527a399b76zf		}
528a399b76zf	} else if (left == 1) {
529a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
530a399b76zf		    "wpa_parse_wpa_ie_rsn");
531a399b76zf		return (-1);
532a399b76zf	}
533a399b76zf
534a399b76zf	if (left >= 2) {
535a399b76zf		data->capabilities = pos[0] | (pos[1] << 8);
536a399b76zf		pos += 2;
537a399b76zf		left -= 2;
538a399b76zf	}
539a399b76zf
540a399b76zf	if (left > 0) {
541a399b76zf		/*
542a399b76zf		 * RSN IE could include PMKID data, but Authenticator should
543a399b76zf		 * never include it, so no need to parse it in the Supplicant.
544a399b76zf		 */
545a399b76zf		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
546a399b76zf		    "wpa_parse_wpa_ie_rsn", left);
547a399b76zf	}
548a399b76zf
549a399b76zf	return (0);
550a399b76zf}
551a399b76zf
552a399b76zfint
553a399b76zfwpa_parse_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
554a399b76zf    size_t wpa_ie_len, struct wpa_ie_data *data)
555a399b76zf{
556a399b76zf	if (wpa_ie_len >= 1 && wpa_ie[0] == RSN_INFO_ELEM)
557a399b76zf		return (wpa_parse_wpa_ie_rsn(wpa_s, wpa_ie, wpa_ie_len, data));
558a399b76zf	else
559a399b76zf		return (wpa_parse_wpa_ie_wpa(wpa_s, wpa_ie, wpa_ie_len, data));
560a399b76zf}
561a399b76zf
562a399b76zfstatic int
563a399b76zfwpa_gen_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
564a399b76zf{
565a399b76zf	uint8_t *pos;
566a399b76zf	struct wpa_ie_hdr *hdr;
567a399b76zf
568a399b76zf	hdr = (struct wpa_ie_hdr *)wpa_ie;
569a399b76zf	hdr->elem_id = GENERIC_INFO_ELEM;
570fb91fd8zf	(void) memcpy(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN);
571a399b76zf	hdr->version = LE_16(WPA_VERSION);
572a399b76zf	pos = (uint8_t *)(hdr + 1);
573a399b76zf
574a399b76zf	if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
575a399b76zf		(void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
576a399b76zf	} else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
577a399b76zf		(void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
578a399b76zf	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
579a399b76zf		(void) memcpy(pos, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN);
580a399b76zf	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
581a399b76zf		(void) memcpy(pos, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN);
582a399b76zf	} else {
583a399b76zf		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
584a399b76zf		    wpa_s->group_cipher);
585a399b76zf		return (-1);
586a399b76zf	}
587a399b76zf	pos += WPA_SELECTOR_LEN;
588a399b76zf
589a399b76zf	*pos++ = 1;
590a399b76zf	*pos++ = 0;
591a399b76zf	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
592a399b76zf		(void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
593a399b76zf	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
594a399b76zf		(void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
595a399b76zf	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
596a399b76zf		(void) memcpy(pos, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN);
597a399b76zf	} else {
598a399b76zf		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
599a399b76zf		    wpa_s->pairwise_cipher);
600a399b76zf		return (-1);
601a399b76zf	}
602a399b76zf	pos += WPA_SELECTOR_LEN;
603a399b76zf
604a399b76zf	*pos++ = 1;
605a399b76zf	*pos++ = 0;
606a399b76zf	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
607a399b76zf		(void) memcpy(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X,
608a399b76zf		    WPA_SELECTOR_LEN);
609a399b76zf	} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
610a399b76zf		(void) memcpy(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X,
611a399b76zf		    WPA_SELECTOR_LEN);
612a399b76zf	} else {
613a399b76zf		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
614a399b76zf		    wpa_s->key_mgmt);
615a399b76zf		return (-1);
616a399b76zf	}
617a399b76zf	pos += WPA_SELECTOR_LEN;
618a399b76zf
619a399b76zf	/*
620a399b76zf	 * WPA Capabilities; use defaults, so no need to include it
621a399b76zf	 */
622a399b76zf	hdr->len = (pos - wpa_ie) - 2;
623a399b76zf
624a399b76zf	return (pos - wpa_ie);
625a399b76zf}
626a399b76zf
627a399b76zfstatic int
628a399b76zfwpa_gen_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie)
629a399b76zf{
630a399b76zf	uint8_t *pos;
631a399b76zf	struct rsn_ie_hdr *hdr;
632a399b76zf
633a399b76zf	hdr = (struct rsn_ie_hdr *)rsn_ie;
634a399b76zf	hdr->elem_id = RSN_INFO_ELEM;
635a399b76zf	hdr->version = LE_16(RSN_VERSION);
636a399b76zf	pos = (uint8_t *)(hdr + 1);
637a399b76zf
638a399b76zf	if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
639a399b76zf		(void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
640a399b76zf	} else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
641a399b76zf		(void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
642a399b76zf	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
643a399b76zf		(void) memcpy(pos, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN);
644a399b76zf	} else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
645a399b76zf		(void) memcpy(pos, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN);
646a399b76zf	} else {
647a399b76zf		wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
648a399b76zf		    wpa_s->group_cipher);
649a399b76zf		return (-1);
650a399b76zf	}
651a399b76zf	pos += RSN_SELECTOR_LEN;
652a399b76zf
653a399b76zf	*pos++ = 1;
654a399b76zf	*pos++ = 0;
655a399b76zf	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
656a399b76zf		(void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
657a399b76zf	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
658a399b76zf		(void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
659a399b76zf	} else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
660a399b76zf		(void) memcpy(pos, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN);
661a399b76zf	} else {
662a399b76zf		wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
663a399b76zf		    wpa_s->pairwise_cipher);
664a399b76zf		return (-1);
665a399b76zf	}
666a399b76zf	pos += RSN_SELECTOR_LEN;
667a399b76zf
668a399b76zf	*pos++ = 1;
669a399b76zf	*pos++ = 0;
670a399b76zf	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
671a399b76zf		(void) memcpy(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X,
672a399b76zf		    RSN_SELECTOR_LEN);
673a399b76zf	} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
674a399b76zf		(void) memcpy(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X,
675a399b76zf		    RSN_SELECTOR_LEN);
676a399b76zf	} else {
677a399b76zf		wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
678a399b76zf		    wpa_s->key_mgmt);
679a399b76zf		return (-1);
680a399b76zf	}
681a399b76zf	pos += RSN_SELECTOR_LEN;
682a399b76zf
683a399b76zf	/* RSN Capabilities */
684a399b76zf	*pos++ = 0;
685a399b76zf	*pos++ = 0;
686a399b76zf
687a399b76zf	if (wpa_s->cur_pmksa) {
688a399b76zf		/* PMKID Count (2 octets, little endian) */
689a399b76zf		*pos++ = 1;
690a399b76zf		*pos++ = 0;
691a399b76zf		/* PMKID */
692a399b76zf		(void) memcpy(pos, wpa_s->cur_pmksa->pmkid, PMKID_LEN);
693a399b76zf		pos += PMKID_LEN;
694a399b76zf	}
695a399b76zf
696a399b76zf	hdr->len = (pos - rsn_ie) - 2;
697a399b76zf
698a399b76zf	return (pos - rsn_ie);
699a399b76zf}
700a399b76zf
701a399b76zfint
702a399b76zfwpa_gen_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
703a399b76zf{
704a399b76zf	if (wpa_s->proto == WPA_PROTO_RSN)
705a399b76zf		return (wpa_gen_wpa_ie_rsn(wpa_s, wpa_ie));
706a399b76zf	else
707a399b76zf		return (wpa_gen_wpa_ie_wpa(wpa_s, wpa_ie));
708a399b76zf}
709a399b76zf
710a399b76zfstatic void
711a399b76zfwpa_pmk_to_ptk(uint8_t *pmk, uint8_t *addr1, uint8_t *addr2,
712a399b76zf    uint8_t *nonce1, uint8_t *nonce2, uint8_t *ptk, size_t ptk_len)
713a399b76zf{
714a399b76zf	uint8_t data[2 * IEEE80211_ADDR_LEN + 2 * WPA_PMK_LEN];
715a399b76zf
716a399b76zf	/*
717a399b76zf	 * PTK = PRF-X(PMK, "Pairwise key expansion",
718a399b76zf	 * 	Min(AA, SA) || Max(AA, SA) ||
719a399b76zf	 * 	Min(ANonce, SNonce) || Max(ANonce, SNonce))
720a399b76zf	 */
721a399b76zf
722a399b76zf	if (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) < 0) {
723a399b76zf		(void) memcpy(data, addr1, IEEE80211_ADDR_LEN);
724a399b76zf		(void) memcpy(data + IEEE80211_ADDR_LEN, addr2,
725a399b76zf		    IEEE80211_ADDR_LEN);
726a399b76zf	} else {
727a399b76zf		(void) memcpy(data, addr2, IEEE80211_ADDR_LEN);
728a399b76zf		(void) memcpy(data + IEEE80211_ADDR_LEN, addr1,
729a399b76zf		    IEEE80211_ADDR_LEN);
730a399b76zf	}
731a399b76zf
732a399b76zf	if (memcmp(nonce1, nonce2, WPA_PMK_LEN) < 0) {
733a399b76zf		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce1,
734a399b76zf		    WPA_PMK_LEN);
735a399b76zf		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
736a399b76zf		    nonce2, WPA_PMK_LEN);
737a399b76zf	} else {
738a399b76zf		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce2,
739a399b76zf		    WPA_PMK_LEN);
740a399b76zf		(void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
741a399b76zf		    nonce1, WPA_PMK_LEN);
742a399b76zf	}
743a399b76zf
744a399b76zf	sha1_prf(pmk, WPA_PMK_LEN, "Pairwise key expansion", data,
745a399b76zf	    sizeof (data), ptk, ptk_len);
746a399b76zf
747a399b76zf	wpa_hexdump(MSG_DEBUG, "WPA: PMK", pmk, WPA_PMK_LEN);
748a399b76zf	wpa_hexdump(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
749a399b76zf}
750a399b76zf
751a399b76zfstruct wpa_ssid *
752a399b76zfwpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
753a399b76zf{
754a399b76zf	struct wpa_ssid *entry;
755a399b76zf	uint8_t ssid[MAX_ESSID_LENGTH];
756a399b76zf	int ssid_len;
757a399b76zf	uint8_t bssid[IEEE80211_ADDR_LEN];
758a399b76zf
759a399b76zf	(void) memset(ssid, 0, MAX_ESSID_LENGTH);
7604ac67f0Anurag S. Maskey	ssid_len = wpa_s->driver->get_ssid(wpa_s->handle, wpa_s->linkid,
7614ac67f0Anurag S. Maskey	    (char *)ssid);
762a399b76zf	if (ssid_len < 0) {
763a399b76zf		wpa_printf(MSG_WARNING, "Could not read SSID from driver.");
764a399b76zf		return (NULL);
765a399b76zf	}
766a399b76zf
7674ac67f0Anurag S. Maskey	if (wpa_s->driver->get_bssid(wpa_s->handle, wpa_s->linkid,
7684ac67f0Anurag S. Maskey	    (char *)bssid) < 0) {
769a399b76zf		wpa_printf(MSG_WARNING, "Could not read BSSID from driver.");
770a399b76zf		return (NULL);
771a399b76zf	}
772a399b76zf
773a399b76zf	entry = wpa_s->conf->ssid;
774a399b76zf	wpa_printf(MSG_DEBUG, "entry len=%d ssid=%s,"
775a399b76zf	    " driver len=%d ssid=%s",
776a399b76zf	    entry->ssid_len, entry->ssid, ssid_len, ssid);
777a399b76zf
778a399b76zf	if (ssid_len == entry->ssid_len &&
779a399b76zf	    memcmp(ssid, entry->ssid, ssid_len) == 0 &&
780a399b76zf	    (!entry->bssid_set ||
781a399b76zf	    memcmp(bssid, entry->bssid, IEEE80211_ADDR_LEN) == 0))
782a399b76zf		return (entry);
783a399b76zf
784a399b76zf	return (NULL);
785a399b76zf}
786a399b76zf
787a399b76zfstatic void
788a399b76zfwpa_eapol_key_mic(uint8_t *key, int ver, uint8_t *buf, size_t len, uint8_t *mic)
789a399b76zf{
790a399b76zf	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
791a399b76zf		hmac_md5(key, 16, buf, len, mic);
792a399b76zf	} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
793a399b76zf		uint8_t hash[SHA1_MAC_LEN];
794a399b76zf		hmac_sha1(key, 16, buf, len, hash);
795a399b76zf		(void) memcpy(mic, hash, MD5_MAC_LEN);
796a399b76zf	}
797a399b76zf}
798a399b76zf
799a399b76zfvoid
800a399b76zfwpa_supplicant_key_request(struct wpa_supplicant *wpa_s,
801a399b76zf	int error, int pairwise)
802a399b76zf{
803a399b76zf	int rlen;
804a399b76zf	struct ieee802_1x_hdr *hdr;
805a399b76zf	struct wpa_eapol_key *reply;
806a399b76zf	unsigned char *rbuf;
807a399b76zf	struct l2_ethhdr *ethhdr;
808a399b76zf	int key_info, ver;
809a399b76zf	uint8_t bssid[IEEE80211_ADDR_LEN];
810a399b76zf
811a399b76zf	if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP)
812a399b76zf		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
813a399b76zf	else
814a399b76zf		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
815a399b76zf
8164ac67f0Anurag S. Maskey	if (wpa_s->driver->get_bssid(wpa_s->handle, wpa_s->linkid,
8174ac67f0Anurag S. Maskey	    (char *)bssid) < 0) {
818a399b76zf		wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
819a399b76zf		    "request");
820a399b76zf		return;
821a399b76zf	}
822a399b76zf
823a399b76zf	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
824a399b76zf	rbuf = malloc(rlen);
825a399b76zf	if (rbuf == NULL)
826a399b76zf		return;
827a399b76zf
828a399b76zf	(void) memset(rbuf, 0, rlen);
829a399b76zf	ethhdr = (struct l2_ethhdr *)rbuf;
830a399b76zf	(void) memcpy(ethhdr->h_dest, bssid, IEEE80211_ADDR_LEN);
831a399b76zf	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
832a399b76zf	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
833a399b76zf
834a399b76zf	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
835a399b76zf	hdr->version = wpa_s->conf->eapol_version;
836a399b76zf	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
837a399b76zf	hdr->length = htons(sizeof (*reply));
838a399b76zf
839a399b76zf	reply = (struct wpa_eapol_key *)(hdr + 1);
840a399b76zf	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
841d62bc4byz	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
842a399b76zf	key_info = WPA_KEY_INFO_REQUEST | ver;
843a399b76zf	if (wpa_s->ptk_set)
844a399b76zf		key_info |= WPA_KEY_INFO_MIC;
845a399b76zf	if (error)
846a399b76zf		key_info |= WPA_KEY_INFO_ERROR;
847a399b76zf	if (pairwise)
848a399b76zf		key_info |= WPA_KEY_INFO_KEY_TYPE;
849a399b76zf	reply->key_info = BE_16(key_info);
850a399b76zf	reply->key_length = 0;
851a399b76zf	(void) memcpy(reply->replay_counter, wpa_s->request_counter,
852d62bc4byz	    WPA_REPLAY_COUNTER_LEN);
853a399b76zf	inc_byte_array(wpa_s->request_counter, WPA_REPLAY_COUNTER_LEN);
854a399b76zf
855a399b76zf	reply->key_data_length = BE_16(0);
856a399b76zf
857a399b76zf	if (key_info & WPA_KEY_INFO_MIC) {
858a399b76zf		wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
859a399b76zf		    rlen - sizeof (*ethhdr), reply->key_mic);
860a399b76zf	}
861a399b76zf
862a399b76zf	wpa_printf(MSG_INFO, "WPA: Sending EAPOL-Key Request (error=%d "
863a399b76zf	    "pairwise=%d ptk_set=%d len=%d)",
864a399b76zf	    error, pairwise, wpa_s->ptk_set, rlen);
865a399b76zf	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key Request", rbuf, rlen);
866a399b76zf	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
867a399b76zf	free(rbuf);
868a399b76zf}
869a399b76zf
870a399b76zfstatic void
871a399b76zfwpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
872a399b76zf    unsigned char *src_addr, struct wpa_eapol_key *key, int ver)
873a399b76zf{
874a399b76zf	int rlen;
875a399b76zf	struct ieee802_1x_hdr *hdr;
876a399b76zf	struct wpa_eapol_key *reply;
877a399b76zf	unsigned char *rbuf;
878a399b76zf	struct l2_ethhdr *ethhdr;
879a399b76zf	struct wpa_ssid *ssid;
880a399b76zf	struct wpa_ptk *ptk;
881a399b76zf	uint8_t buf[8], wpa_ie_buf[80], *wpa_ie, *pmkid = NULL;
882a399b76zf	int wpa_ie_len;
883a399b76zf
884a399b76zf	wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
885a399b76zf	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from "
886a399b76zf	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
887a399b76zf
888a399b76zf	ssid = wpa_supplicant_get_ssid(wpa_s);
889a399b76zf	if (ssid == NULL) {
890a399b76zf		wpa_printf(MSG_WARNING,
891a399b76zf		    "WPA: No SSID info found (msg 1 of 4).");
892a399b76zf		return;
893a399b76zf	}
894a399b76zf
895a399b76zf	if (wpa_s->proto == WPA_PROTO_RSN) {
896a399b76zf		/* RSN: msg 1/4 should contain PMKID for the selected PMK */
897a399b76zf		uint8_t *pos = (uint8_t *)(key + 1);
898a399b76zf		uint8_t *end = pos + BE_16(key->key_data_length);
899a399b76zf
900a399b76zf		wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
901a399b76zf		    pos, BE_16(key->key_data_length));
902a399b76zf
903a399b76zf		while (pos + 1 < end) {
904a399b76zf			if (pos + 2 + pos[1] > end) {
905a399b76zf				wpa_printf(MSG_DEBUG, "RSN: key data "
906a399b76zf				    "underflow (ie=%d len=%d)",
907a399b76zf				    pos[0], pos[1]);
908a399b76zf				break;
909a399b76zf			}
910a399b76zf			if (pos[0] == GENERIC_INFO_ELEM &&
911d62bc4byz			    pos + 1 + RSN_SELECTOR_LEN < end &&
912d62bc4byz			    pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
913d62bc4byz			    memcmp(pos + 2, RSN_KEY_DATA_PMKID,
914d62bc4byz			    RSN_SELECTOR_LEN) == 0) {
915a399b76zf				pmkid = pos + 2 + RSN_SELECTOR_LEN;
916a399b76zf				wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
917a399b76zf				    "Authenticator", pmkid, PMKID_LEN);
918a399b76zf				break;
919a399b76zf			} else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0)
920a399b76zf				break;
921a399b76zf			pos += 2 + pos[1];
922a399b76zf		}
923a399b76zf	}
924a399b76zf
925a399b76zf	wpa_ie = wpa_ie_buf;
926a399b76zf	wpa_ie_len = wpa_gen_wpa_ie(wpa_s, wpa_ie);
927a399b76zf	if (wpa_ie_len < 0) {
928a399b76zf		wpa_printf(MSG_WARNING, "WPA: Failed to generate "
929a399b76zf		    "WPA IE (for msg 2 of 4).");
930a399b76zf		return;
931a399b76zf	}
932a399b76zf	wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
933a399b76zf
934a399b76zf	rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply) + wpa_ie_len;
935a399b76zf	rbuf = malloc(rlen);
936a399b76zf	if (rbuf == NULL)
937a399b76zf		return;
938a399b76zf
939a399b76zf	(void) memset(rbuf, 0, rlen);
940a399b76zf	ethhdr = (struct l2_ethhdr *)rbuf;
941a399b76zf	(void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
942a399b76zf	(void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
943a399b76zf	ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
944a399b76zf
945a399b76zf	hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
946a399b76zf	hdr->version = wpa_s->conf->eapol_version;
947a399b76zf	hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
948a399b76zf	hdr->length = htons(sizeof (*reply) + wpa_ie_len);
949a399b76zf
950a399b76zf	reply = (struct wpa_eapol_key *)(hdr + 1);
951a399b76zf	reply->type = wpa_s->proto == WPA_PROTO_RSN ?
952d62bc4byz	    EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
953d62bc4byz	reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
954a399b76zf	reply->key_length = key->key_length;
955a399b76zf	(void) memcpy(reply->replay_counter, key->replay_counter,
956d62bc4byz	    WPA_REPLAY_COUNTER_LEN);
957a399b76zf
958a399b76zf	reply->key_data_length = BE_16(wpa_ie_len);
959a399b76zf	(void) memcpy(reply + 1, wpa_ie, wpa_ie_len);
960a399b76zf
961a399b76zf	if (wpa_s->renew_snonce) {
962a399b76zf		if (random_get_pseudo_bytes(wpa_s->snonce, WPA_NONCE_LEN)) {
963a399b76zf			wpa_printf(MSG_WARNING, "WPA: Failed to get "
964a399b76zf			    "random data for SNonce");
965a399b76zf			free(rbuf);
966a399b76zf			return;
967a399b76zf		}
968a399b76zf
969a399b76zf		wpa_s->renew_snonce = 0;
970a399b76zf		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
971a399b76zf		    wpa_s->snonce, WPA_NONCE_LEN);
972a399b76zf	}
973a399b76zf	(void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN);
974a399b76zf	ptk = &wpa_s->tptk;
975a399b76zf	(void) memcpy(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN);
976a399b76zf
977a399b76zf	wpa_pmk_to_ptk(wpa_s->pmk, wpa_s->own_addr, src_addr,
978a399b76zf	    wpa_s->snonce, key->key_nonce, (uint8_t *)ptk, sizeof (*ptk));
979a399b76zf
980a399b76zf	/*
981a399b76zf	 * Supplicant: swap tx/rx Mic keys
982a399b76zf	 */
983a399b76zf	(void) memcpy(buf, ptk->u.auth.tx_mic_key, 8);
984a399b76zf	(void) memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
985a399b76zf	(void) memcpy(ptk->u.auth.rx_mic_key, buf, 8);
986a399b76zf	wpa_s->tptk_set = 1;
987a399b76zf	wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, (uint8_t *)hdr,
988d62bc4byz	    rlen - sizeof (*ethhdr), reply->key_mic);
989a399b76zf	wpa_hexdump(MSG_DEBUG, "WPA: EAPOL-Key MIC", reply->key_mic, 16);
990a399b76zf
991a399b76zf	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
992a399b76zf	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/4", rbuf, rlen);
993a399b76zf	(void) l2_packet_send(wpa_s->l2, rbuf, rlen);
994a399b76zf
995a399b76zf	free(rbuf);
996a399b76zf}
997a399b76zf
998a399b76zfstatic void
999a399b76zfwpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant *wpa_s,
1000a399b76zf    unsigned char *src_addr, struct wpa_eapol_key *key,
1001a399b76zf    uint8_t *gtk, int gtk_len)
1002a399b76zf{
1003a399b76zf	int keyidx, tx, key_rsc_len = 0, alg;
1004a399b76zf
1005a399b76zf	wpa_hexdump(MSG_DEBUG,
1006a399b76zf	    "WPA: received GTK in pairwise handshake", gtk, gtk_len);
1007a399b76zf
1008a399b76zf	keyidx = gtk[0] & 0x3;
1009a399b76zf	tx = !!(gtk[0] & BIT(2));
1010a399b76zf	if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
1011a399b76zf		/*
1012a399b76zf		 * Ignore Tx bit in GTK IE if a pairwise key is used.
1013a399b76zf		 * One AP seemed to set this bit (incorrectly, since Tx
1014a399b76zf		 * is only when doing Group Key only APs) and without
1015a399b76zf		 * this workaround, the data connection does not work
1016a399b76zf		 * because wpa_supplicant configured non-zero keyidx to
1017a399b76zf		 * be used for unicast.
1018a399b76zf		 */
1019a399b76zf		wpa_printf(MSG_INFO, "RSN: Tx bit set for GTK IE, but "
1020a399b76zf		    "pairwise keys are used - ignore Tx bit");
1021a399b76zf		tx = 0;
1022a399b76zf	}
1023a399b76zf
1024a399b76zf	gtk += 2;
1025a399b76zf	gtk_len -= 2;
1026a399b76zf	wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, gtk_len);
1027a399b76zf
1028a399b76zf	switch (wpa_s->group_cipher) {
1029a399b76zf	case WPA_CIPHER_CCMP:
1030a399b76zf		if (gtk_len != 16) {
1031a399b76zf			wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP"
1032a399b76zf			    " Group Cipher key length %d.", gtk_len);
1033a399b76zf			return;
1034a399b76zf		}
1035a399b76zf		key_rsc_len = 6;
1036a399b76zf		alg = WPA_ALG_CCMP;
1037a399b76zf		break;
1038a399b76zf	case WPA_CIPHER_TKIP:
1039a399b76zf		if (gtk_len != 32) {
1040a399b76zf			wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP"
1041a399b76zf			    " Group Cipher key length %d.", gtk_len);
1042a399b76zf			return;
1043a399b76zf		}
1044a399b76zf		key_rsc_len = 6;
1045a399b76zf		alg = WPA_ALG_TKIP;
1046a399b76zf		break;
1047a399b76zf	case WPA_CIPHER_WEP104:
1048a399b76zf		if (gtk_len != 13) {
1049a399b76zf			wpa_printf(MSG_WARNING, "WPA: Unsupported "
1050a399b76zf			    "WEP104 Group Cipher key length " "%d.", gtk_len);
1051a399b76zf			return;
1052a399b76zf		}
1053a399b76zf		alg = WPA_ALG_WEP;
1054a399b76zf		break;
1055a399b76zf	case WPA_CIPHER_WEP40:
1056a399b76zf		if (gtk_len != 5) {
1057a399b76zf			wpa_printf(MSG_WARNING, "WPA: Unsupported "
1058a399b76zf			    "WEP40 Group Cipher key length %d.", gtk_len);
1059a399b76zf			return;
1060a399b76zf		}
1061a399b76zf		alg = WPA_ALG_WEP;
1062a399b76zf		break;
1063a399b76zf	default:
1064a399b76zf		wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher "
1065a399b76zf		    "%d", wpa_s->group_cipher);
1066a399b76zf		return;
1067a399b76zf	}
1068a399b76zf
1069a399b76zf	wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "
1070a399b76zf	    "(keyidx=%d tx=%d).", keyidx, tx);
1071a399b76zf	wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len);
1072a399b76zf	if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
1073a399b76zf		uint8_t tmpbuf[8];
1074a399b76zf		/*
1075a399b76zf		 * Swap Tx/Rx keys for Michael MIC
1076a399b76zf		 */
1077a399b76zf		(void) memcpy(tmpbuf, gtk + 16, 8);
1078a399b76zf		(void) memcpy(gtk + 16, gtk + 24, 8);
1079a399b76zf		(void) memcpy(gtk + 24, tmpbuf, 8);
1080a399b76zf	}
1081a399b76zf	if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
10824ac67f0Anurag S. Maskey		if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1083a399b76zf		    (uint8_t *)"\xff\xff\xff\xff\xff\xff",
1084a399b76zf		    keyidx, 1, key->key_rsc,
1085a399b76zf		    key_rsc_len, gtk, gtk_len) < 0)
1086a399b76zf			wpa_printf(MSG_WARNING, "WPA: Failed to set "
1087a399b76zf			    "GTK to the driver (Group only).");
10884ac67f0Anurag S. Maskey	} else if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1089d62bc4byz	    (uint8_t *)"\xff\xff\xff\xff\xff\xff", keyidx, tx,
1090d62bc4byz	    key->key_rsc, key_rsc_len, gtk, gtk_len) < 0) {
1091a399b76zf		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "
1092a399b76zf		    "the driver.");
1093a399b76zf	}
1094a399b76zf
1095a399b76zf	wpa_printf(MSG_INFO, "WPA: Key negotiation completed with "
1096d62bc4byz	    MACSTR, MAC2STR(src_addr));
1097a399b76zf	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
1098a399b76zf	wpa_supplicant_cancel_auth_timeout(wpa_s);
1099a399b76zf	wpa_s->wpa_state = WPA_COMPLETED;
1100a399b76zf}
1101a399b76zf
1102a399b76zfstatic void
1103a399b76zfwpa_supplicant_process_3_of_4(struct wpa_supplicant *wpa_s,
1104a399b76zf    unsigned char *src_addr, struct wpa_eapol_key *key,
1105a399b76zf    int extra_len, int ver)
1106a399b76zf{
1107a399b76zf	int rlen;
1108a399b76zf	struct ieee802_1x_hdr *hdr;
1109a399b76zf	struct wpa_eapol_key *reply;
1110a399b76zf	unsigned char *rbuf;
1111a399b76zf	struct l2_ethhdr *ethhdr;
1112a399b76zf	int key_info, ie_len = 0, keylen, gtk_len = 0;
1113a399b76zf	uint8_t *ie = NULL, *gtk = NULL, *key_rsc;
1114a399b76zf	uint8_t null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1115a399b76zf
1116a399b76zf	wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
1117a399b76zf	wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from "
1118a399b76zf	    MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1119a399b76zf
1120a399b76zf	key_info = BE_16(key->key_info);
1121a399b76zf
1122a399b76zf	if (wpa_s->proto == WPA_PROTO_RSN) {
1123a399b76zf		uint8_t *pos = (uint8_t *)(key + 1);
1124a399b76zf		uint8_t *end = pos + BE_16(key->key_data_length);
1125a399b76zf		while (pos + 1 < end) {
1126a399b76zf			if (pos + 2 + pos[1] > end) {
1127a399b76zf				wpa_printf(MSG_DEBUG, "RSN: key data "
1128a399b76zf				    "underflow (ie=%d len=%d)",
1129a399b76zf				    pos[0], pos[1]);
1130a399b76zf				break;
1131