]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/wpa/src/ap/wpa_auth_ie.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / wpa / src / ap / wpa_auth_ie.c
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
23 int rsn_testing = 0;
24 #endif /* CONFIG_RSN_TESTING */
25
26
27 static 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
91 int 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
298 int 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
340 u8 * 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
357 struct 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
365 static 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
376 int 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  */
639 static 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  */
725 int 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
775 int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
776 {
777         return sm ? sm->mgmt_frame_prot : 0;
778 }