xref: /freebsd/contrib/wpa/src/common/wpa_common.c (revision f4b37ed0f8b307b1f3f0f630ca725d68f1dff30d)
1 /*
2  * WPA/RSN - Shared functions for supplicant and authenticator
3  * Copyright (c) 2002-2015, 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 "includes.h"
10 
11 #include "common.h"
12 #include "crypto/md5.h"
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
15 #include "crypto/sha384.h"
16 #include "crypto/aes_wrap.h"
17 #include "crypto/crypto.h"
18 #include "ieee802_11_defs.h"
19 #include "defs.h"
20 #include "wpa_common.h"
21 
22 
23 static unsigned int wpa_kck_len(int akmp)
24 {
25 	if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
26 		return 24;
27 	return 16;
28 }
29 
30 
31 static unsigned int wpa_kek_len(int akmp)
32 {
33 	if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
34 		return 32;
35 	return 16;
36 }
37 
38 
39 unsigned int wpa_mic_len(int akmp)
40 {
41 	if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
42 		return 24;
43 	return 16;
44 }
45 
46 
47 /**
48  * wpa_eapol_key_mic - Calculate EAPOL-Key MIC
49  * @key: EAPOL-Key Key Confirmation Key (KCK)
50  * @key_len: KCK length in octets
51  * @akmp: WPA_KEY_MGMT_* used in key derivation
52  * @ver: Key descriptor version (WPA_KEY_INFO_TYPE_*)
53  * @buf: Pointer to the beginning of the EAPOL header (version field)
54  * @len: Length of the EAPOL frame (from EAPOL header to the end of the frame)
55  * @mic: Pointer to the buffer to which the EAPOL-Key MIC is written
56  * Returns: 0 on success, -1 on failure
57  *
58  * Calculate EAPOL-Key MIC for an EAPOL-Key packet. The EAPOL-Key MIC field has
59  * to be cleared (all zeroes) when calling this function.
60  *
61  * Note: 'IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames' has an error in the
62  * description of the Key MIC calculation. It includes packet data from the
63  * beginning of the EAPOL-Key header, not EAPOL header. This incorrect change
64  * happened during final editing of the standard and the correct behavior is
65  * defined in the last draft (IEEE 802.11i/D10).
66  */
67 int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
68 		      const u8 *buf, size_t len, u8 *mic)
69 {
70 	u8 hash[SHA384_MAC_LEN];
71 
72 	switch (ver) {
73 #ifndef CONFIG_FIPS
74 	case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
75 		return hmac_md5(key, key_len, buf, len, mic);
76 #endif /* CONFIG_FIPS */
77 	case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
78 		if (hmac_sha1(key, key_len, buf, len, hash))
79 			return -1;
80 		os_memcpy(mic, hash, MD5_MAC_LEN);
81 		break;
82 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
83 	case WPA_KEY_INFO_TYPE_AES_128_CMAC:
84 		return omac1_aes_128(key, buf, len, mic);
85 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
86 	case WPA_KEY_INFO_TYPE_AKM_DEFINED:
87 		switch (akmp) {
88 #ifdef CONFIG_HS20
89 		case WPA_KEY_MGMT_OSEN:
90 			return omac1_aes_128(key, buf, len, mic);
91 #endif /* CONFIG_HS20 */
92 #ifdef CONFIG_SUITEB
93 		case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
94 			if (hmac_sha256(key, key_len, buf, len, hash))
95 				return -1;
96 			os_memcpy(mic, hash, MD5_MAC_LEN);
97 			break;
98 #endif /* CONFIG_SUITEB */
99 #ifdef CONFIG_SUITEB192
100 		case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
101 			if (hmac_sha384(key, key_len, buf, len, hash))
102 				return -1;
103 			os_memcpy(mic, hash, 24);
104 			break;
105 #endif /* CONFIG_SUITEB192 */
106 		default:
107 			return -1;
108 		}
109 		break;
110 	default:
111 		return -1;
112 	}
113 
114 	return 0;
115 }
116 
117 
118 /**
119  * wpa_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces
120  * @pmk: Pairwise master key
121  * @pmk_len: Length of PMK
122  * @label: Label to use in derivation
123  * @addr1: AA or SA
124  * @addr2: SA or AA
125  * @nonce1: ANonce or SNonce
126  * @nonce2: SNonce or ANonce
127  * @ptk: Buffer for pairwise transient key
128  * @akmp: Negotiated AKM
129  * @cipher: Negotiated pairwise cipher
130  * Returns: 0 on success, -1 on failure
131  *
132  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
133  * PTK = PRF-X(PMK, "Pairwise key expansion",
134  *             Min(AA, SA) || Max(AA, SA) ||
135  *             Min(ANonce, SNonce) || Max(ANonce, SNonce))
136  *
137  * STK = PRF-X(SMK, "Peer key expansion",
138  *             Min(MAC_I, MAC_P) || Max(MAC_I, MAC_P) ||
139  *             Min(INonce, PNonce) || Max(INonce, PNonce))
140  */
141 int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
142 		   const u8 *addr1, const u8 *addr2,
143 		   const u8 *nonce1, const u8 *nonce2,
144 		   struct wpa_ptk *ptk, int akmp, int cipher)
145 {
146 	u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
147 	u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
148 	size_t ptk_len;
149 
150 	if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
151 		os_memcpy(data, addr1, ETH_ALEN);
152 		os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
153 	} else {
154 		os_memcpy(data, addr2, ETH_ALEN);
155 		os_memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
156 	}
157 
158 	if (os_memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
159 		os_memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
160 		os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
161 			  WPA_NONCE_LEN);
162 	} else {
163 		os_memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
164 		os_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
165 			  WPA_NONCE_LEN);
166 	}
167 
168 	ptk->kck_len = wpa_kck_len(akmp);
169 	ptk->kek_len = wpa_kek_len(akmp);
170 	ptk->tk_len = wpa_cipher_key_len(cipher);
171 	ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
172 
173 #ifdef CONFIG_IEEE80211W
174 	if (wpa_key_mgmt_sha256(akmp))
175 		sha256_prf(pmk, pmk_len, label, data, sizeof(data),
176 			   tmp, ptk_len);
177 	else
178 #endif /* CONFIG_IEEE80211W */
179 		sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp, ptk_len);
180 
181 	wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
182 		   MAC2STR(addr1), MAC2STR(addr2));
183 	wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
184 	wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
185 	wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
186 	wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
187 
188 	os_memcpy(ptk->kck, tmp, ptk->kck_len);
189 	wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
190 
191 	os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
192 	wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
193 
194 	os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
195 	wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
196 
197 	os_memset(tmp, 0, sizeof(tmp));
198 	return 0;
199 }
200 
201 
202 #ifdef CONFIG_IEEE80211R
203 int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
204 	       const u8 *ap_addr, u8 transaction_seqnum,
205 	       const u8 *mdie, size_t mdie_len,
206 	       const u8 *ftie, size_t ftie_len,
207 	       const u8 *rsnie, size_t rsnie_len,
208 	       const u8 *ric, size_t ric_len, u8 *mic)
209 {
210 	u8 *buf, *pos;
211 	size_t buf_len;
212 
213 	if (kck_len != 16) {
214 		wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u",
215 			   (unsigned int) kck_len);
216 		return -1;
217 	}
218 
219 	buf_len = 2 * ETH_ALEN + 1 + mdie_len + ftie_len + rsnie_len + ric_len;
220 	buf = os_malloc(buf_len);
221 	if (buf == NULL)
222 		return -1;
223 
224 	pos = buf;
225 	os_memcpy(pos, sta_addr, ETH_ALEN);
226 	pos += ETH_ALEN;
227 	os_memcpy(pos, ap_addr, ETH_ALEN);
228 	pos += ETH_ALEN;
229 	*pos++ = transaction_seqnum;
230 	if (rsnie) {
231 		os_memcpy(pos, rsnie, rsnie_len);
232 		pos += rsnie_len;
233 	}
234 	if (mdie) {
235 		os_memcpy(pos, mdie, mdie_len);
236 		pos += mdie_len;
237 	}
238 	if (ftie) {
239 		struct rsn_ftie *_ftie;
240 		os_memcpy(pos, ftie, ftie_len);
241 		if (ftie_len < 2 + sizeof(*_ftie)) {
242 			os_free(buf);
243 			return -1;
244 		}
245 		_ftie = (struct rsn_ftie *) (pos + 2);
246 		os_memset(_ftie->mic, 0, sizeof(_ftie->mic));
247 		pos += ftie_len;
248 	}
249 	if (ric) {
250 		os_memcpy(pos, ric, ric_len);
251 		pos += ric_len;
252 	}
253 
254 	wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", buf, pos - buf);
255 	if (omac1_aes_128(kck, buf, pos - buf, mic)) {
256 		os_free(buf);
257 		return -1;
258 	}
259 
260 	os_free(buf);
261 
262 	return 0;
263 }
264 
265 
266 static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
267 			     struct wpa_ft_ies *parse)
268 {
269 	const u8 *end, *pos;
270 
271 	parse->ftie = ie;
272 	parse->ftie_len = ie_len;
273 
274 	pos = ie + sizeof(struct rsn_ftie);
275 	end = ie + ie_len;
276 
277 	while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
278 		switch (pos[0]) {
279 		case FTIE_SUBELEM_R1KH_ID:
280 			if (pos[1] != FT_R1KH_ID_LEN) {
281 				wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
282 					   "length in FTIE: %d", pos[1]);
283 				return -1;
284 			}
285 			parse->r1kh_id = pos + 2;
286 			break;
287 		case FTIE_SUBELEM_GTK:
288 			parse->gtk = pos + 2;
289 			parse->gtk_len = pos[1];
290 			break;
291 		case FTIE_SUBELEM_R0KH_ID:
292 			if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
293 				wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
294 					   "length in FTIE: %d", pos[1]);
295 				return -1;
296 			}
297 			parse->r0kh_id = pos + 2;
298 			parse->r0kh_id_len = pos[1];
299 			break;
300 #ifdef CONFIG_IEEE80211W
301 		case FTIE_SUBELEM_IGTK:
302 			parse->igtk = pos + 2;
303 			parse->igtk_len = pos[1];
304 			break;
305 #endif /* CONFIG_IEEE80211W */
306 		}
307 
308 		pos += 2 + pos[1];
309 	}
310 
311 	return 0;
312 }
313 
314 
315 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
316 		     struct wpa_ft_ies *parse)
317 {
318 	const u8 *end, *pos;
319 	struct wpa_ie_data data;
320 	int ret;
321 	const struct rsn_ftie *ftie;
322 	int prot_ie_count = 0;
323 
324 	os_memset(parse, 0, sizeof(*parse));
325 	if (ies == NULL)
326 		return 0;
327 
328 	pos = ies;
329 	end = ies + ies_len;
330 	while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
331 		switch (pos[0]) {
332 		case WLAN_EID_RSN:
333 			parse->rsn = pos + 2;
334 			parse->rsn_len = pos[1];
335 			ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
336 						   parse->rsn_len + 2,
337 						   &data);
338 			if (ret < 0) {
339 				wpa_printf(MSG_DEBUG, "FT: Failed to parse "
340 					   "RSN IE: %d", ret);
341 				return -1;
342 			}
343 			if (data.num_pmkid == 1 && data.pmkid)
344 				parse->rsn_pmkid = data.pmkid;
345 			break;
346 		case WLAN_EID_MOBILITY_DOMAIN:
347 			parse->mdie = pos + 2;
348 			parse->mdie_len = pos[1];
349 			break;
350 		case WLAN_EID_FAST_BSS_TRANSITION:
351 			if (pos[1] < sizeof(*ftie))
352 				return -1;
353 			ftie = (const struct rsn_ftie *) (pos + 2);
354 			prot_ie_count = ftie->mic_control[1];
355 			if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
356 				return -1;
357 			break;
358 		case WLAN_EID_TIMEOUT_INTERVAL:
359 			parse->tie = pos + 2;
360 			parse->tie_len = pos[1];
361 			break;
362 		case WLAN_EID_RIC_DATA:
363 			if (parse->ric == NULL)
364 				parse->ric = pos;
365 			break;
366 		}
367 
368 		pos += 2 + pos[1];
369 	}
370 
371 	if (prot_ie_count == 0)
372 		return 0; /* no MIC */
373 
374 	/*
375 	 * Check that the protected IE count matches with IEs included in the
376 	 * frame.
377 	 */
378 	if (parse->rsn)
379 		prot_ie_count--;
380 	if (parse->mdie)
381 		prot_ie_count--;
382 	if (parse->ftie)
383 		prot_ie_count--;
384 	if (prot_ie_count < 0) {
385 		wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
386 			   "the protected IE count");
387 		return -1;
388 	}
389 
390 	if (prot_ie_count == 0 && parse->ric) {
391 		wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
392 			   "included in protected IE count");
393 		return -1;
394 	}
395 
396 	/* Determine the end of the RIC IE(s) */
397 	pos = parse->ric;
398 	while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
399 	       prot_ie_count) {
400 		prot_ie_count--;
401 		pos += 2 + pos[1];
402 	}
403 	parse->ric_len = pos - parse->ric;
404 	if (prot_ie_count) {
405 		wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
406 			   "frame", (int) prot_ie_count);
407 		return -1;
408 	}
409 
410 	return 0;
411 }
412 #endif /* CONFIG_IEEE80211R */
413 
414 
415 static int rsn_selector_to_bitfield(const u8 *s)
416 {
417 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
418 		return WPA_CIPHER_NONE;
419 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP40)
420 		return WPA_CIPHER_WEP40;
421 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_TKIP)
422 		return WPA_CIPHER_TKIP;
423 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP)
424 		return WPA_CIPHER_CCMP;
425 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_WEP104)
426 		return WPA_CIPHER_WEP104;
427 #ifdef CONFIG_IEEE80211W
428 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_AES_128_CMAC)
429 		return WPA_CIPHER_AES_128_CMAC;
430 #endif /* CONFIG_IEEE80211W */
431 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP)
432 		return WPA_CIPHER_GCMP;
433 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_CCMP_256)
434 		return WPA_CIPHER_CCMP_256;
435 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_GCMP_256)
436 		return WPA_CIPHER_GCMP_256;
437 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_128)
438 		return WPA_CIPHER_BIP_GMAC_128;
439 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_GMAC_256)
440 		return WPA_CIPHER_BIP_GMAC_256;
441 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_BIP_CMAC_256)
442 		return WPA_CIPHER_BIP_CMAC_256;
443 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED)
444 		return WPA_CIPHER_GTK_NOT_USED;
445 	return 0;
446 }
447 
448 
449 static int rsn_key_mgmt_to_bitfield(const u8 *s)
450 {
451 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_UNSPEC_802_1X)
452 		return WPA_KEY_MGMT_IEEE8021X;
453 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X)
454 		return WPA_KEY_MGMT_PSK;
455 #ifdef CONFIG_IEEE80211R
456 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_802_1X)
457 		return WPA_KEY_MGMT_FT_IEEE8021X;
458 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
459 		return WPA_KEY_MGMT_FT_PSK;
460 #endif /* CONFIG_IEEE80211R */
461 #ifdef CONFIG_IEEE80211W
462 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
463 		return WPA_KEY_MGMT_IEEE8021X_SHA256;
464 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
465 		return WPA_KEY_MGMT_PSK_SHA256;
466 #endif /* CONFIG_IEEE80211W */
467 #ifdef CONFIG_SAE
468 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
469 		return WPA_KEY_MGMT_SAE;
470 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_SAE)
471 		return WPA_KEY_MGMT_FT_SAE;
472 #endif /* CONFIG_SAE */
473 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
474 		return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
475 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
476 		return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
477 	return 0;
478 }
479 
480 
481 static int wpa_cipher_valid_group(int cipher)
482 {
483 	return wpa_cipher_valid_pairwise(cipher) ||
484 		cipher == WPA_CIPHER_WEP104 ||
485 		cipher == WPA_CIPHER_WEP40 ||
486 		cipher == WPA_CIPHER_GTK_NOT_USED;
487 }
488 
489 
490 #ifdef CONFIG_IEEE80211W
491 int wpa_cipher_valid_mgmt_group(int cipher)
492 {
493 	return cipher == WPA_CIPHER_AES_128_CMAC ||
494 		cipher == WPA_CIPHER_BIP_GMAC_128 ||
495 		cipher == WPA_CIPHER_BIP_GMAC_256 ||
496 		cipher == WPA_CIPHER_BIP_CMAC_256;
497 }
498 #endif /* CONFIG_IEEE80211W */
499 
500 
501 /**
502  * wpa_parse_wpa_ie_rsn - Parse RSN IE
503  * @rsn_ie: Buffer containing RSN IE
504  * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
505  * @data: Pointer to structure that will be filled in with parsed data
506  * Returns: 0 on success, <0 on failure
507  */
508 int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
509 			 struct wpa_ie_data *data)
510 {
511 	const struct rsn_ie_hdr *hdr;
512 	const u8 *pos;
513 	int left;
514 	int i, count;
515 
516 	os_memset(data, 0, sizeof(*data));
517 	data->proto = WPA_PROTO_RSN;
518 	data->pairwise_cipher = WPA_CIPHER_CCMP;
519 	data->group_cipher = WPA_CIPHER_CCMP;
520 	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
521 	data->capabilities = 0;
522 	data->pmkid = NULL;
523 	data->num_pmkid = 0;
524 #ifdef CONFIG_IEEE80211W
525 	data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
526 #else /* CONFIG_IEEE80211W */
527 	data->mgmt_group_cipher = 0;
528 #endif /* CONFIG_IEEE80211W */
529 
530 	if (rsn_ie_len == 0) {
531 		/* No RSN IE - fail silently */
532 		return -1;
533 	}
534 
535 	if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
536 		wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
537 			   __func__, (unsigned long) rsn_ie_len);
538 		return -1;
539 	}
540 
541 	hdr = (const struct rsn_ie_hdr *) rsn_ie;
542 
543 	if (hdr->elem_id != WLAN_EID_RSN ||
544 	    hdr->len != rsn_ie_len - 2 ||
545 	    WPA_GET_LE16(hdr->version) != RSN_VERSION) {
546 		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
547 			   __func__);
548 		return -2;
549 	}
550 
551 	pos = (const u8 *) (hdr + 1);
552 	left = rsn_ie_len - sizeof(*hdr);
553 
554 	if (left >= RSN_SELECTOR_LEN) {
555 		data->group_cipher = rsn_selector_to_bitfield(pos);
556 		if (!wpa_cipher_valid_group(data->group_cipher)) {
557 			wpa_printf(MSG_DEBUG, "%s: invalid group cipher 0x%x",
558 				   __func__, data->group_cipher);
559 			return -1;
560 		}
561 		pos += RSN_SELECTOR_LEN;
562 		left -= RSN_SELECTOR_LEN;
563 	} else if (left > 0) {
564 		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
565 			   __func__, left);
566 		return -3;
567 	}
568 
569 	if (left >= 2) {
570 		data->pairwise_cipher = 0;
571 		count = WPA_GET_LE16(pos);
572 		pos += 2;
573 		left -= 2;
574 		if (count == 0 || count > left / RSN_SELECTOR_LEN) {
575 			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
576 				   "count %u left %u", __func__, count, left);
577 			return -4;
578 		}
579 		for (i = 0; i < count; i++) {
580 			data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
581 			pos += RSN_SELECTOR_LEN;
582 			left -= RSN_SELECTOR_LEN;
583 		}
584 #ifdef CONFIG_IEEE80211W
585 		if (data->pairwise_cipher & WPA_CIPHER_AES_128_CMAC) {
586 			wpa_printf(MSG_DEBUG, "%s: AES-128-CMAC used as "
587 				   "pairwise cipher", __func__);
588 			return -1;
589 		}
590 #endif /* CONFIG_IEEE80211W */
591 	} else if (left == 1) {
592 		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
593 			   __func__);
594 		return -5;
595 	}
596 
597 	if (left >= 2) {
598 		data->key_mgmt = 0;
599 		count = WPA_GET_LE16(pos);
600 		pos += 2;
601 		left -= 2;
602 		if (count == 0 || count > left / RSN_SELECTOR_LEN) {
603 			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
604 				   "count %u left %u", __func__, count, left);
605 			return -6;
606 		}
607 		for (i = 0; i < count; i++) {
608 			data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
609 			pos += RSN_SELECTOR_LEN;
610 			left -= RSN_SELECTOR_LEN;
611 		}
612 	} else if (left == 1) {
613 		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
614 			   __func__);
615 		return -7;
616 	}
617 
618 	if (left >= 2) {
619 		data->capabilities = WPA_GET_LE16(pos);
620 		pos += 2;
621 		left -= 2;
622 	}
623 
624 	if (left >= 2) {
625 		u16 num_pmkid = WPA_GET_LE16(pos);
626 		pos += 2;
627 		left -= 2;
628 		if (num_pmkid > (unsigned int) left / PMKID_LEN) {
629 			wpa_printf(MSG_DEBUG, "%s: PMKID underflow "
630 				   "(num_pmkid=%u left=%d)",
631 				   __func__, num_pmkid, left);
632 			data->num_pmkid = 0;
633 			return -9;
634 		} else {
635 			data->num_pmkid = num_pmkid;
636 			data->pmkid = pos;
637 			pos += data->num_pmkid * PMKID_LEN;
638 			left -= data->num_pmkid * PMKID_LEN;
639 		}
640 	}
641 
642 #ifdef CONFIG_IEEE80211W
643 	if (left >= 4) {
644 		data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
645 		if (!wpa_cipher_valid_mgmt_group(data->mgmt_group_cipher)) {
646 			wpa_printf(MSG_DEBUG, "%s: Unsupported management "
647 				   "group cipher 0x%x", __func__,
648 				   data->mgmt_group_cipher);
649 			return -10;
650 		}
651 		pos += RSN_SELECTOR_LEN;
652 		left -= RSN_SELECTOR_LEN;
653 	}
654 #endif /* CONFIG_IEEE80211W */
655 
656 	if (left > 0) {
657 		wpa_hexdump(MSG_DEBUG,
658 			    "wpa_parse_wpa_ie_rsn: ignore trailing bytes",
659 			    pos, left);
660 	}
661 
662 	return 0;
663 }
664 
665 
666 static int wpa_selector_to_bitfield(const u8 *s)
667 {
668 	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
669 		return WPA_CIPHER_NONE;
670 	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
671 		return WPA_CIPHER_WEP40;
672 	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
673 		return WPA_CIPHER_TKIP;
674 	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
675 		return WPA_CIPHER_CCMP;
676 	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
677 		return WPA_CIPHER_WEP104;
678 	return 0;
679 }
680 
681 
682 static int wpa_key_mgmt_to_bitfield(const u8 *s)
683 {
684 	if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
685 		return WPA_KEY_MGMT_IEEE8021X;
686 	if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
687 		return WPA_KEY_MGMT_PSK;
688 	if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
689 		return WPA_KEY_MGMT_WPA_NONE;
690 	return 0;
691 }
692 
693 
694 int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
695 			 struct wpa_ie_data *data)
696 {
697 	const struct wpa_ie_hdr *hdr;
698 	const u8 *pos;
699 	int left;
700 	int i, count;
701 
702 	os_memset(data, 0, sizeof(*data));
703 	data->proto = WPA_PROTO_WPA;
704 	data->pairwise_cipher = WPA_CIPHER_TKIP;
705 	data->group_cipher = WPA_CIPHER_TKIP;
706 	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
707 	data->capabilities = 0;
708 	data->pmkid = NULL;
709 	data->num_pmkid = 0;
710 	data->mgmt_group_cipher = 0;
711 
712 	if (wpa_ie_len == 0) {
713 		/* No WPA IE - fail silently */
714 		return -1;
715 	}
716 
717 	if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
718 		wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",
719 			   __func__, (unsigned long) wpa_ie_len);
720 		return -1;
721 	}
722 
723 	hdr = (const struct wpa_ie_hdr *) wpa_ie;
724 
725 	if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
726 	    hdr->len != wpa_ie_len - 2 ||
727 	    RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
728 	    WPA_GET_LE16(hdr->version) != WPA_VERSION) {
729 		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
730 			   __func__);
731 		return -2;
732 	}
733 
734 	pos = (const u8 *) (hdr + 1);
735 	left = wpa_ie_len - sizeof(*hdr);
736 
737 	if (left >= WPA_SELECTOR_LEN) {
738 		data->group_cipher = wpa_selector_to_bitfield(pos);
739 		pos += WPA_SELECTOR_LEN;
740 		left -= WPA_SELECTOR_LEN;
741 	} else if (left > 0) {
742 		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
743 			   __func__, left);
744 		return -3;
745 	}
746 
747 	if (left >= 2) {
748 		data->pairwise_cipher = 0;
749 		count = WPA_GET_LE16(pos);
750 		pos += 2;
751 		left -= 2;
752 		if (count == 0 || count > left / WPA_SELECTOR_LEN) {
753 			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
754 				   "count %u left %u", __func__, count, left);
755 			return -4;
756 		}
757 		for (i = 0; i < count; i++) {
758 			data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
759 			pos += WPA_SELECTOR_LEN;
760 			left -= WPA_SELECTOR_LEN;
761 		}
762 	} else if (left == 1) {
763 		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
764 			   __func__);
765 		return -5;
766 	}
767 
768 	if (left >= 2) {
769 		data->key_mgmt = 0;
770 		count = WPA_GET_LE16(pos);
771 		pos += 2;
772 		left -= 2;
773 		if (count == 0 || count > left / WPA_SELECTOR_LEN) {
774 			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
775 				   "count %u left %u", __func__, count, left);
776 			return -6;
777 		}
778 		for (i = 0; i < count; i++) {
779 			data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
780 			pos += WPA_SELECTOR_LEN;
781 			left -= WPA_SELECTOR_LEN;
782 		}
783 	} else if (left == 1) {
784 		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
785 			   __func__);
786 		return -7;
787 	}
788 
789 	if (left >= 2) {
790 		data->capabilities = WPA_GET_LE16(pos);
791 		pos += 2;
792 		left -= 2;
793 	}
794 
795 	if (left > 0) {
796 		wpa_hexdump(MSG_DEBUG,
797 			    "wpa_parse_wpa_ie_wpa: ignore trailing bytes",
798 			    pos, left);
799 	}
800 
801 	return 0;
802 }
803 
804 
805 #ifdef CONFIG_IEEE80211R
806 
807 /**
808  * wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
809  *
810  * IEEE Std 802.11r-2008 - 8.5.1.5.3
811  */
812 void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
813 		       const u8 *ssid, size_t ssid_len,
814 		       const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
815 		       const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name)
816 {
817 	u8 buf[1 + WPA_MAX_SSID_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
818 	       FT_R0KH_ID_MAX_LEN + ETH_ALEN];
819 	u8 *pos, r0_key_data[48], hash[32];
820 	const u8 *addr[2];
821 	size_t len[2];
822 
823 	/*
824 	 * R0-Key-Data = KDF-384(XXKey, "FT-R0",
825 	 *                       SSIDlength || SSID || MDID || R0KHlength ||
826 	 *                       R0KH-ID || S0KH-ID)
827 	 * XXKey is either the second 256 bits of MSK or PSK.
828 	 * PMK-R0 = L(R0-Key-Data, 0, 256)
829 	 * PMK-R0Name-Salt = L(R0-Key-Data, 256, 128)
830 	 */
831 	if (ssid_len > WPA_MAX_SSID_LEN || r0kh_id_len > FT_R0KH_ID_MAX_LEN)
832 		return;
833 	pos = buf;
834 	*pos++ = ssid_len;
835 	os_memcpy(pos, ssid, ssid_len);
836 	pos += ssid_len;
837 	os_memcpy(pos, mdid, MOBILITY_DOMAIN_ID_LEN);
838 	pos += MOBILITY_DOMAIN_ID_LEN;
839 	*pos++ = r0kh_id_len;
840 	os_memcpy(pos, r0kh_id, r0kh_id_len);
841 	pos += r0kh_id_len;
842 	os_memcpy(pos, s0kh_id, ETH_ALEN);
843 	pos += ETH_ALEN;
844 
845 	sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
846 		   r0_key_data, sizeof(r0_key_data));
847 	os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
848 
849 	/*
850 	 * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
851 	 */
852 	addr[0] = (const u8 *) "FT-R0N";
853 	len[0] = 6;
854 	addr[1] = r0_key_data + PMK_LEN;
855 	len[1] = 16;
856 
857 	sha256_vector(2, addr, len, hash);
858 	os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
859 }
860 
861 
862 /**
863  * wpa_derive_pmk_r1_name - Derive PMKR1Name
864  *
865  * IEEE Std 802.11r-2008 - 8.5.1.5.4
866  */
867 void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
868 			    const u8 *s1kh_id, u8 *pmk_r1_name)
869 {
870 	u8 hash[32];
871 	const u8 *addr[4];
872 	size_t len[4];
873 
874 	/*
875 	 * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name ||
876 	 *                                  R1KH-ID || S1KH-ID))
877 	 */
878 	addr[0] = (const u8 *) "FT-R1N";
879 	len[0] = 6;
880 	addr[1] = pmk_r0_name;
881 	len[1] = WPA_PMK_NAME_LEN;
882 	addr[2] = r1kh_id;
883 	len[2] = FT_R1KH_ID_LEN;
884 	addr[3] = s1kh_id;
885 	len[3] = ETH_ALEN;
886 
887 	sha256_vector(4, addr, len, hash);
888 	os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
889 }
890 
891 
892 /**
893  * wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
894  *
895  * IEEE Std 802.11r-2008 - 8.5.1.5.4
896  */
897 void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
898 		       const u8 *r1kh_id, const u8 *s1kh_id,
899 		       u8 *pmk_r1, u8 *pmk_r1_name)
900 {
901 	u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
902 	u8 *pos;
903 
904 	/* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
905 	pos = buf;
906 	os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
907 	pos += FT_R1KH_ID_LEN;
908 	os_memcpy(pos, s1kh_id, ETH_ALEN);
909 	pos += ETH_ALEN;
910 
911 	sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN);
912 
913 	wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
914 }
915 
916 
917 /**
918  * wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
919  *
920  * IEEE Std 802.11r-2008 - 8.5.1.5.5
921  */
922 int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
923 		      const u8 *sta_addr, const u8 *bssid,
924 		      const u8 *pmk_r1_name,
925 		      struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher)
926 {
927 	u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
928 	u8 *pos, hash[32];
929 	const u8 *addr[6];
930 	size_t len[6];
931 	u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
932 	size_t ptk_len;
933 
934 	/*
935 	 * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
936 	 *                  BSSID || STA-ADDR)
937 	 */
938 	pos = buf;
939 	os_memcpy(pos, snonce, WPA_NONCE_LEN);
940 	pos += WPA_NONCE_LEN;
941 	os_memcpy(pos, anonce, WPA_NONCE_LEN);
942 	pos += WPA_NONCE_LEN;
943 	os_memcpy(pos, bssid, ETH_ALEN);
944 	pos += ETH_ALEN;
945 	os_memcpy(pos, sta_addr, ETH_ALEN);
946 	pos += ETH_ALEN;
947 
948 	ptk->kck_len = wpa_kck_len(akmp);
949 	ptk->kek_len = wpa_kek_len(akmp);
950 	ptk->tk_len = wpa_cipher_key_len(cipher);
951 	ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
952 
953 	sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf, tmp, ptk_len);
954 
955 	/*
956 	 * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTKN" || SNonce ||
957 	 *                                ANonce || BSSID || STA-ADDR))
958 	 */
959 	addr[0] = pmk_r1_name;
960 	len[0] = WPA_PMK_NAME_LEN;
961 	addr[1] = (const u8 *) "FT-PTKN";
962 	len[1] = 7;
963 	addr[2] = snonce;
964 	len[2] = WPA_NONCE_LEN;
965 	addr[3] = anonce;
966 	len[3] = WPA_NONCE_LEN;
967 	addr[4] = bssid;
968 	len[4] = ETH_ALEN;
969 	addr[5] = sta_addr;
970 	len[5] = ETH_ALEN;
971 
972 	sha256_vector(6, addr, len, hash);
973 	os_memcpy(ptk_name, hash, WPA_PMK_NAME_LEN);
974 
975 	os_memcpy(ptk->kck, tmp, ptk->kck_len);
976 	os_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);
977 	os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
978 
979 	wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
980 	wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
981 	wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
982 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
983 
984 	os_memset(tmp, 0, sizeof(tmp));
985 
986 	return 0;
987 }
988 
989 #endif /* CONFIG_IEEE80211R */
990 
991 
992 /**
993  * rsn_pmkid - Calculate PMK identifier
994  * @pmk: Pairwise master key
995  * @pmk_len: Length of pmk in bytes
996  * @aa: Authenticator address
997  * @spa: Supplicant address
998  * @pmkid: Buffer for PMKID
999  * @use_sha256: Whether to use SHA256-based KDF
1000  *
1001  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
1002  * PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
1003  */
1004 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
1005 	       u8 *pmkid, int use_sha256)
1006 {
1007 	char *title = "PMK Name";
1008 	const u8 *addr[3];
1009 	const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1010 	unsigned char hash[SHA256_MAC_LEN];
1011 
1012 	addr[0] = (u8 *) title;
1013 	addr[1] = aa;
1014 	addr[2] = spa;
1015 
1016 #ifdef CONFIG_IEEE80211W
1017 	if (use_sha256)
1018 		hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
1019 	else
1020 #endif /* CONFIG_IEEE80211W */
1021 		hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
1022 	os_memcpy(pmkid, hash, PMKID_LEN);
1023 }
1024 
1025 
1026 #ifdef CONFIG_SUITEB
1027 /**
1028  * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
1029  * @kck: Key confirmation key
1030  * @kck_len: Length of kck in bytes
1031  * @aa: Authenticator address
1032  * @spa: Supplicant address
1033  * @pmkid: Buffer for PMKID
1034  * Returns: 0 on success, -1 on failure
1035  *
1036  * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
1037  * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
1038  */
1039 int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
1040 		      const u8 *spa, u8 *pmkid)
1041 {
1042 	char *title = "PMK Name";
1043 	const u8 *addr[3];
1044 	const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1045 	unsigned char hash[SHA256_MAC_LEN];
1046 
1047 	addr[0] = (u8 *) title;
1048 	addr[1] = aa;
1049 	addr[2] = spa;
1050 
1051 	if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
1052 		return -1;
1053 	os_memcpy(pmkid, hash, PMKID_LEN);
1054 	return 0;
1055 }
1056 #endif /* CONFIG_SUITEB */
1057 
1058 
1059 #ifdef CONFIG_SUITEB192
1060 /**
1061  * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
1062  * @kck: Key confirmation key
1063  * @kck_len: Length of kck in bytes
1064  * @aa: Authenticator address
1065  * @spa: Supplicant address
1066  * @pmkid: Buffer for PMKID
1067  * Returns: 0 on success, -1 on failure
1068  *
1069  * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
1070  * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
1071  */
1072 int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
1073 			  const u8 *spa, u8 *pmkid)
1074 {
1075 	char *title = "PMK Name";
1076 	const u8 *addr[3];
1077 	const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
1078 	unsigned char hash[SHA384_MAC_LEN];
1079 
1080 	addr[0] = (u8 *) title;
1081 	addr[1] = aa;
1082 	addr[2] = spa;
1083 
1084 	if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
1085 		return -1;
1086 	os_memcpy(pmkid, hash, PMKID_LEN);
1087 	return 0;
1088 }
1089 #endif /* CONFIG_SUITEB192 */
1090 
1091 
1092 /**
1093  * wpa_cipher_txt - Convert cipher suite to a text string
1094  * @cipher: Cipher suite (WPA_CIPHER_* enum)
1095  * Returns: Pointer to a text string of the cipher suite name
1096  */
1097 const char * wpa_cipher_txt(int cipher)
1098 {
1099 	switch (cipher) {
1100 	case WPA_CIPHER_NONE:
1101 		return "NONE";
1102 	case WPA_CIPHER_WEP40:
1103 		return "WEP-40";
1104 	case WPA_CIPHER_WEP104:
1105 		return "WEP-104";
1106 	case WPA_CIPHER_TKIP:
1107 		return "TKIP";
1108 	case WPA_CIPHER_CCMP:
1109 		return "CCMP";
1110 	case WPA_CIPHER_CCMP | WPA_CIPHER_TKIP:
1111 		return "CCMP+TKIP";
1112 	case WPA_CIPHER_GCMP:
1113 		return "GCMP";
1114 	case WPA_CIPHER_GCMP_256:
1115 		return "GCMP-256";
1116 	case WPA_CIPHER_CCMP_256:
1117 		return "CCMP-256";
1118 	case WPA_CIPHER_GTK_NOT_USED:
1119 		return "GTK_NOT_USED";
1120 	default:
1121 		return "UNKNOWN";
1122 	}
1123 }
1124 
1125 
1126 /**
1127  * wpa_key_mgmt_txt - Convert key management suite to a text string
1128  * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
1129  * @proto: WPA/WPA2 version (WPA_PROTO_*)
1130  * Returns: Pointer to a text string of the key management suite name
1131  */
1132 const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
1133 {
1134 	switch (key_mgmt) {
1135 	case WPA_KEY_MGMT_IEEE8021X:
1136 		if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
1137 			return "WPA2+WPA/IEEE 802.1X/EAP";
1138 		return proto == WPA_PROTO_RSN ?
1139 			"WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
1140 	case WPA_KEY_MGMT_PSK:
1141 		if (proto == (WPA_PROTO_RSN | WPA_PROTO_WPA))
1142 			return "WPA2-PSK+WPA-PSK";
1143 		return proto == WPA_PROTO_RSN ?
1144 			"WPA2-PSK" : "WPA-PSK";
1145 	case WPA_KEY_MGMT_NONE:
1146 		return "NONE";
1147 	case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
1148 		return "IEEE 802.1X (no WPA)";
1149 #ifdef CONFIG_IEEE80211R
1150 	case WPA_KEY_MGMT_FT_IEEE8021X:
1151 		return "FT-EAP";
1152 	case WPA_KEY_MGMT_FT_PSK:
1153 		return "FT-PSK";
1154 #endif /* CONFIG_IEEE80211R */
1155 #ifdef CONFIG_IEEE80211W
1156 	case WPA_KEY_MGMT_IEEE8021X_SHA256:
1157 		return "WPA2-EAP-SHA256";
1158 	case WPA_KEY_MGMT_PSK_SHA256:
1159 		return "WPA2-PSK-SHA256";
1160 #endif /* CONFIG_IEEE80211W */
1161 	case WPA_KEY_MGMT_WPS:
1162 		return "WPS";
1163 	case WPA_KEY_MGMT_SAE:
1164 		return "SAE";
1165 	case WPA_KEY_MGMT_FT_SAE:
1166 		return "FT-SAE";
1167 	case WPA_KEY_MGMT_OSEN:
1168 		return "OSEN";
1169 	case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
1170 		return "WPA2-EAP-SUITE-B";
1171 	case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
1172 		return "WPA2-EAP-SUITE-B-192";
1173 	default:
1174 		return "UNKNOWN";
1175 	}
1176 }
1177 
1178 
1179 u32 wpa_akm_to_suite(int akm)
1180 {
1181 	if (akm & WPA_KEY_MGMT_FT_IEEE8021X)
1182 		return WLAN_AKM_SUITE_FT_8021X;
1183 	if (akm & WPA_KEY_MGMT_FT_PSK)
1184 		return WLAN_AKM_SUITE_FT_PSK;
1185 	if (akm & WPA_KEY_MGMT_IEEE8021X)
1186 		return WLAN_AKM_SUITE_8021X;
1187 	if (akm & WPA_KEY_MGMT_IEEE8021X_SHA256)
1188 		return WLAN_AKM_SUITE_8021X_SHA256;
1189 	if (akm & WPA_KEY_MGMT_IEEE8021X)
1190 		return WLAN_AKM_SUITE_8021X;
1191 	if (akm & WPA_KEY_MGMT_PSK_SHA256)
1192 		return WLAN_AKM_SUITE_PSK_SHA256;
1193 	if (akm & WPA_KEY_MGMT_PSK)
1194 		return WLAN_AKM_SUITE_PSK;
1195 	if (akm & WPA_KEY_MGMT_CCKM)
1196 		return WLAN_AKM_SUITE_CCKM;
1197 	if (akm & WPA_KEY_MGMT_OSEN)
1198 		return WLAN_AKM_SUITE_OSEN;
1199 	if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
1200 		return WLAN_AKM_SUITE_8021X_SUITE_B;
1201 	if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
1202 		return WLAN_AKM_SUITE_8021X_SUITE_B_192;
1203 	return 0;
1204 }
1205 
1206 
1207 int wpa_compare_rsn_ie(int ft_initial_assoc,
1208 		       const u8 *ie1, size_t ie1len,
1209 		       const u8 *ie2, size_t ie2len)
1210 {
1211 	if (ie1 == NULL || ie2 == NULL)
1212 		return -1;
1213 
1214 	if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0)
1215 		return 0; /* identical IEs */
1216 
1217 #ifdef CONFIG_IEEE80211R
1218 	if (ft_initial_assoc) {
1219 		struct wpa_ie_data ie1d, ie2d;
1220 		/*
1221 		 * The PMKID-List in RSN IE is different between Beacon/Probe
1222 		 * Response/(Re)Association Request frames and EAPOL-Key
1223 		 * messages in FT initial mobility domain association. Allow
1224 		 * for this, but verify that other parts of the RSN IEs are
1225 		 * identical.
1226 		 */
1227 		if (wpa_parse_wpa_ie_rsn(ie1, ie1len, &ie1d) < 0 ||
1228 		    wpa_parse_wpa_ie_rsn(ie2, ie2len, &ie2d) < 0)
1229 			return -1;
1230 		if (ie1d.proto == ie2d.proto &&
1231 		    ie1d.pairwise_cipher == ie2d.pairwise_cipher &&
1232 		    ie1d.group_cipher == ie2d.group_cipher &&
1233 		    ie1d.key_mgmt == ie2d.key_mgmt &&
1234 		    ie1d.capabilities == ie2d.capabilities &&
1235 		    ie1d.mgmt_group_cipher == ie2d.mgmt_group_cipher)
1236 			return 0;
1237 	}
1238 #endif /* CONFIG_IEEE80211R */
1239 
1240 	return -1;
1241 }
1242 
1243 
1244 #ifdef CONFIG_IEEE80211R
1245 int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid)
1246 {
1247 	u8 *start, *end, *rpos, *rend;
1248 	int added = 0;
1249 
1250 	start = ies;
1251 	end = ies + ies_len;
1252 
1253 	while (start < end) {
1254 		if (*start == WLAN_EID_RSN)
1255 			break;
1256 		start += 2 + start[1];
1257 	}
1258 	if (start >= end) {
1259 		wpa_printf(MSG_ERROR, "FT: Could not find RSN IE in "
1260 			   "IEs data");
1261 		return -1;
1262 	}
1263 	wpa_hexdump(MSG_DEBUG, "FT: RSN IE before modification",
1264 		    start, 2 + start[1]);
1265 
1266 	/* Find start of PMKID-Count */
1267 	rpos = start + 2;
1268 	rend = rpos + start[1];
1269 
1270 	/* Skip Version and Group Data Cipher Suite */
1271 	rpos += 2 + 4;
1272 	/* Skip Pairwise Cipher Suite Count and List */
1273 	rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
1274 	/* Skip AKM Suite Count and List */
1275 	rpos += 2 + WPA_GET_LE16(rpos) * RSN_SELECTOR_LEN;
1276 
1277 	if (rpos == rend) {
1278 		/* Add RSN Capabilities */
1279 		os_memmove(rpos + 2, rpos, end - rpos);
1280 		*rpos++ = 0;
1281 		*rpos++ = 0;
1282 	} else {
1283 		/* Skip RSN Capabilities */
1284 		rpos += 2;
1285 		if (rpos > rend) {
1286 			wpa_printf(MSG_ERROR, "FT: Could not parse RSN IE in "
1287 				   "IEs data");
1288 			return -1;
1289 		}
1290 	}
1291 
1292 	if (rpos == rend) {
1293 		/* No PMKID-Count field included; add it */
1294 		os_memmove(rpos + 2 + PMKID_LEN, rpos, end - rpos);
1295 		WPA_PUT_LE16(rpos, 1);
1296 		rpos += 2;
1297 		os_memcpy(rpos, pmkid, PMKID_LEN);
1298 		added += 2 + PMKID_LEN;
1299 		start[1] += 2 + PMKID_LEN;
1300 	} else {
1301 		/* PMKID-Count was included; use it */
1302 		if (WPA_GET_LE16(rpos) != 0) {
1303 			wpa_printf(MSG_ERROR, "FT: Unexpected PMKID "
1304 				   "in RSN IE in EAPOL-Key data");
1305 			return -1;
1306 		}
1307 		WPA_PUT_LE16(rpos, 1);
1308 		rpos += 2;
1309 		os_memmove(rpos + PMKID_LEN, rpos, end - rpos);
1310 		os_memcpy(rpos, pmkid, PMKID_LEN);
1311 		added += PMKID_LEN;
1312 		start[1] += PMKID_LEN;
1313 	}
1314 
1315 	wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
1316 		    "(PMKID inserted)", start, 2 + start[1]);
1317 
1318 	return added;
1319 }
1320 #endif /* CONFIG_IEEE80211R */
1321 
1322 
1323 int wpa_cipher_key_len(int cipher)
1324 {
1325 	switch (cipher) {
1326 	case WPA_CIPHER_CCMP_256:
1327 	case WPA_CIPHER_GCMP_256:
1328 	case WPA_CIPHER_BIP_GMAC_256:
1329 	case WPA_CIPHER_BIP_CMAC_256:
1330 		return 32;
1331 	case WPA_CIPHER_CCMP:
1332 	case WPA_CIPHER_GCMP:
1333 	case WPA_CIPHER_AES_128_CMAC:
1334 	case WPA_CIPHER_BIP_GMAC_128:
1335 		return 16;
1336 	case WPA_CIPHER_TKIP:
1337 		return 32;
1338 	case WPA_CIPHER_WEP104:
1339 		return 13;
1340 	case WPA_CIPHER_WEP40:
1341 		return 5;
1342 	}
1343 
1344 	return 0;
1345 }
1346 
1347 
1348 int wpa_cipher_rsc_len(int cipher)
1349 {
1350 	switch (cipher) {
1351 	case WPA_CIPHER_CCMP_256:
1352 	case WPA_CIPHER_GCMP_256:
1353 	case WPA_CIPHER_CCMP:
1354 	case WPA_CIPHER_GCMP:
1355 	case WPA_CIPHER_TKIP:
1356 		return 6;
1357 	case WPA_CIPHER_WEP104:
1358 	case WPA_CIPHER_WEP40:
1359 		return 0;
1360 	}
1361 
1362 	return 0;
1363 }
1364 
1365 
1366 int wpa_cipher_to_alg(int cipher)
1367 {
1368 	switch (cipher) {
1369 	case WPA_CIPHER_CCMP_256:
1370 		return WPA_ALG_CCMP_256;
1371 	case WPA_CIPHER_GCMP_256:
1372 		return WPA_ALG_GCMP_256;
1373 	case WPA_CIPHER_CCMP:
1374 		return WPA_ALG_CCMP;
1375 	case WPA_CIPHER_GCMP:
1376 		return WPA_ALG_GCMP;
1377 	case WPA_CIPHER_TKIP:
1378 		return WPA_ALG_TKIP;
1379 	case WPA_CIPHER_WEP104:
1380 	case WPA_CIPHER_WEP40:
1381 		return WPA_ALG_WEP;
1382 	case WPA_CIPHER_AES_128_CMAC:
1383 		return WPA_ALG_IGTK;
1384 	case WPA_CIPHER_BIP_GMAC_128:
1385 		return WPA_ALG_BIP_GMAC_128;
1386 	case WPA_CIPHER_BIP_GMAC_256:
1387 		return WPA_ALG_BIP_GMAC_256;
1388 	case WPA_CIPHER_BIP_CMAC_256:
1389 		return WPA_ALG_BIP_CMAC_256;
1390 	}
1391 	return WPA_ALG_NONE;
1392 }
1393 
1394 
1395 int wpa_cipher_valid_pairwise(int cipher)
1396 {
1397 	return cipher == WPA_CIPHER_CCMP_256 ||
1398 		cipher == WPA_CIPHER_GCMP_256 ||
1399 		cipher == WPA_CIPHER_CCMP ||
1400 		cipher == WPA_CIPHER_GCMP ||
1401 		cipher == WPA_CIPHER_TKIP;
1402 }
1403 
1404 
1405 u32 wpa_cipher_to_suite(int proto, int cipher)
1406 {
1407 	if (cipher & WPA_CIPHER_CCMP_256)
1408 		return RSN_CIPHER_SUITE_CCMP_256;
1409 	if (cipher & WPA_CIPHER_GCMP_256)
1410 		return RSN_CIPHER_SUITE_GCMP_256;
1411 	if (cipher & WPA_CIPHER_CCMP)
1412 		return (proto == WPA_PROTO_RSN ?
1413 			RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
1414 	if (cipher & WPA_CIPHER_GCMP)
1415 		return RSN_CIPHER_SUITE_GCMP;
1416 	if (cipher & WPA_CIPHER_TKIP)
1417 		return (proto == WPA_PROTO_RSN ?
1418 			RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
1419 	if (cipher & WPA_CIPHER_WEP104)
1420 		return (proto == WPA_PROTO_RSN ?
1421 			RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);
1422 	if (cipher & WPA_CIPHER_WEP40)
1423 		return (proto == WPA_PROTO_RSN ?
1424 			RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);
1425 	if (cipher & WPA_CIPHER_NONE)
1426 		return (proto == WPA_PROTO_RSN ?
1427 			RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
1428 	if (cipher & WPA_CIPHER_GTK_NOT_USED)
1429 		return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
1430 	if (cipher & WPA_CIPHER_AES_128_CMAC)
1431 		return RSN_CIPHER_SUITE_AES_128_CMAC;
1432 	if (cipher & WPA_CIPHER_BIP_GMAC_128)
1433 		return RSN_CIPHER_SUITE_BIP_GMAC_128;
1434 	if (cipher & WPA_CIPHER_BIP_GMAC_256)
1435 		return RSN_CIPHER_SUITE_BIP_GMAC_256;
1436 	if (cipher & WPA_CIPHER_BIP_CMAC_256)
1437 		return RSN_CIPHER_SUITE_BIP_CMAC_256;
1438 	return 0;
1439 }
1440 
1441 
1442 int rsn_cipher_put_suites(u8 *start, int ciphers)
1443 {
1444 	u8 *pos = start;
1445 
1446 	if (ciphers & WPA_CIPHER_CCMP_256) {
1447 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP_256);
1448 		pos += RSN_SELECTOR_LEN;
1449 	}
1450 	if (ciphers & WPA_CIPHER_GCMP_256) {
1451 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP_256);
1452 		pos += RSN_SELECTOR_LEN;
1453 	}
1454 	if (ciphers & WPA_CIPHER_CCMP) {
1455 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
1456 		pos += RSN_SELECTOR_LEN;
1457 	}
1458 	if (ciphers & WPA_CIPHER_GCMP) {
1459 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_GCMP);
1460 		pos += RSN_SELECTOR_LEN;
1461 	}
1462 	if (ciphers & WPA_CIPHER_TKIP) {
1463 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
1464 		pos += RSN_SELECTOR_LEN;
1465 	}
1466 	if (ciphers & WPA_CIPHER_NONE) {
1467 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE);
1468 		pos += RSN_SELECTOR_LEN;
1469 	}
1470 
1471 	return (pos - start) / RSN_SELECTOR_LEN;
1472 }
1473 
1474 
1475 int wpa_cipher_put_suites(u8 *start, int ciphers)
1476 {
1477 	u8 *pos = start;
1478 
1479 	if (ciphers & WPA_CIPHER_CCMP) {
1480 		RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_CCMP);
1481 		pos += WPA_SELECTOR_LEN;
1482 	}
1483 	if (ciphers & WPA_CIPHER_TKIP) {
1484 		RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_TKIP);
1485 		pos += WPA_SELECTOR_LEN;
1486 	}
1487 	if (ciphers & WPA_CIPHER_NONE) {
1488 		RSN_SELECTOR_PUT(pos, WPA_CIPHER_SUITE_NONE);
1489 		pos += WPA_SELECTOR_LEN;
1490 	}
1491 
1492 	return (pos - start) / RSN_SELECTOR_LEN;
1493 }
1494 
1495 
1496 int wpa_pick_pairwise_cipher(int ciphers, int none_allowed)
1497 {
1498 	if (ciphers & WPA_CIPHER_CCMP_256)
1499 		return WPA_CIPHER_CCMP_256;
1500 	if (ciphers & WPA_CIPHER_GCMP_256)
1501 		return WPA_CIPHER_GCMP_256;
1502 	if (ciphers & WPA_CIPHER_CCMP)
1503 		return WPA_CIPHER_CCMP;
1504 	if (ciphers & WPA_CIPHER_GCMP)
1505 		return WPA_CIPHER_GCMP;
1506 	if (ciphers & WPA_CIPHER_TKIP)
1507 		return WPA_CIPHER_TKIP;
1508 	if (none_allowed && (ciphers & WPA_CIPHER_NONE))
1509 		return WPA_CIPHER_NONE;
1510 	return -1;
1511 }
1512 
1513 
1514 int wpa_pick_group_cipher(int ciphers)
1515 {
1516 	if (ciphers & WPA_CIPHER_CCMP_256)
1517 		return WPA_CIPHER_CCMP_256;
1518 	if (ciphers & WPA_CIPHER_GCMP_256)
1519 		return WPA_CIPHER_GCMP_256;
1520 	if (ciphers & WPA_CIPHER_CCMP)
1521 		return WPA_CIPHER_CCMP;
1522 	if (ciphers & WPA_CIPHER_GCMP)
1523 		return WPA_CIPHER_GCMP;
1524 	if (ciphers & WPA_CIPHER_GTK_NOT_USED)
1525 		return WPA_CIPHER_GTK_NOT_USED;
1526 	if (ciphers & WPA_CIPHER_TKIP)
1527 		return WPA_CIPHER_TKIP;
1528 	if (ciphers & WPA_CIPHER_WEP104)
1529 		return WPA_CIPHER_WEP104;
1530 	if (ciphers & WPA_CIPHER_WEP40)
1531 		return WPA_CIPHER_WEP40;
1532 	return -1;
1533 }
1534 
1535 
1536 int wpa_parse_cipher(const char *value)
1537 {
1538 	int val = 0, last;
1539 	char *start, *end, *buf;
1540 
1541 	buf = os_strdup(value);
1542 	if (buf == NULL)
1543 		return -1;
1544 	start = buf;
1545 
1546 	while (*start != '\0') {
1547 		while (*start == ' ' || *start == '\t')
1548 			start++;
1549 		if (*start == '\0')
1550 			break;
1551 		end = start;
1552 		while (*end != ' ' && *end != '\t' && *end != '\0')
1553 			end++;
1554 		last = *end == '\0';
1555 		*end = '\0';
1556 		if (os_strcmp(start, "CCMP-256") == 0)
1557 			val |= WPA_CIPHER_CCMP_256;
1558 		else if (os_strcmp(start, "GCMP-256") == 0)
1559 			val |= WPA_CIPHER_GCMP_256;
1560 		else if (os_strcmp(start, "CCMP") == 0)
1561 			val |= WPA_CIPHER_CCMP;
1562 		else if (os_strcmp(start, "GCMP") == 0)
1563 			val |= WPA_CIPHER_GCMP;
1564 		else if (os_strcmp(start, "TKIP") == 0)
1565 			val |= WPA_CIPHER_TKIP;
1566 		else if (os_strcmp(start, "WEP104") == 0)
1567 			val |= WPA_CIPHER_WEP104;
1568 		else if (os_strcmp(start, "WEP40") == 0)
1569 			val |= WPA_CIPHER_WEP40;
1570 		else if (os_strcmp(start, "NONE") == 0)
1571 			val |= WPA_CIPHER_NONE;
1572 		else if (os_strcmp(start, "GTK_NOT_USED") == 0)
1573 			val |= WPA_CIPHER_GTK_NOT_USED;
1574 		else {
1575 			os_free(buf);
1576 			return -1;
1577 		}
1578 
1579 		if (last)
1580 			break;
1581 		start = end + 1;
1582 	}
1583 	os_free(buf);
1584 
1585 	return val;
1586 }
1587 
1588 
1589 int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim)
1590 {
1591 	char *pos = start;
1592 	int ret;
1593 
1594 	if (ciphers & WPA_CIPHER_CCMP_256) {
1595 		ret = os_snprintf(pos, end - pos, "%sCCMP-256",
1596 				  pos == start ? "" : delim);
1597 		if (os_snprintf_error(end - pos, ret))
1598 			return -1;
1599 		pos += ret;
1600 	}
1601 	if (ciphers & WPA_CIPHER_GCMP_256) {
1602 		ret = os_snprintf(pos, end - pos, "%sGCMP-256",
1603 				  pos == start ? "" : delim);
1604 		if (os_snprintf_error(end - pos, ret))
1605 			return -1;
1606 		pos += ret;
1607 	}
1608 	if (ciphers & WPA_CIPHER_CCMP) {
1609 		ret = os_snprintf(pos, end - pos, "%sCCMP",
1610 				  pos == start ? "" : delim);
1611 		if (os_snprintf_error(end - pos, ret))
1612 			return -1;
1613 		pos += ret;
1614 	}
1615 	if (ciphers & WPA_CIPHER_GCMP) {
1616 		ret = os_snprintf(pos, end - pos, "%sGCMP",
1617 				  pos == start ? "" : delim);
1618 		if (os_snprintf_error(end - pos, ret))
1619 			return -1;
1620 		pos += ret;
1621 	}
1622 	if (ciphers & WPA_CIPHER_TKIP) {
1623 		ret = os_snprintf(pos, end - pos, "%sTKIP",
1624 				  pos == start ? "" : delim);
1625 		if (os_snprintf_error(end - pos, ret))
1626 			return -1;
1627 		pos += ret;
1628 	}
1629 	if (ciphers & WPA_CIPHER_WEP104) {
1630 		ret = os_snprintf(pos, end - pos, "%sWEP104",
1631 				  pos == start ? "" : delim);
1632 		if (os_snprintf_error(end - pos, ret))
1633 			return -1;
1634 		pos += ret;
1635 	}
1636 	if (ciphers & WPA_CIPHER_WEP40) {
1637 		ret = os_snprintf(pos, end - pos, "%sWEP40",
1638 				  pos == start ? "" : delim);
1639 		if (os_snprintf_error(end - pos, ret))
1640 			return -1;
1641 		pos += ret;
1642 	}
1643 	if (ciphers & WPA_CIPHER_NONE) {
1644 		ret = os_snprintf(pos, end - pos, "%sNONE",
1645 				  pos == start ? "" : delim);
1646 		if (os_snprintf_error(end - pos, ret))
1647 			return -1;
1648 		pos += ret;
1649 	}
1650 
1651 	return pos - start;
1652 }
1653 
1654 
1655 int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise)
1656 {
1657 	int pairwise = 0;
1658 
1659 	/* Select group cipher based on the enabled pairwise cipher suites */
1660 	if (wpa & 1)
1661 		pairwise |= wpa_pairwise;
1662 	if (wpa & 2)
1663 		pairwise |= rsn_pairwise;
1664 
1665 	if (pairwise & WPA_CIPHER_TKIP)
1666 		return WPA_CIPHER_TKIP;
1667 	if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP)
1668 		return WPA_CIPHER_GCMP;
1669 	if ((pairwise & (WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP |
1670 			 WPA_CIPHER_GCMP)) == WPA_CIPHER_GCMP_256)
1671 		return WPA_CIPHER_GCMP_256;
1672 	if ((pairwise & (WPA_CIPHER_CCMP_256 | WPA_CIPHER_CCMP |
1673 			 WPA_CIPHER_GCMP)) == WPA_CIPHER_CCMP_256)
1674 		return WPA_CIPHER_CCMP_256;
1675 	return WPA_CIPHER_CCMP;
1676 }
1677