wpa_auth_ie.c revision d5e4923d04122f81300fa68fb07d64ede28fd44d
1/*
2 * hostapd - WPA/RSN IE and KDE definitions
3 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "utils/includes.h"
10
11#include "utils/common.h"
12#include "common/ieee802_11_defs.h"
13#include "eapol_auth/eapol_auth_sm.h"
14#include "ap_config.h"
15#include "ieee802_11.h"
16#include "wpa_auth.h"
17#include "pmksa_cache_auth.h"
18#include "wpa_auth_ie.h"
19#include "wpa_auth_i.h"
20
21
22#ifdef CONFIG_RSN_TESTING
23int rsn_testing = 0;
24#endif /* CONFIG_RSN_TESTING */
25
26
27static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len)
28{
29	struct wpa_ie_hdr *hdr;
30	int num_suites;
31	u8 *pos, *count;
32	u32 suite;
33
34	hdr = (struct wpa_ie_hdr *) buf;
35	hdr->elem_id = WLAN_EID_VENDOR_SPECIFIC;
36	RSN_SELECTOR_PUT(hdr->oui, WPA_OUI_TYPE);
37	WPA_PUT_LE16(hdr->version, WPA_VERSION);
38	pos = (u8 *) (hdr + 1);
39
40	suite = wpa_cipher_to_suite(WPA_PROTO_WPA, conf->wpa_group);
41	if (suite == 0) {
42		wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
43			   conf->wpa_group);
44		return -1;
45	}
46	RSN_SELECTOR_PUT(pos, suite);
47	pos += WPA_SELECTOR_LEN;
48
49	count = pos;
50	pos += 2;
51
52	num_suites = wpa_cipher_put_suites(pos, conf->wpa_pairwise);
53	if (num_suites == 0) {
54		wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
55			   conf->wpa_pairwise);
56		return -1;
57	}
58	pos += num_suites * WPA_SELECTOR_LEN;
59	WPA_PUT_LE16(count, num_suites);
60
61	num_suites = 0;
62	count = pos;
63	pos += 2;
64
65	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
66		RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
67		pos += WPA_SELECTOR_LEN;
68		num_suites++;
69	}
70	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
71		RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
72		pos += WPA_SELECTOR_LEN;
73		num_suites++;
74	}
75
76	if (num_suites == 0) {
77		wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
78			   conf->wpa_key_mgmt);
79		return -1;
80	}
81	WPA_PUT_LE16(count, num_suites);
82
83	/* WPA Capabilities; use defaults, so no need to include it */
84
85	hdr->len = (pos - buf) - 2;
86
87	return pos - buf;
88}
89
90
91int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
92		     const u8 *pmkid)
93{
94	struct rsn_ie_hdr *hdr;
95	int num_suites, res;
96	u8 *pos, *count;
97	u16 capab;
98	u32 suite;
99
100	hdr = (struct rsn_ie_hdr *) buf;
101	hdr->elem_id = WLAN_EID_RSN;
102	WPA_PUT_LE16(hdr->version, RSN_VERSION);
103	pos = (u8 *) (hdr + 1);
104
105	suite = wpa_cipher_to_suite(WPA_PROTO_RSN, conf->wpa_group);
106	if (suite == 0) {
107		wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
108			   conf->wpa_group);
109		return -1;
110	}
111	RSN_SELECTOR_PUT(pos, suite);
112	pos += RSN_SELECTOR_LEN;
113
114	num_suites = 0;
115	count = pos;
116	pos += 2;
117
118#ifdef CONFIG_RSN_TESTING
119	if (rsn_testing) {
120		RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
121		pos += RSN_SELECTOR_LEN;
122		num_suites++;
123	}
124#endif /* CONFIG_RSN_TESTING */
125
126	res = rsn_cipher_put_suites(pos, conf->rsn_pairwise);
127	num_suites += res;
128	pos += res * RSN_SELECTOR_LEN;
129
130#ifdef CONFIG_RSN_TESTING
131	if (rsn_testing) {
132		RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
133		pos += RSN_SELECTOR_LEN;
134		num_suites++;
135	}
136#endif /* CONFIG_RSN_TESTING */
137
138	if (num_suites == 0) {
139		wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
140			   conf->rsn_pairwise);
141		return -1;
142	}
143	WPA_PUT_LE16(count, num_suites);
144
145	num_suites = 0;
146	count = pos;
147	pos += 2;
148
149#ifdef CONFIG_RSN_TESTING
150	if (rsn_testing) {
151		RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1));
152		pos += RSN_SELECTOR_LEN;
153		num_suites++;
154	}
155#endif /* CONFIG_RSN_TESTING */
156
157	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
158		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
159		pos += RSN_SELECTOR_LEN;
160		num_suites++;
161	}
162	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
163		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
164		pos += RSN_SELECTOR_LEN;
165		num_suites++;
166	}
167#ifdef CONFIG_IEEE80211R
168	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
169		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
170		pos += RSN_SELECTOR_LEN;
171		num_suites++;
172	}
173	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) {
174		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
175		pos += RSN_SELECTOR_LEN;
176		num_suites++;
177	}
178#endif /* CONFIG_IEEE80211R */
179#ifdef CONFIG_IEEE80211W
180	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
181		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
182		pos += RSN_SELECTOR_LEN;
183		num_suites++;
184	}
185	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
186		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
187		pos += RSN_SELECTOR_LEN;
188		num_suites++;
189	}
190#endif /* CONFIG_IEEE80211W */
191#ifdef CONFIG_SAE
192	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) {
193		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
194		pos += RSN_SELECTOR_LEN;
195		num_suites++;
196	}
197	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
198		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
199		pos += RSN_SELECTOR_LEN;
200		num_suites++;
201	}
202#endif /* CONFIG_SAE */
203
204#ifdef CONFIG_RSN_TESTING
205	if (rsn_testing) {
206		RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
207		pos += RSN_SELECTOR_LEN;
208		num_suites++;
209	}
210#endif /* CONFIG_RSN_TESTING */
211
212	if (num_suites == 0) {
213		wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
214			   conf->wpa_key_mgmt);
215		return -1;
216	}
217	WPA_PUT_LE16(count, num_suites);
218
219	/* RSN Capabilities */
220	capab = 0;
221	if (conf->rsn_preauth)
222		capab |= WPA_CAPABILITY_PREAUTH;
223	if (conf->peerkey)
224		capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
225	if (conf->wmm_enabled) {
226		/* 4 PTKSA replay counters when using WMM */
227		capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
228	}
229#ifdef CONFIG_IEEE80211W
230	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
231		capab |= WPA_CAPABILITY_MFPC;
232		if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
233			capab |= WPA_CAPABILITY_MFPR;
234	}
235#endif /* CONFIG_IEEE80211W */
236#ifdef CONFIG_RSN_TESTING
237	if (rsn_testing)
238		capab |= BIT(8) | BIT(14) | BIT(15);
239#endif /* CONFIG_RSN_TESTING */
240	WPA_PUT_LE16(pos, capab);
241	pos += 2;
242
243	if (pmkid) {
244		if (pos + 2 + PMKID_LEN > buf + len)
245			return -1;
246		/* PMKID Count */
247		WPA_PUT_LE16(pos, 1);
248		pos += 2;
249		os_memcpy(pos, pmkid, PMKID_LEN);
250		pos += PMKID_LEN;
251	}
252
253#ifdef CONFIG_IEEE80211W
254	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
255		if (pos + 2 + 4 > buf + len)
256			return -1;
257		if (pmkid == NULL) {
258			/* PMKID Count */
259			WPA_PUT_LE16(pos, 0);
260			pos += 2;
261		}
262
263		/* Management Group Cipher Suite */
264		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
265		pos += RSN_SELECTOR_LEN;
266	}
267#endif /* CONFIG_IEEE80211W */
268
269#ifdef CONFIG_RSN_TESTING
270	if (rsn_testing) {
271		/*
272		 * Fill in any defined fields and add extra data to the end of
273		 * the element.
274		 */
275		int pmkid_count_set = pmkid != NULL;
276		if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION)
277			pmkid_count_set = 1;
278		/* PMKID Count */
279		WPA_PUT_LE16(pos, 0);
280		pos += 2;
281		if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
282			/* Management Group Cipher Suite */
283			RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
284			pos += RSN_SELECTOR_LEN;
285		}
286
287		os_memset(pos, 0x12, 17);
288		pos += 17;
289	}
290#endif /* CONFIG_RSN_TESTING */
291
292	hdr->len = (pos - buf) - 2;
293
294	return pos - buf;
295}
296
297
298int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
299{
300	u8 *pos, buf[128];
301	int res;
302
303	pos = buf;
304
305	if (wpa_auth->conf.wpa & WPA_PROTO_RSN) {
306		res = wpa_write_rsn_ie(&wpa_auth->conf,
307				       pos, buf + sizeof(buf) - pos, NULL);
308		if (res < 0)
309			return res;
310		pos += res;
311	}
312#ifdef CONFIG_IEEE80211R
313	if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) {
314		res = wpa_write_mdie(&wpa_auth->conf, pos,
315				     buf + sizeof(buf) - pos);
316		if (res < 0)
317			return res;
318		pos += res;
319	}
320#endif /* CONFIG_IEEE80211R */
321	if (wpa_auth->conf.wpa & WPA_PROTO_WPA) {
322		res = wpa_write_wpa_ie(&wpa_auth->conf,
323				       pos, buf + sizeof(buf) - pos);
324		if (res < 0)
325			return res;
326		pos += res;
327	}
328
329	os_free(wpa_auth->wpa_ie);
330	wpa_auth->wpa_ie = os_malloc(pos - buf);
331	if (wpa_auth->wpa_ie == NULL)
332		return -1;
333	os_memcpy(wpa_auth->wpa_ie, buf, pos - buf);
334	wpa_auth->wpa_ie_len = pos - buf;
335
336	return 0;
337}
338
339
340u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len,
341		 const u8 *data2, size_t data2_len)
342{
343	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
344	*pos++ = RSN_SELECTOR_LEN + data_len + data2_len;
345	RSN_SELECTOR_PUT(pos, kde);
346	pos += RSN_SELECTOR_LEN;
347	os_memcpy(pos, data, data_len);
348	pos += data_len;
349	if (data2) {
350		os_memcpy(pos, data2, data2_len);
351		pos += data2_len;
352	}
353	return pos;
354}
355
356
357struct wpa_auth_okc_iter_data {
358	struct rsn_pmksa_cache_entry *pmksa;
359	const u8 *aa;
360	const u8 *spa;
361	const u8 *pmkid;
362};
363
364
365static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx)
366{
367	struct wpa_auth_okc_iter_data *data = ctx;
368	data->pmksa = pmksa_cache_get_okc(a->pmksa, data->aa, data->spa,
369					  data->pmkid);
370	if (data->pmksa)
371		return 1;
372	return 0;
373}
374
375
376int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
377			struct wpa_state_machine *sm,
378			const u8 *wpa_ie, size_t wpa_ie_len,
379			const u8 *mdie, size_t mdie_len)
380{
381	struct wpa_ie_data data;
382	int ciphers, key_mgmt, res, version;
383	u32 selector;
384	size_t i;
385	const u8 *pmkid = NULL;
386
387	if (wpa_auth == NULL || sm == NULL)
388		return WPA_NOT_ENABLED;
389
390	if (wpa_ie == NULL || wpa_ie_len < 1)
391		return WPA_INVALID_IE;
392
393	if (wpa_ie[0] == WLAN_EID_RSN)
394		version = WPA_PROTO_RSN;
395	else
396		version = WPA_PROTO_WPA;
397
398	if (!(wpa_auth->conf.wpa & version)) {
399		wpa_printf(MSG_DEBUG, "Invalid WPA proto (%d) from " MACSTR,
400			   version, MAC2STR(sm->addr));
401		return WPA_INVALID_PROTO;
402	}
403
404	if (version == WPA_PROTO_RSN) {
405		res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
406
407		selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
408		if (0) {
409		}
410#ifdef CONFIG_IEEE80211R
411		else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
412			selector = RSN_AUTH_KEY_MGMT_FT_802_1X;
413		else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK)
414			selector = RSN_AUTH_KEY_MGMT_FT_PSK;
415#endif /* CONFIG_IEEE80211R */
416#ifdef CONFIG_IEEE80211W
417		else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
418			selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256;
419		else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
420			selector = RSN_AUTH_KEY_MGMT_PSK_SHA256;
421#endif /* CONFIG_IEEE80211W */
422#ifdef CONFIG_SAE
423		else if (data.key_mgmt & WPA_KEY_MGMT_SAE)
424			selector = RSN_AUTH_KEY_MGMT_SAE;
425		else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)
426			selector = RSN_AUTH_KEY_MGMT_FT_SAE;
427#endif /* CONFIG_SAE */
428		else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
429			selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
430		else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
431			selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
432		wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
433
434		selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
435					       data.pairwise_cipher);
436		if (!selector)
437			selector = RSN_CIPHER_SUITE_CCMP;
438		wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
439
440		selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
441					       data.group_cipher);
442		if (!selector)
443			selector = RSN_CIPHER_SUITE_CCMP;
444		wpa_auth->dot11RSNAGroupCipherSelected = selector;
445	} else {
446		res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data);
447
448		selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
449		if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
450			selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
451		else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
452			selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
453		wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
454
455		selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
456					       data.pairwise_cipher);
457		if (!selector)
458			selector = RSN_CIPHER_SUITE_TKIP;
459		wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
460
461		selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
462					       data.group_cipher);
463		if (!selector)
464			selector = WPA_CIPHER_SUITE_TKIP;
465		wpa_auth->dot11RSNAGroupCipherSelected = selector;
466	}
467	if (res) {
468		wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from "
469			   MACSTR " (res=%d)", MAC2STR(sm->addr), res);
470		wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len);
471		return WPA_INVALID_IE;
472	}
473
474	if (data.group_cipher != wpa_auth->conf.wpa_group) {
475		wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from "
476			   MACSTR, data.group_cipher, MAC2STR(sm->addr));
477		return WPA_INVALID_GROUP;
478	}
479
480	key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
481	if (!key_mgmt) {
482		wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from "
483			   MACSTR, data.key_mgmt, MAC2STR(sm->addr));
484		return WPA_INVALID_AKMP;
485	}
486	if (0) {
487	}
488#ifdef CONFIG_IEEE80211R
489	else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
490		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
491	else if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
492		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK;
493#endif /* CONFIG_IEEE80211R */
494#ifdef CONFIG_IEEE80211W
495	else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
496		sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
497	else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
498		sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
499#endif /* CONFIG_IEEE80211W */
500#ifdef CONFIG_SAE
501	else if (key_mgmt & WPA_KEY_MGMT_SAE)
502		sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
503	else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)
504		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;
505#endif /* CONFIG_SAE */
506	else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
507		sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
508	else
509		sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
510
511	if (version == WPA_PROTO_RSN)
512		ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise;
513	else
514		ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise;
515	if (!ciphers) {
516		wpa_printf(MSG_DEBUG, "Invalid %s pairwise cipher (0x%x) "
517			   "from " MACSTR,
518			   version == WPA_PROTO_RSN ? "RSN" : "WPA",
519			   data.pairwise_cipher, MAC2STR(sm->addr));
520		return WPA_INVALID_PAIRWISE;
521	}
522
523#ifdef CONFIG_IEEE80211W
524	if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
525		if (!(data.capabilities & WPA_CAPABILITY_MFPC)) {
526			wpa_printf(MSG_DEBUG, "Management frame protection "
527				   "required, but client did not enable it");
528			return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
529		}
530
531		if (ciphers & WPA_CIPHER_TKIP) {
532			wpa_printf(MSG_DEBUG, "Management frame protection "
533				   "cannot use TKIP");
534			return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
535		}
536
537		if (data.mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) {
538			wpa_printf(MSG_DEBUG, "Unsupported management group "
539				   "cipher %d", data.mgmt_group_cipher);
540			return WPA_INVALID_MGMT_GROUP_CIPHER;
541		}
542	}
543
544	if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION ||
545	    !(data.capabilities & WPA_CAPABILITY_MFPC))
546		sm->mgmt_frame_prot = 0;
547	else
548		sm->mgmt_frame_prot = 1;
549#endif /* CONFIG_IEEE80211W */
550
551#ifdef CONFIG_IEEE80211R
552	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
553		if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) {
554			wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but "
555				   "MDIE not included");
556			return WPA_INVALID_MDIE;
557		}
558		if (os_memcmp(mdie, wpa_auth->conf.mobility_domain,
559			      MOBILITY_DOMAIN_ID_LEN) != 0) {
560			wpa_hexdump(MSG_DEBUG, "RSN: Attempted to use unknown "
561				    "MDIE", mdie, MOBILITY_DOMAIN_ID_LEN);
562			return WPA_INVALID_MDIE;
563		}
564	}
565#endif /* CONFIG_IEEE80211R */
566
567	if (ciphers & WPA_CIPHER_CCMP)
568		sm->pairwise = WPA_CIPHER_CCMP;
569	else if (ciphers & WPA_CIPHER_GCMP)
570		sm->pairwise = WPA_CIPHER_GCMP;
571	else
572		sm->pairwise = WPA_CIPHER_TKIP;
573
574	/* TODO: clear WPA/WPA2 state if STA changes from one to another */
575	if (wpa_ie[0] == WLAN_EID_RSN)
576		sm->wpa = WPA_VERSION_WPA2;
577	else
578		sm->wpa = WPA_VERSION_WPA;
579
580	sm->pmksa = NULL;
581	for (i = 0; i < data.num_pmkid; i++) {
582		wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID",
583			    &data.pmkid[i * PMKID_LEN], PMKID_LEN);
584		sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr,
585						 &data.pmkid[i * PMKID_LEN]);
586		if (sm->pmksa) {
587			pmkid = sm->pmksa->pmkid;
588			break;
589		}
590	}
591	for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc &&
592		     i < data.num_pmkid; i++) {
593		struct wpa_auth_okc_iter_data idata;
594		idata.pmksa = NULL;
595		idata.aa = wpa_auth->addr;
596		idata.spa = sm->addr;
597		idata.pmkid = &data.pmkid[i * PMKID_LEN];
598		wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata);
599		if (idata.pmksa) {
600			wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
601					 "OKC match for PMKID");
602			sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa,
603							idata.pmksa,
604							wpa_auth->addr,
605							idata.pmkid);
606			pmkid = idata.pmkid;
607			break;
608		}
609	}
610	if (sm->pmksa) {
611		wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
612				 "PMKID found from PMKSA cache "
613				 "eap_type=%d vlan_id=%d",
614				 sm->pmksa->eap_type_authsrv,
615				 sm->pmksa->vlan_id);
616		os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
617	}
618
619	if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
620		os_free(sm->wpa_ie);
621		sm->wpa_ie = os_malloc(wpa_ie_len);
622		if (sm->wpa_ie == NULL)
623			return WPA_ALLOC_FAIL;
624	}
625	os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len);
626	sm->wpa_ie_len = wpa_ie_len;
627
628	return WPA_IE_OK;
629}
630
631
632/**
633 * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
634 * @pos: Pointer to the IE header
635 * @end: Pointer to the end of the Key Data buffer
636 * @ie: Pointer to parsed IE data
637 * Returns: 0 on success, 1 if end mark is found, -1 on failure
638 */
639static int wpa_parse_generic(const u8 *pos, const u8 *end,
640			     struct wpa_eapol_ie_parse *ie)
641{
642	if (pos[1] == 0)
643		return 1;
644
645	if (pos[1] >= 6 &&
646	    RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
647	    pos[2 + WPA_SELECTOR_LEN] == 1 &&
648	    pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
649		ie->wpa_ie = pos;
650		ie->wpa_ie_len = pos[1] + 2;
651		return 0;
652	}
653
654	if (pos + 1 + RSN_SELECTOR_LEN < end &&
655	    pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
656	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
657		ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
658		return 0;
659	}
660
661	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
662	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
663		ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
664		ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
665		return 0;
666	}
667
668	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
669	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
670		ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
671		ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
672		return 0;
673	}
674
675#ifdef CONFIG_PEERKEY
676	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
677	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
678		ie->smk = pos + 2 + RSN_SELECTOR_LEN;
679		ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
680		return 0;
681	}
682
683	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
684	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
685		ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
686		ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
687		return 0;
688	}
689
690	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
691	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
692		ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
693		ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
694		return 0;
695	}
696
697	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
698	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
699		ie->error = pos + 2 + RSN_SELECTOR_LEN;
700		ie->error_len = pos[1] - RSN_SELECTOR_LEN;
701		return 0;
702	}
703#endif /* CONFIG_PEERKEY */
704
705#ifdef CONFIG_IEEE80211W
706	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
707	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
708		ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
709		ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
710		return 0;
711	}
712#endif /* CONFIG_IEEE80211W */
713
714	return 0;
715}
716
717
718/**
719 * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
720 * @buf: Pointer to the Key Data buffer
721 * @len: Key Data Length
722 * @ie: Pointer to parsed IE data
723 * Returns: 0 on success, -1 on failure
724 */
725int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
726{
727	const u8 *pos, *end;
728	int ret = 0;
729
730	os_memset(ie, 0, sizeof(*ie));
731	for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
732		if (pos[0] == 0xdd &&
733		    ((pos == buf + len - 1) || pos[1] == 0)) {
734			/* Ignore padding */
735			break;
736		}
737		if (pos + 2 + pos[1] > end) {
738			wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
739				   "underflow (ie=%d len=%d pos=%d)",
740				   pos[0], pos[1], (int) (pos - buf));
741			wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
742					buf, len);
743			ret = -1;
744			break;
745		}
746		if (*pos == WLAN_EID_RSN) {
747			ie->rsn_ie = pos;
748			ie->rsn_ie_len = pos[1] + 2;
749#ifdef CONFIG_IEEE80211R
750		} else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
751			ie->mdie = pos;
752			ie->mdie_len = pos[1] + 2;
753		} else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
754			ie->ftie = pos;
755			ie->ftie_len = pos[1] + 2;
756#endif /* CONFIG_IEEE80211R */
757		} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
758			ret = wpa_parse_generic(pos, end, ie);
759			if (ret < 0)
760				break;
761			if (ret > 0) {
762				ret = 0;
763				break;
764			}
765		} else {
766			wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
767				    "Key Data IE", pos, 2 + pos[1]);
768		}
769	}
770
771	return ret;
772}
773
774
775int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
776{
777	return sm ? sm->mgmt_frame_prot : 0;
778}
779