Disconnect hostapd from building in base
[dragonfly.git] / contrib / hostapd / 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         sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
568         if (sm->pairwise < 0)
569                 return WPA_INVALID_PAIRWISE;
570
571         /* TODO: clear WPA/WPA2 state if STA changes from one to another */
572         if (wpa_ie[0] == WLAN_EID_RSN)
573                 sm->wpa = WPA_VERSION_WPA2;
574         else
575                 sm->wpa = WPA_VERSION_WPA;
576
577         sm->pmksa = NULL;
578         for (i = 0; i < data.num_pmkid; i++) {
579                 wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID",
580                             &data.pmkid[i * PMKID_LEN], PMKID_LEN);
581                 sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr,
582                                                  &data.pmkid[i * PMKID_LEN]);
583                 if (sm->pmksa) {
584                         pmkid = sm->pmksa->pmkid;
585                         break;
586                 }
587         }
588         for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc &&
589                      i < data.num_pmkid; i++) {
590                 struct wpa_auth_okc_iter_data idata;
591                 idata.pmksa = NULL;
592                 idata.aa = wpa_auth->addr;
593                 idata.spa = sm->addr;
594                 idata.pmkid = &data.pmkid[i * PMKID_LEN];
595                 wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata);
596                 if (idata.pmksa) {
597                         wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
598                                          "OKC match for PMKID");
599                         sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa,
600                                                         idata.pmksa,
601                                                         wpa_auth->addr,
602                                                         idata.pmkid);
603                         pmkid = idata.pmkid;
604                         break;
605                 }
606         }
607         if (sm->pmksa) {
608                 wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
609                                  "PMKID found from PMKSA cache "
610                                  "eap_type=%d vlan_id=%d",
611                                  sm->pmksa->eap_type_authsrv,
612                                  sm->pmksa->vlan_id);
613                 os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
614         }
615
616         if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
617                 os_free(sm->wpa_ie);
618                 sm->wpa_ie = os_malloc(wpa_ie_len);
619                 if (sm->wpa_ie == NULL)
620                         return WPA_ALLOC_FAIL;
621         }
622         os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len);
623         sm->wpa_ie_len = wpa_ie_len;
624
625         return WPA_IE_OK;
626 }
627
628
629 /**
630  * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
631  * @pos: Pointer to the IE header
632  * @end: Pointer to the end of the Key Data buffer
633  * @ie: Pointer to parsed IE data
634  * Returns: 0 on success, 1 if end mark is found, -1 on failure
635  */
636 static int wpa_parse_generic(const u8 *pos, const u8 *end,
637                              struct wpa_eapol_ie_parse *ie)
638 {
639         if (pos[1] == 0)
640                 return 1;
641
642         if (pos[1] >= 6 &&
643             RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
644             pos[2 + WPA_SELECTOR_LEN] == 1 &&
645             pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
646                 ie->wpa_ie = pos;
647                 ie->wpa_ie_len = pos[1] + 2;
648                 return 0;
649         }
650
651         if (pos + 1 + RSN_SELECTOR_LEN < end &&
652             pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
653             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
654                 ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
655                 return 0;
656         }
657
658         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
659             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
660                 ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
661                 ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
662                 return 0;
663         }
664
665         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
666             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
667                 ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
668                 ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
669                 return 0;
670         }
671
672 #ifdef CONFIG_PEERKEY
673         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
674             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
675                 ie->smk = pos + 2 + RSN_SELECTOR_LEN;
676                 ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
677                 return 0;
678         }
679
680         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
681             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
682                 ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
683                 ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
684                 return 0;
685         }
686
687         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
688             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
689                 ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
690                 ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
691                 return 0;
692         }
693
694         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
695             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
696                 ie->error = pos + 2 + RSN_SELECTOR_LEN;
697                 ie->error_len = pos[1] - RSN_SELECTOR_LEN;
698                 return 0;
699         }
700 #endif /* CONFIG_PEERKEY */
701
702 #ifdef CONFIG_IEEE80211W
703         if (pos[1] > RSN_SELECTOR_LEN + 2 &&
704             RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
705                 ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
706                 ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
707                 return 0;
708         }
709 #endif /* CONFIG_IEEE80211W */
710
711 #ifdef CONFIG_P2P
712         if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
713             RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
714                 ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
715                 wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
716                             ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
717                 return 0;
718         }
719
720         if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
721             RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
722                 ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
723                 wpa_hexdump(MSG_DEBUG,
724                             "WPA: IP Address Allocation in EAPOL-Key",
725                             ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
726                 return 0;
727         }
728 #endif /* CONFIG_P2P */
729
730         return 0;
731 }
732
733
734 /**
735  * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
736  * @buf: Pointer to the Key Data buffer
737  * @len: Key Data Length
738  * @ie: Pointer to parsed IE data
739  * Returns: 0 on success, -1 on failure
740  */
741 int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
742 {
743         const u8 *pos, *end;
744         int ret = 0;
745
746         os_memset(ie, 0, sizeof(*ie));
747         for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
748                 if (pos[0] == 0xdd &&
749                     ((pos == buf + len - 1) || pos[1] == 0)) {
750                         /* Ignore padding */
751                         break;
752                 }
753                 if (pos + 2 + pos[1] > end) {
754                         wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
755                                    "underflow (ie=%d len=%d pos=%d)",
756                                    pos[0], pos[1], (int) (pos - buf));
757                         wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
758                                         buf, len);
759                         ret = -1;
760                         break;
761                 }
762                 if (*pos == WLAN_EID_RSN) {
763                         ie->rsn_ie = pos;
764                         ie->rsn_ie_len = pos[1] + 2;
765 #ifdef CONFIG_IEEE80211R
766                 } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
767                         ie->mdie = pos;
768                         ie->mdie_len = pos[1] + 2;
769                 } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
770                         ie->ftie = pos;
771                         ie->ftie_len = pos[1] + 2;
772 #endif /* CONFIG_IEEE80211R */
773                 } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
774                         ret = wpa_parse_generic(pos, end, ie);
775                         if (ret < 0)
776                                 break;
777                         if (ret > 0) {
778                                 ret = 0;
779                                 break;
780                         }
781                 } else {
782                         wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
783                                     "Key Data IE", pos, 2 + pos[1]);
784                 }
785         }
786
787         return ret;
788 }
789
790
791 int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
792 {
793         return sm ? sm->mgmt_frame_prot : 0;
794 }