Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd - WPA/RSN IE and KDE definitions
      3  * Copyright (c) 2004-2015, Jouni Malinen <j (at) 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_AP
    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_AP */
    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 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
    204 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
    205 		pos += RSN_SELECTOR_LEN;
    206 		num_suites++;
    207 	}
    208 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
    209 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192);
    210 		pos += RSN_SELECTOR_LEN;
    211 		num_suites++;
    212 	}
    213 #ifdef CONFIG_FILS
    214 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA256) {
    215 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
    216 		pos += RSN_SELECTOR_LEN;
    217 		num_suites++;
    218 	}
    219 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA384) {
    220 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
    221 		pos += RSN_SELECTOR_LEN;
    222 		num_suites++;
    223 	}
    224 #ifdef CONFIG_IEEE80211R_AP
    225 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
    226 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256);
    227 		pos += RSN_SELECTOR_LEN;
    228 		num_suites++;
    229 	}
    230 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) {
    231 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384);
    232 		pos += RSN_SELECTOR_LEN;
    233 		num_suites++;
    234 	}
    235 #endif /* CONFIG_IEEE80211R_AP */
    236 #endif /* CONFIG_FILS */
    237 #ifdef CONFIG_OWE
    238 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) {
    239 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE);
    240 		pos += RSN_SELECTOR_LEN;
    241 		num_suites++;
    242 	}
    243 #endif /* CONFIG_OWE */
    244 #ifdef CONFIG_DPP
    245 	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
    246 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_DPP);
    247 		pos += RSN_SELECTOR_LEN;
    248 		num_suites++;
    249 	}
    250 #endif /* CONFIG_DPP */
    251 
    252 #ifdef CONFIG_RSN_TESTING
    253 	if (rsn_testing) {
    254 		RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2));
    255 		pos += RSN_SELECTOR_LEN;
    256 		num_suites++;
    257 	}
    258 #endif /* CONFIG_RSN_TESTING */
    259 
    260 	if (num_suites == 0) {
    261 		wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
    262 			   conf->wpa_key_mgmt);
    263 		return -1;
    264 	}
    265 	WPA_PUT_LE16(count, num_suites);
    266 
    267 	/* RSN Capabilities */
    268 	capab = 0;
    269 	if (conf->rsn_preauth)
    270 		capab |= WPA_CAPABILITY_PREAUTH;
    271 	if (conf->wmm_enabled) {
    272 		/* 4 PTKSA replay counters when using WMM */
    273 		capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
    274 	}
    275 #ifdef CONFIG_IEEE80211W
    276 	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
    277 		capab |= WPA_CAPABILITY_MFPC;
    278 		if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
    279 			capab |= WPA_CAPABILITY_MFPR;
    280 	}
    281 #endif /* CONFIG_IEEE80211W */
    282 #ifdef CONFIG_RSN_TESTING
    283 	if (rsn_testing)
    284 		capab |= BIT(8) | BIT(14) | BIT(15);
    285 #endif /* CONFIG_RSN_TESTING */
    286 	WPA_PUT_LE16(pos, capab);
    287 	pos += 2;
    288 
    289 	if (pmkid) {
    290 		if (2 + PMKID_LEN > buf + len - pos)
    291 			return -1;
    292 		/* PMKID Count */
    293 		WPA_PUT_LE16(pos, 1);
    294 		pos += 2;
    295 		os_memcpy(pos, pmkid, PMKID_LEN);
    296 		pos += PMKID_LEN;
    297 	}
    298 
    299 #ifdef CONFIG_IEEE80211W
    300 	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
    301 	    conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) {
    302 		if (2 + 4 > buf + len - pos)
    303 			return -1;
    304 		if (pmkid == NULL) {
    305 			/* PMKID Count */
    306 			WPA_PUT_LE16(pos, 0);
    307 			pos += 2;
    308 		}
    309 
    310 		/* Management Group Cipher Suite */
    311 		switch (conf->group_mgmt_cipher) {
    312 		case WPA_CIPHER_AES_128_CMAC:
    313 			RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
    314 			break;
    315 		case WPA_CIPHER_BIP_GMAC_128:
    316 			RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128);
    317 			break;
    318 		case WPA_CIPHER_BIP_GMAC_256:
    319 			RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256);
    320 			break;
    321 		case WPA_CIPHER_BIP_CMAC_256:
    322 			RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_CMAC_256);
    323 			break;
    324 		default:
    325 			wpa_printf(MSG_DEBUG,
    326 				   "Invalid group management cipher (0x%x)",
    327 				   conf->group_mgmt_cipher);
    328 			return -1;
    329 		}
    330 		pos += RSN_SELECTOR_LEN;
    331 	}
    332 #endif /* CONFIG_IEEE80211W */
    333 
    334 #ifdef CONFIG_RSN_TESTING
    335 	if (rsn_testing) {
    336 		/*
    337 		 * Fill in any defined fields and add extra data to the end of
    338 		 * the element.
    339 		 */
    340 		int pmkid_count_set = pmkid != NULL;
    341 		if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION)
    342 			pmkid_count_set = 1;
    343 		/* PMKID Count */
    344 		WPA_PUT_LE16(pos, 0);
    345 		pos += 2;
    346 		if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
    347 			/* Management Group Cipher Suite */
    348 			RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
    349 			pos += RSN_SELECTOR_LEN;
    350 		}
    351 
    352 		os_memset(pos, 0x12, 17);
    353 		pos += 17;
    354 	}
    355 #endif /* CONFIG_RSN_TESTING */
    356 
    357 	hdr->len = (pos - buf) - 2;
    358 
    359 	return pos - buf;
    360 }
    361 
    362 
    363 static u8 * wpa_write_osen(struct wpa_auth_config *conf, u8 *eid)
    364 {
    365 	u8 *len;
    366 	u16 capab;
    367 
    368 	*eid++ = WLAN_EID_VENDOR_SPECIFIC;
    369 	len = eid++; /* to be filled */
    370 	WPA_PUT_BE24(eid, OUI_WFA);
    371 	eid += 3;
    372 	*eid++ = HS20_OSEN_OUI_TYPE;
    373 
    374 	/* Group Data Cipher Suite */
    375 	RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
    376 	eid += RSN_SELECTOR_LEN;
    377 
    378 	/* Pairwise Cipher Suite Count and List */
    379 	WPA_PUT_LE16(eid, 1);
    380 	eid += 2;
    381 	RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_CCMP);
    382 	eid += RSN_SELECTOR_LEN;
    383 
    384 	/* AKM Suite Count and List */
    385 	WPA_PUT_LE16(eid, 1);
    386 	eid += 2;
    387 	RSN_SELECTOR_PUT(eid, RSN_AUTH_KEY_MGMT_OSEN);
    388 	eid += RSN_SELECTOR_LEN;
    389 
    390 	/* RSN Capabilities */
    391 	capab = 0;
    392 	if (conf->wmm_enabled) {
    393 		/* 4 PTKSA replay counters when using WMM */
    394 		capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
    395 	}
    396 #ifdef CONFIG_IEEE80211W
    397 	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
    398 		capab |= WPA_CAPABILITY_MFPC;
    399 		if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
    400 			capab |= WPA_CAPABILITY_MFPR;
    401 	}
    402 #endif /* CONFIG_IEEE80211W */
    403 	WPA_PUT_LE16(eid, capab);
    404 	eid += 2;
    405 
    406 	*len = eid - len - 1;
    407 
    408 	return eid;
    409 }
    410 
    411 
    412 int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
    413 {
    414 	u8 *pos, buf[128];
    415 	int res;
    416 
    417 #ifdef CONFIG_TESTING_OPTIONS
    418 	if (wpa_auth->conf.own_ie_override_len) {
    419 		wpa_hexdump(MSG_DEBUG, "WPA: Forced own IE(s) for testing",
    420 			    wpa_auth->conf.own_ie_override,
    421 			    wpa_auth->conf.own_ie_override_len);
    422 		os_free(wpa_auth->wpa_ie);
    423 		wpa_auth->wpa_ie =
    424 			os_malloc(wpa_auth->conf.own_ie_override_len);
    425 		if (wpa_auth->wpa_ie == NULL)
    426 			return -1;
    427 		os_memcpy(wpa_auth->wpa_ie, wpa_auth->conf.own_ie_override,
    428 			  wpa_auth->conf.own_ie_override_len);
    429 		wpa_auth->wpa_ie_len = wpa_auth->conf.own_ie_override_len;
    430 		return 0;
    431 	}
    432 #endif /* CONFIG_TESTING_OPTIONS */
    433 
    434 	pos = buf;
    435 
    436 	if (wpa_auth->conf.wpa == WPA_PROTO_OSEN) {
    437 		pos = wpa_write_osen(&wpa_auth->conf, pos);
    438 	}
    439 	if (wpa_auth->conf.wpa & WPA_PROTO_RSN) {
    440 		res = wpa_write_rsn_ie(&wpa_auth->conf,
    441 				       pos, buf + sizeof(buf) - pos, NULL);
    442 		if (res < 0)
    443 			return res;
    444 		pos += res;
    445 	}
    446 #ifdef CONFIG_IEEE80211R_AP
    447 	if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) {
    448 		res = wpa_write_mdie(&wpa_auth->conf, pos,
    449 				     buf + sizeof(buf) - pos);
    450 		if (res < 0)
    451 			return res;
    452 		pos += res;
    453 	}
    454 #endif /* CONFIG_IEEE80211R_AP */
    455 	if (wpa_auth->conf.wpa & WPA_PROTO_WPA) {
    456 		res = wpa_write_wpa_ie(&wpa_auth->conf,
    457 				       pos, buf + sizeof(buf) - pos);
    458 		if (res < 0)
    459 			return res;
    460 		pos += res;
    461 	}
    462 
    463 	os_free(wpa_auth->wpa_ie);
    464 	wpa_auth->wpa_ie = os_malloc(pos - buf);
    465 	if (wpa_auth->wpa_ie == NULL)
    466 		return -1;
    467 	os_memcpy(wpa_auth->wpa_ie, buf, pos - buf);
    468 	wpa_auth->wpa_ie_len = pos - buf;
    469 
    470 	return 0;
    471 }
    472 
    473 
    474 u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len,
    475 		 const u8 *data2, size_t data2_len)
    476 {
    477 	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
    478 	*pos++ = RSN_SELECTOR_LEN + data_len + data2_len;
    479 	RSN_SELECTOR_PUT(pos, kde);
    480 	pos += RSN_SELECTOR_LEN;
    481 	os_memcpy(pos, data, data_len);
    482 	pos += data_len;
    483 	if (data2) {
    484 		os_memcpy(pos, data2, data2_len);
    485 		pos += data2_len;
    486 	}
    487 	return pos;
    488 }
    489 
    490 
    491 struct wpa_auth_okc_iter_data {
    492 	struct rsn_pmksa_cache_entry *pmksa;
    493 	const u8 *aa;
    494 	const u8 *spa;
    495 	const u8 *pmkid;
    496 };
    497 
    498 
    499 static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx)
    500 {
    501 	struct wpa_auth_okc_iter_data *data = ctx;
    502 	data->pmksa = pmksa_cache_get_okc(a->pmksa, data->aa, data->spa,
    503 					  data->pmkid);
    504 	if (data->pmksa)
    505 		return 1;
    506 	return 0;
    507 }
    508 
    509 
    510 int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
    511 			struct wpa_state_machine *sm,
    512 			const u8 *wpa_ie, size_t wpa_ie_len,
    513 			const u8 *mdie, size_t mdie_len,
    514 			const u8 *owe_dh, size_t owe_dh_len)
    515 {
    516 	struct wpa_ie_data data;
    517 	int ciphers, key_mgmt, res, version;
    518 	u32 selector;
    519 	size_t i;
    520 	const u8 *pmkid = NULL;
    521 
    522 	if (wpa_auth == NULL || sm == NULL)
    523 		return WPA_NOT_ENABLED;
    524 
    525 	if (wpa_ie == NULL || wpa_ie_len < 1)
    526 		return WPA_INVALID_IE;
    527 
    528 	if (wpa_ie[0] == WLAN_EID_RSN)
    529 		version = WPA_PROTO_RSN;
    530 	else
    531 		version = WPA_PROTO_WPA;
    532 
    533 	if (!(wpa_auth->conf.wpa & version)) {
    534 		wpa_printf(MSG_DEBUG, "Invalid WPA proto (%d) from " MACSTR,
    535 			   version, MAC2STR(sm->addr));
    536 		return WPA_INVALID_PROTO;
    537 	}
    538 
    539 	if (version == WPA_PROTO_RSN) {
    540 		res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
    541 
    542 		selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
    543 		if (0) {
    544 		}
    545 		else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
    546 			selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
    547 		else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
    548 			selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
    549 #ifdef CONFIG_FILS
    550 #ifdef CONFIG_IEEE80211R_AP
    551 		else if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384)
    552 			selector = RSN_AUTH_KEY_MGMT_FT_FILS_SHA384;
    553 		else if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256)
    554 			selector = RSN_AUTH_KEY_MGMT_FT_FILS_SHA256;
    555 #endif /* CONFIG_IEEE80211R_AP */
    556 		else if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA384)
    557 			selector = RSN_AUTH_KEY_MGMT_FILS_SHA384;
    558 		else if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA256)
    559 			selector = RSN_AUTH_KEY_MGMT_FILS_SHA256;
    560 #endif /* CONFIG_FILS */
    561 #ifdef CONFIG_IEEE80211R_AP
    562 		else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
    563 			selector = RSN_AUTH_KEY_MGMT_FT_802_1X;
    564 		else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK)
    565 			selector = RSN_AUTH_KEY_MGMT_FT_PSK;
    566 #endif /* CONFIG_IEEE80211R_AP */
    567 #ifdef CONFIG_IEEE80211W
    568 		else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
    569 			selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256;
    570 		else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
    571 			selector = RSN_AUTH_KEY_MGMT_PSK_SHA256;
    572 #endif /* CONFIG_IEEE80211W */
    573 #ifdef CONFIG_SAE
    574 		else if (data.key_mgmt & WPA_KEY_MGMT_SAE)
    575 			selector = RSN_AUTH_KEY_MGMT_SAE;
    576 		else if (data.key_mgmt & WPA_KEY_MGMT_FT_SAE)
    577 			selector = RSN_AUTH_KEY_MGMT_FT_SAE;
    578 #endif /* CONFIG_SAE */
    579 		else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
    580 			selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
    581 		else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
    582 			selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
    583 #ifdef CONFIG_OWE
    584 		else if (data.key_mgmt & WPA_KEY_MGMT_OWE)
    585 			selector = RSN_AUTH_KEY_MGMT_OWE;
    586 #endif /* CONFIG_OWE */
    587 #ifdef CONFIG_DPP
    588 		else if (data.key_mgmt & WPA_KEY_MGMT_DPP)
    589 			selector = RSN_AUTH_KEY_MGMT_DPP;
    590 #endif /* CONFIG_DPP */
    591 		wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
    592 
    593 		selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
    594 					       data.pairwise_cipher);
    595 		if (!selector)
    596 			selector = RSN_CIPHER_SUITE_CCMP;
    597 		wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
    598 
    599 		selector = wpa_cipher_to_suite(WPA_PROTO_RSN,
    600 					       data.group_cipher);
    601 		if (!selector)
    602 			selector = RSN_CIPHER_SUITE_CCMP;
    603 		wpa_auth->dot11RSNAGroupCipherSelected = selector;
    604 	} else {
    605 		res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data);
    606 
    607 		selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
    608 		if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
    609 			selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
    610 		else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
    611 			selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
    612 		wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector;
    613 
    614 		selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
    615 					       data.pairwise_cipher);
    616 		if (!selector)
    617 			selector = RSN_CIPHER_SUITE_TKIP;
    618 		wpa_auth->dot11RSNAPairwiseCipherSelected = selector;
    619 
    620 		selector = wpa_cipher_to_suite(WPA_PROTO_WPA,
    621 					       data.group_cipher);
    622 		if (!selector)
    623 			selector = WPA_CIPHER_SUITE_TKIP;
    624 		wpa_auth->dot11RSNAGroupCipherSelected = selector;
    625 	}
    626 	if (res) {
    627 		wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from "
    628 			   MACSTR " (res=%d)", MAC2STR(sm->addr), res);
    629 		wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len);
    630 		return WPA_INVALID_IE;
    631 	}
    632 
    633 	if (data.group_cipher != wpa_auth->conf.wpa_group) {
    634 		wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from "
    635 			   MACSTR, data.group_cipher, MAC2STR(sm->addr));
    636 		return WPA_INVALID_GROUP;
    637 	}
    638 
    639 	key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
    640 	if (!key_mgmt) {
    641 		wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from "
    642 			   MACSTR, data.key_mgmt, MAC2STR(sm->addr));
    643 		return WPA_INVALID_AKMP;
    644 	}
    645 	if (0) {
    646 	}
    647 	else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
    648 		sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
    649 	else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
    650 		sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
    651 #ifdef CONFIG_FILS
    652 #ifdef CONFIG_IEEE80211R_AP
    653 	else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384)
    654 		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA384;
    655 	else if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256)
    656 		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA256;
    657 #endif /* CONFIG_IEEE80211R_AP */
    658 	else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA384)
    659 		sm->wpa_key_mgmt = WPA_KEY_MGMT_FILS_SHA384;
    660 	else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA256)
    661 		sm->wpa_key_mgmt = WPA_KEY_MGMT_FILS_SHA256;
    662 #endif /* CONFIG_FILS */
    663 #ifdef CONFIG_IEEE80211R_AP
    664 	else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
    665 		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
    666 	else if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
    667 		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK;
    668 #endif /* CONFIG_IEEE80211R_AP */
    669 #ifdef CONFIG_IEEE80211W
    670 	else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
    671 		sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
    672 	else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
    673 		sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
    674 #endif /* CONFIG_IEEE80211W */
    675 #ifdef CONFIG_SAE
    676 	else if (key_mgmt & WPA_KEY_MGMT_SAE)
    677 		sm->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
    678 	else if (key_mgmt & WPA_KEY_MGMT_FT_SAE)
    679 		sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_SAE;
    680 #endif /* CONFIG_SAE */
    681 	else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
    682 		sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
    683 #ifdef CONFIG_OWE
    684 	else if (key_mgmt & WPA_KEY_MGMT_OWE)
    685 		sm->wpa_key_mgmt = WPA_KEY_MGMT_OWE;
    686 #endif /* CONFIG_OWE */
    687 #ifdef CONFIG_DPP
    688 	else if (key_mgmt & WPA_KEY_MGMT_DPP)
    689 		sm->wpa_key_mgmt = WPA_KEY_MGMT_DPP;
    690 #endif /* CONFIG_DPP */
    691 	else
    692 		sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
    693 
    694 	if (version == WPA_PROTO_RSN)
    695 		ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise;
    696 	else
    697 		ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise;
    698 	if (!ciphers) {
    699 		wpa_printf(MSG_DEBUG, "Invalid %s pairwise cipher (0x%x) "
    700 			   "from " MACSTR,
    701 			   version == WPA_PROTO_RSN ? "RSN" : "WPA",
    702 			   data.pairwise_cipher, MAC2STR(sm->addr));
    703 		return WPA_INVALID_PAIRWISE;
    704 	}
    705 
    706 #ifdef CONFIG_IEEE80211W
    707 	if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
    708 		if (!(data.capabilities & WPA_CAPABILITY_MFPC)) {
    709 			wpa_printf(MSG_DEBUG, "Management frame protection "
    710 				   "required, but client did not enable it");
    711 			return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
    712 		}
    713 
    714 		if (ciphers & WPA_CIPHER_TKIP) {
    715 			wpa_printf(MSG_DEBUG, "Management frame protection "
    716 				   "cannot use TKIP");
    717 			return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
    718 		}
    719 
    720 		if (data.mgmt_group_cipher != wpa_auth->conf.group_mgmt_cipher)
    721 		{
    722 			wpa_printf(MSG_DEBUG, "Unsupported management group "
    723 				   "cipher %d", data.mgmt_group_cipher);
    724 			return WPA_INVALID_MGMT_GROUP_CIPHER;
    725 		}
    726 	}
    727 
    728 	if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION ||
    729 	    !(data.capabilities & WPA_CAPABILITY_MFPC))
    730 		sm->mgmt_frame_prot = 0;
    731 	else
    732 		sm->mgmt_frame_prot = 1;
    733 #endif /* CONFIG_IEEE80211W */
    734 
    735 #ifdef CONFIG_IEEE80211R_AP
    736 	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
    737 		if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) {
    738 			wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but "
    739 				   "MDIE not included");
    740 			return WPA_INVALID_MDIE;
    741 		}
    742 		if (os_memcmp(mdie, wpa_auth->conf.mobility_domain,
    743 			      MOBILITY_DOMAIN_ID_LEN) != 0) {
    744 			wpa_hexdump(MSG_DEBUG, "RSN: Attempted to use unknown "
    745 				    "MDIE", mdie, MOBILITY_DOMAIN_ID_LEN);
    746 			return WPA_INVALID_MDIE;
    747 		}
    748 	} else if (mdie != NULL) {
    749 		wpa_printf(MSG_DEBUG,
    750 			   "RSN: Trying to use non-FT AKM suite, but MDIE included");
    751 		return WPA_INVALID_AKMP;
    752 	}
    753 #endif /* CONFIG_IEEE80211R_AP */
    754 
    755 #ifdef CONFIG_OWE
    756 	if (sm->wpa_key_mgmt == WPA_KEY_MGMT_OWE && !owe_dh) {
    757 		wpa_printf(MSG_DEBUG,
    758 			   "OWE: No Diffie-Hellman Parameter element");
    759 		return WPA_INVALID_AKMP;
    760 	}
    761 	if (sm->wpa_key_mgmt != WPA_KEY_MGMT_OWE && owe_dh) {
    762 		wpa_printf(MSG_DEBUG,
    763 			   "OWE: Unexpected Diffie-Hellman Parameter element with non-OWE AKM");
    764 		return WPA_INVALID_AKMP;
    765 	}
    766 #endif /* CONFIG_OWE */
    767 
    768 	sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
    769 	if (sm->pairwise < 0)
    770 		return WPA_INVALID_PAIRWISE;
    771 
    772 	/* TODO: clear WPA/WPA2 state if STA changes from one to another */
    773 	if (wpa_ie[0] == WLAN_EID_RSN)
    774 		sm->wpa = WPA_VERSION_WPA2;
    775 	else
    776 		sm->wpa = WPA_VERSION_WPA;
    777 
    778 	sm->pmksa = NULL;
    779 	for (i = 0; i < data.num_pmkid; i++) {
    780 		wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID",
    781 			    &data.pmkid[i * PMKID_LEN], PMKID_LEN);
    782 		sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr,
    783 						 &data.pmkid[i * PMKID_LEN]);
    784 		if (sm->pmksa) {
    785 			pmkid = sm->pmksa->pmkid;
    786 			break;
    787 		}
    788 	}
    789 	for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc &&
    790 		     i < data.num_pmkid; i++) {
    791 		struct wpa_auth_okc_iter_data idata;
    792 		idata.pmksa = NULL;
    793 		idata.aa = wpa_auth->addr;
    794 		idata.spa = sm->addr;
    795 		idata.pmkid = &data.pmkid[i * PMKID_LEN];
    796 		wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata);
    797 		if (idata.pmksa) {
    798 			wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
    799 					 "OKC match for PMKID");
    800 			sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa,
    801 							idata.pmksa,
    802 							wpa_auth->addr,
    803 							idata.pmkid);
    804 			pmkid = idata.pmkid;
    805 			break;
    806 		}
    807 	}
    808 	if (sm->pmksa && pmkid) {
    809 		struct vlan_description *vlan;
    810 
    811 		vlan = sm->pmksa->vlan_desc;
    812 		wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
    813 				 "PMKID found from PMKSA cache eap_type=%d vlan=%d%s",
    814 				 sm->pmksa->eap_type_authsrv,
    815 				 vlan ? vlan->untagged : 0,
    816 				 (vlan && vlan->tagged[0]) ? "+" : "");
    817 		os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
    818 	}
    819 
    820 #ifdef CONFIG_DPP
    821 	if (sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP && !sm->pmksa) {
    822 		wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
    823 				 "No PMKSA cache entry found for DPP");
    824 		return WPA_INVALID_PMKID;
    825 	}
    826 #endif /* CONFIG_DPP */
    827 
    828 	if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
    829 		os_free(sm->wpa_ie);
    830 		sm->wpa_ie = os_malloc(wpa_ie_len);
    831 		if (sm->wpa_ie == NULL)
    832 			return WPA_ALLOC_FAIL;
    833 	}
    834 	os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len);
    835 	sm->wpa_ie_len = wpa_ie_len;
    836 
    837 	return WPA_IE_OK;
    838 }
    839 
    840 
    841 #ifdef CONFIG_HS20
    842 int wpa_validate_osen(struct wpa_authenticator *wpa_auth,
    843 		      struct wpa_state_machine *sm,
    844 		      const u8 *osen_ie, size_t osen_ie_len)
    845 {
    846 	if (wpa_auth == NULL || sm == NULL)
    847 		return -1;
    848 
    849 	/* TODO: parse OSEN element */
    850 	sm->wpa_key_mgmt = WPA_KEY_MGMT_OSEN;
    851 	sm->mgmt_frame_prot = 1;
    852 	sm->pairwise = WPA_CIPHER_CCMP;
    853 	sm->wpa = WPA_VERSION_WPA2;
    854 
    855 	if (sm->wpa_ie == NULL || sm->wpa_ie_len < osen_ie_len) {
    856 		os_free(sm->wpa_ie);
    857 		sm->wpa_ie = os_malloc(osen_ie_len);
    858 		if (sm->wpa_ie == NULL)
    859 			return -1;
    860 	}
    861 
    862 	os_memcpy(sm->wpa_ie, osen_ie, osen_ie_len);
    863 	sm->wpa_ie_len = osen_ie_len;
    864 
    865 	return 0;
    866 }
    867 
    868 #endif /* CONFIG_HS20 */
    869 
    870 
    871 /**
    872  * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
    873  * @pos: Pointer to the IE header
    874  * @end: Pointer to the end of the Key Data buffer
    875  * @ie: Pointer to parsed IE data
    876  * Returns: 0 on success, 1 if end mark is found, -1 on failure
    877  */
    878 static int wpa_parse_generic(const u8 *pos, const u8 *end,
    879 			     struct wpa_eapol_ie_parse *ie)
    880 {
    881 	if (pos[1] == 0)
    882 		return 1;
    883 
    884 	if (pos[1] >= 6 &&
    885 	    RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
    886 	    pos[2 + WPA_SELECTOR_LEN] == 1 &&
    887 	    pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
    888 		ie->wpa_ie = pos;
    889 		ie->wpa_ie_len = pos[1] + 2;
    890 		return 0;
    891 	}
    892 
    893 	if (pos[1] >= 4 && WPA_GET_BE32(pos + 2) == OSEN_IE_VENDOR_TYPE) {
    894 		ie->osen = pos;
    895 		ie->osen_len = pos[1] + 2;
    896 		return 0;
    897 	}
    898 
    899 	if (1 + RSN_SELECTOR_LEN < end - pos &&
    900 	    pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
    901 	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
    902 		ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
    903 		return 0;
    904 	}
    905 
    906 	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
    907 	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
    908 		ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
    909 		ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
    910 		return 0;
    911 	}
    912 
    913 	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
    914 	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
    915 		ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
    916 		ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
    917 		return 0;
    918 	}
    919 
    920 #ifdef CONFIG_IEEE80211W
    921 	if (pos[1] > RSN_SELECTOR_LEN + 2 &&
    922 	    RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
    923 		ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
    924 		ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
    925 		return 0;
    926 	}
    927 #endif /* CONFIG_IEEE80211W */
    928 
    929 #ifdef CONFIG_P2P
    930 	if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
    931 	    RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
    932 		ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
    933 		wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
    934 			    ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
    935 		return 0;
    936 	}
    937 
    938 	if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
    939 	    RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
    940 		ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
    941 		wpa_hexdump(MSG_DEBUG,
    942 			    "WPA: IP Address Allocation in EAPOL-Key",
    943 			    ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
    944 		return 0;
    945 	}
    946 #endif /* CONFIG_P2P */
    947 
    948 	return 0;
    949 }
    950 
    951 
    952 /**
    953  * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
    954  * @buf: Pointer to the Key Data buffer
    955  * @len: Key Data Length
    956  * @ie: Pointer to parsed IE data
    957  * Returns: 0 on success, -1 on failure
    958  */
    959 int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
    960 {
    961 	const u8 *pos, *end;
    962 	int ret = 0;
    963 
    964 	os_memset(ie, 0, sizeof(*ie));
    965 	for (pos = buf, end = pos + len; end - pos > 1; pos += 2 + pos[1]) {
    966 		if (pos[0] == 0xdd &&
    967 		    ((pos == buf + len - 1) || pos[1] == 0)) {
    968 			/* Ignore padding */
    969 			break;
    970 		}
    971 		if (2 + pos[1] > end - pos) {
    972 			wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
    973 				   "underflow (ie=%d len=%d pos=%d)",
    974 				   pos[0], pos[1], (int) (pos - buf));
    975 			wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
    976 					buf, len);
    977 			ret = -1;
    978 			break;
    979 		}
    980 		if (*pos == WLAN_EID_RSN) {
    981 			ie->rsn_ie = pos;
    982 			ie->rsn_ie_len = pos[1] + 2;
    983 #ifdef CONFIG_IEEE80211R_AP
    984 		} else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
    985 			ie->mdie = pos;
    986 			ie->mdie_len = pos[1] + 2;
    987 		} else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
    988 			ie->ftie = pos;
    989 			ie->ftie_len = pos[1] + 2;
    990 #endif /* CONFIG_IEEE80211R_AP */
    991 		} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
    992 			ret = wpa_parse_generic(pos, end, ie);
    993 			if (ret < 0)
    994 				break;
    995 			if (ret > 0) {
    996 				ret = 0;
    997 				break;
    998 			}
    999 		} else {
   1000 			wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
   1001 				    "Key Data IE", pos, 2 + pos[1]);
   1002 		}
   1003 	}
   1004 
   1005 	return ret;
   1006 }
   1007 
   1008 
   1009 int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
   1010 {
   1011 	return sm ? sm->mgmt_frame_prot : 0;
   1012 }
   1013 
   1014 
   1015 #ifdef CONFIG_OWE
   1016 u8 * wpa_auth_write_assoc_resp_owe(struct wpa_state_machine *sm,
   1017 				   u8 *pos, size_t max_len,
   1018 				   const u8 *req_ies, size_t req_ies_len)
   1019 {
   1020 	int res;
   1021 
   1022 	res = wpa_write_rsn_ie(&sm->wpa_auth->conf, pos, max_len,
   1023 			       sm->pmksa ? sm->pmksa->pmkid : NULL);
   1024 	if (res < 0)
   1025 		return pos;
   1026 	return pos + res;
   1027 }
   1028 #endif /* CONFIG_OWE */
   1029