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