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