xref: /freebsd/contrib/wpa/src/rsn_supp/wpa_ft.c (revision 148a8da8)
1 /*
2  * WPA Supplicant - IEEE 802.11r - Fast BSS Transition
3  * Copyright (c) 2006-2018, 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/aes_wrap.h"
13 #include "crypto/sha384.h"
14 #include "crypto/random.h"
15 #include "common/ieee802_11_defs.h"
16 #include "common/ieee802_11_common.h"
17 #include "wpa.h"
18 #include "wpa_i.h"
19 
20 #ifdef CONFIG_IEEE80211R
21 
22 int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
23 		      const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
24 {
25 	u8 ptk_name[WPA_PMK_NAME_LEN];
26 	const u8 *anonce = key->key_nonce;
27 	int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
28 
29 	if (sm->xxkey_len == 0) {
30 		wpa_printf(MSG_DEBUG, "FT: XXKey not available for key "
31 			   "derivation");
32 		return -1;
33 	}
34 
35 	sm->pmk_r0_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN;
36 	if (wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, sm->ssid,
37 			      sm->ssid_len, sm->mobility_domain,
38 			      sm->r0kh_id, sm->r0kh_id_len, sm->own_addr,
39 			      sm->pmk_r0, sm->pmk_r0_name, use_sha384) < 0)
40 		return -1;
41 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", sm->pmk_r0, sm->pmk_r0_len);
42 	wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name",
43 		    sm->pmk_r0_name, WPA_PMK_NAME_LEN);
44 	sm->pmk_r1_len = sm->pmk_r0_len;
45 	if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name,
46 			      sm->r1kh_id, sm->own_addr, sm->pmk_r1,
47 			      sm->pmk_r1_name) < 0)
48 		return -1;
49 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", sm->pmk_r1, sm->pmk_r1_len);
50 	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name,
51 		    WPA_PMK_NAME_LEN);
52 	return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce,
53 				 sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk,
54 				 ptk_name, sm->key_mgmt, sm->pairwise_cipher);
55 }
56 
57 
58 /**
59  * wpa_sm_set_ft_params - Set FT (IEEE 802.11r) parameters
60  * @sm: Pointer to WPA state machine data from wpa_sm_init()
61  * @ies: Association Response IEs or %NULL to clear FT parameters
62  * @ies_len: Length of ies buffer in octets
63  * Returns: 0 on success, -1 on failure
64  */
65 int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
66 {
67 	struct wpa_ft_ies ft;
68 	int use_sha384;
69 
70 	if (sm == NULL)
71 		return 0;
72 
73 	use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
74 	if (wpa_ft_parse_ies(ies, ies_len, &ft, use_sha384) < 0)
75 		return -1;
76 
77 	if (ft.mdie && ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1)
78 		return -1;
79 
80 	if (ft.mdie) {
81 		wpa_hexdump(MSG_DEBUG, "FT: Mobility domain",
82 			    ft.mdie, MOBILITY_DOMAIN_ID_LEN);
83 		os_memcpy(sm->mobility_domain, ft.mdie,
84 			  MOBILITY_DOMAIN_ID_LEN);
85 		sm->mdie_ft_capab = ft.mdie[MOBILITY_DOMAIN_ID_LEN];
86 		wpa_printf(MSG_DEBUG, "FT: Capability and Policy: 0x%02x",
87 			   sm->mdie_ft_capab);
88 	} else
89 		os_memset(sm->mobility_domain, 0, MOBILITY_DOMAIN_ID_LEN);
90 
91 	if (ft.r0kh_id) {
92 		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID",
93 			    ft.r0kh_id, ft.r0kh_id_len);
94 		os_memcpy(sm->r0kh_id, ft.r0kh_id, ft.r0kh_id_len);
95 		sm->r0kh_id_len = ft.r0kh_id_len;
96 	} else {
97 		/* FIX: When should R0KH-ID be cleared? We need to keep the
98 		 * old R0KH-ID in order to be able to use this during FT. */
99 		/*
100 		 * os_memset(sm->r0kh_id, 0, FT_R0KH_ID_LEN);
101 		 * sm->r0kh_id_len = 0;
102 		 */
103 	}
104 
105 	if (ft.r1kh_id) {
106 		wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID",
107 			    ft.r1kh_id, FT_R1KH_ID_LEN);
108 		os_memcpy(sm->r1kh_id, ft.r1kh_id, FT_R1KH_ID_LEN);
109 	} else
110 		os_memset(sm->r1kh_id, 0, FT_R1KH_ID_LEN);
111 
112 	os_free(sm->assoc_resp_ies);
113 	sm->assoc_resp_ies = os_malloc(ft.mdie_len + 2 + ft.ftie_len + 2);
114 	if (sm->assoc_resp_ies) {
115 		u8 *pos = sm->assoc_resp_ies;
116 		if (ft.mdie) {
117 			os_memcpy(pos, ft.mdie - 2, ft.mdie_len + 2);
118 			pos += ft.mdie_len + 2;
119 		}
120 		if (ft.ftie) {
121 			os_memcpy(pos, ft.ftie - 2, ft.ftie_len + 2);
122 			pos += ft.ftie_len + 2;
123 		}
124 		sm->assoc_resp_ies_len = pos - sm->assoc_resp_ies;
125 		wpa_hexdump(MSG_DEBUG, "FT: Stored MDIE and FTIE from "
126 			    "(Re)Association Response",
127 			    sm->assoc_resp_ies, sm->assoc_resp_ies_len);
128 	}
129 
130 	return 0;
131 }
132 
133 
134 /**
135  * wpa_ft_gen_req_ies - Generate FT (IEEE 802.11r) IEs for Auth/ReAssoc Request
136  * @sm: Pointer to WPA state machine data from wpa_sm_init()
137  * @len: Buffer for returning the length of the IEs
138  * @anonce: ANonce or %NULL if not yet available
139  * @pmk_name: PMKR0Name or PMKR1Name to be added into the RSN IE PMKID List
140  * @kck: 128-bit KCK for MIC or %NULL if no MIC is used
141  * @kck_len: KCK length in octets
142  * @target_ap: Target AP address
143  * @ric_ies: Optional IE(s), e.g., WMM TSPEC(s), for RIC-Request or %NULL
144  * @ric_ies_len: Length of ric_ies buffer in octets
145  * @ap_mdie: Mobility Domain IE from the target AP
146  * Returns: Pointer to buffer with IEs or %NULL on failure
147  *
148  * Caller is responsible for freeing the returned buffer with os_free();
149  */
150 static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
151 			       const u8 *anonce, const u8 *pmk_name,
152 			       const u8 *kck, size_t kck_len,
153 			       const u8 *target_ap,
154 			       const u8 *ric_ies, size_t ric_ies_len,
155 			       const u8 *ap_mdie)
156 {
157 	size_t buf_len;
158 	u8 *buf, *pos, *ftie_len, *ftie_pos, *fte_mic, *elem_count;
159 	struct rsn_mdie *mdie;
160 	struct rsn_ie_hdr *rsnie;
161 	u16 capab;
162 	int mdie_len;
163 
164 	sm->ft_completed = 0;
165 	sm->ft_reassoc_completed = 0;
166 
167 	buf_len = 2 + sizeof(struct rsn_mdie) + 2 +
168 		sizeof(struct rsn_ftie_sha384) +
169 		2 + sm->r0kh_id_len + ric_ies_len + 100;
170 	buf = os_zalloc(buf_len);
171 	if (buf == NULL)
172 		return NULL;
173 	pos = buf;
174 
175 	/* RSNIE[PMKR0Name/PMKR1Name] */
176 	rsnie = (struct rsn_ie_hdr *) pos;
177 	rsnie->elem_id = WLAN_EID_RSN;
178 	WPA_PUT_LE16(rsnie->version, RSN_VERSION);
179 	pos = (u8 *) (rsnie + 1);
180 
181 	/* Group Suite Selector */
182 	if (!wpa_cipher_valid_group(sm->group_cipher)) {
183 		wpa_printf(MSG_WARNING, "FT: Invalid group cipher (%d)",
184 			   sm->group_cipher);
185 		os_free(buf);
186 		return NULL;
187 	}
188 	RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN,
189 						  sm->group_cipher));
190 	pos += RSN_SELECTOR_LEN;
191 
192 	/* Pairwise Suite Count */
193 	WPA_PUT_LE16(pos, 1);
194 	pos += 2;
195 
196 	/* Pairwise Suite List */
197 	if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
198 		wpa_printf(MSG_WARNING, "FT: Invalid pairwise cipher (%d)",
199 			   sm->pairwise_cipher);
200 		os_free(buf);
201 		return NULL;
202 	}
203 	RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN,
204 						  sm->pairwise_cipher));
205 	pos += RSN_SELECTOR_LEN;
206 
207 	/* Authenticated Key Management Suite Count */
208 	WPA_PUT_LE16(pos, 1);
209 	pos += 2;
210 
211 	/* Authenticated Key Management Suite List */
212 	if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X)
213 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
214 #ifdef CONFIG_SHA384
215 	else if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X_SHA384)
216 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
217 #endif /* CONFIG_SHA384 */
218 	else if (sm->key_mgmt == WPA_KEY_MGMT_FT_PSK)
219 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
220 	else if (sm->key_mgmt == WPA_KEY_MGMT_FT_SAE)
221 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
222 #ifdef CONFIG_FILS
223 	else if (sm->key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA256)
224 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256);
225 	else if (sm->key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA384)
226 		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384);
227 #endif /* CONFIG_FILS */
228 	else {
229 		wpa_printf(MSG_WARNING, "FT: Invalid key management type (%d)",
230 			   sm->key_mgmt);
231 		os_free(buf);
232 		return NULL;
233 	}
234 	pos += RSN_SELECTOR_LEN;
235 
236 	/* RSN Capabilities */
237 	capab = 0;
238 #ifdef CONFIG_IEEE80211W
239 	if (sm->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ||
240 	    sm->mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_128 ||
241 	    sm->mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_256 ||
242 	    sm->mgmt_group_cipher == WPA_CIPHER_BIP_CMAC_256)
243 		capab |= WPA_CAPABILITY_MFPC;
244 #endif /* CONFIG_IEEE80211W */
245 	WPA_PUT_LE16(pos, capab);
246 	pos += 2;
247 
248 	/* PMKID Count */
249 	WPA_PUT_LE16(pos, 1);
250 	pos += 2;
251 
252 	/* PMKID List [PMKR0Name/PMKR1Name] */
253 	os_memcpy(pos, pmk_name, WPA_PMK_NAME_LEN);
254 	pos += WPA_PMK_NAME_LEN;
255 
256 #ifdef CONFIG_IEEE80211W
257 	/* Management Group Cipher Suite */
258 	switch (sm->mgmt_group_cipher) {
259 	case WPA_CIPHER_AES_128_CMAC:
260 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
261 		pos += RSN_SELECTOR_LEN;
262 		break;
263 	case WPA_CIPHER_BIP_GMAC_128:
264 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128);
265 		pos += RSN_SELECTOR_LEN;
266 		break;
267 	case WPA_CIPHER_BIP_GMAC_256:
268 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256);
269 		pos += RSN_SELECTOR_LEN;
270 		break;
271 	case WPA_CIPHER_BIP_CMAC_256:
272 		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_CMAC_256);
273 		pos += RSN_SELECTOR_LEN;
274 		break;
275 	}
276 #endif /* CONFIG_IEEE80211W */
277 
278 	rsnie->len = (pos - (u8 *) rsnie) - 2;
279 
280 	/* MDIE */
281 	mdie_len = wpa_ft_add_mdie(sm, pos, buf_len - (pos - buf), ap_mdie);
282 	if (mdie_len <= 0) {
283 		os_free(buf);
284 		return NULL;
285 	}
286 	mdie = (struct rsn_mdie *) (pos + 2);
287 	pos += mdie_len;
288 
289 	/* FTIE[SNonce, [R1KH-ID,] R0KH-ID ] */
290 	ftie_pos = pos;
291 	*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
292 	ftie_len = pos++;
293 	if (wpa_key_mgmt_sha384(sm->key_mgmt)) {
294 		struct rsn_ftie_sha384 *ftie;
295 
296 		ftie = (struct rsn_ftie_sha384 *) pos;
297 		fte_mic = ftie->mic;
298 		elem_count = &ftie->mic_control[1];
299 		pos += sizeof(*ftie);
300 		os_memcpy(ftie->snonce, sm->snonce, WPA_NONCE_LEN);
301 		if (anonce)
302 			os_memcpy(ftie->anonce, anonce, WPA_NONCE_LEN);
303 	} else {
304 		struct rsn_ftie *ftie;
305 
306 		ftie = (struct rsn_ftie *) pos;
307 		fte_mic = ftie->mic;
308 		elem_count = &ftie->mic_control[1];
309 		pos += sizeof(*ftie);
310 		os_memcpy(ftie->snonce, sm->snonce, WPA_NONCE_LEN);
311 		if (anonce)
312 			os_memcpy(ftie->anonce, anonce, WPA_NONCE_LEN);
313 	}
314 	if (kck) {
315 		/* R1KH-ID sub-element in third FT message */
316 		*pos++ = FTIE_SUBELEM_R1KH_ID;
317 		*pos++ = FT_R1KH_ID_LEN;
318 		os_memcpy(pos, sm->r1kh_id, FT_R1KH_ID_LEN);
319 		pos += FT_R1KH_ID_LEN;
320 	}
321 	/* R0KH-ID sub-element */
322 	*pos++ = FTIE_SUBELEM_R0KH_ID;
323 	*pos++ = sm->r0kh_id_len;
324 	os_memcpy(pos, sm->r0kh_id, sm->r0kh_id_len);
325 	pos += sm->r0kh_id_len;
326 	*ftie_len = pos - ftie_len - 1;
327 
328 	if (ric_ies) {
329 		/* RIC Request */
330 		os_memcpy(pos, ric_ies, ric_ies_len);
331 		pos += ric_ies_len;
332 	}
333 
334 	if (kck) {
335 		/*
336 		 * IEEE Std 802.11r-2008, 11A.8.4
337 		 * MIC shall be calculated over:
338 		 * non-AP STA MAC address
339 		 * Target AP MAC address
340 		 * Transaction seq number (5 for ReassocReq, 3 otherwise)
341 		 * RSN IE
342 		 * MDIE
343 		 * FTIE (with MIC field set to 0)
344 		 * RIC-Request (if present)
345 		 */
346 		/* Information element count */
347 		*elem_count = 3 + ieee802_11_ie_count(ric_ies, ric_ies_len);
348 		if (wpa_ft_mic(kck, kck_len, sm->own_addr, target_ap, 5,
349 			       ((u8 *) mdie) - 2, 2 + sizeof(*mdie),
350 			       ftie_pos, 2 + *ftie_len,
351 			       (u8 *) rsnie, 2 + rsnie->len, ric_ies,
352 			       ric_ies_len, fte_mic) < 0) {
353 			wpa_printf(MSG_INFO, "FT: Failed to calculate MIC");
354 			os_free(buf);
355 			return NULL;
356 		}
357 	}
358 
359 	*len = pos - buf;
360 
361 	return buf;
362 }
363 
364 
365 static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
366 {
367 	int keylen;
368 	enum wpa_alg alg;
369 	u8 null_rsc[6] = { 0, 0, 0, 0, 0, 0 };
370 
371 	wpa_printf(MSG_DEBUG, "FT: Installing PTK to the driver.");
372 
373 	if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
374 		wpa_printf(MSG_WARNING, "FT: Unsupported pairwise cipher %d",
375 			   sm->pairwise_cipher);
376 		return -1;
377 	}
378 
379 	alg = wpa_cipher_to_alg(sm->pairwise_cipher);
380 	keylen = wpa_cipher_key_len(sm->pairwise_cipher);
381 
382 	if (wpa_sm_set_key(sm, alg, bssid, 0, 1, null_rsc,
383 			   sizeof(null_rsc), (u8 *) sm->ptk.tk, keylen) < 0) {
384 		wpa_printf(MSG_WARNING, "FT: Failed to set PTK to the driver");
385 		return -1;
386 	}
387 
388 	return 0;
389 }
390 
391 
392 /**
393  * wpa_ft_prepare_auth_request - Generate over-the-air auth request
394  * @sm: Pointer to WPA state machine data from wpa_sm_init()
395  * @mdie: Target AP MDIE
396  * Returns: 0 on success, -1 on failure
397  */
398 int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie)
399 {
400 	u8 *ft_ies;
401 	size_t ft_ies_len;
402 
403 	/* Generate a new SNonce */
404 	if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
405 		wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce");
406 		return -1;
407 	}
408 
409 	ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name,
410 				    NULL, 0, sm->bssid, NULL, 0, mdie);
411 	if (ft_ies) {
412 		wpa_sm_update_ft_ies(sm, sm->mobility_domain,
413 				     ft_ies, ft_ies_len);
414 		os_free(ft_ies);
415 	}
416 
417 	return 0;
418 }
419 
420 
421 int wpa_ft_add_mdie(struct wpa_sm *sm, u8 *buf, size_t buf_len,
422 		    const u8 *ap_mdie)
423 {
424 	u8 *pos = buf;
425 	struct rsn_mdie *mdie;
426 
427 	if (buf_len < 2 + sizeof(*mdie)) {
428 		wpa_printf(MSG_INFO,
429 			   "FT: Failed to add MDIE: short buffer, length=%zu",
430 			   buf_len);
431 		return 0;
432 	}
433 
434 	*pos++ = WLAN_EID_MOBILITY_DOMAIN;
435 	*pos++ = sizeof(*mdie);
436 	mdie = (struct rsn_mdie *) pos;
437 	os_memcpy(mdie->mobility_domain, sm->mobility_domain,
438 		  MOBILITY_DOMAIN_ID_LEN);
439 	mdie->ft_capab = ap_mdie && ap_mdie[1] >= 3 ? ap_mdie[4] :
440 		sm->mdie_ft_capab;
441 
442 	return 2 + sizeof(*mdie);
443 }
444 
445 
446 const u8 * wpa_sm_get_ft_md(struct wpa_sm *sm)
447 {
448 	return sm->mobility_domain;
449 }
450 
451 
452 int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
453 			    int ft_action, const u8 *target_ap,
454 			    const u8 *ric_ies, size_t ric_ies_len)
455 {
456 	u8 *ft_ies;
457 	size_t ft_ies_len;
458 	struct wpa_ft_ies parse;
459 	struct rsn_mdie *mdie;
460 	u8 ptk_name[WPA_PMK_NAME_LEN];
461 	int ret;
462 	const u8 *bssid;
463 	const u8 *kck;
464 	size_t kck_len;
465 	int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
466 	const u8 *anonce, *snonce;
467 
468 	wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
469 	wpa_hexdump(MSG_DEBUG, "FT: RIC IEs", ric_ies, ric_ies_len);
470 
471 	if (ft_action) {
472 		if (!sm->over_the_ds_in_progress) {
473 			wpa_printf(MSG_DEBUG, "FT: No over-the-DS in progress "
474 				   "- drop FT Action Response");
475 			return -1;
476 		}
477 
478 		if (os_memcmp(target_ap, sm->target_ap, ETH_ALEN) != 0) {
479 			wpa_printf(MSG_DEBUG, "FT: No over-the-DS in progress "
480 				   "with this Target AP - drop FT Action "
481 				   "Response");
482 			return -1;
483 		}
484 	}
485 
486 	if (!wpa_key_mgmt_ft(sm->key_mgmt)) {
487 		wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not "
488 			   "enabled for this connection");
489 		return -1;
490 	}
491 
492 	if (wpa_ft_parse_ies(ies, ies_len, &parse, use_sha384) < 0) {
493 		wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
494 		return -1;
495 	}
496 
497 	mdie = (struct rsn_mdie *) parse.mdie;
498 	if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
499 	    os_memcmp(mdie->mobility_domain, sm->mobility_domain,
500 		      MOBILITY_DOMAIN_ID_LEN) != 0) {
501 		wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
502 		return -1;
503 	}
504 
505 	if (use_sha384) {
506 		struct rsn_ftie_sha384 *ftie;
507 
508 		ftie = (struct rsn_ftie_sha384 *) parse.ftie;
509 		if (!ftie || parse.ftie_len < sizeof(*ftie)) {
510 			wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
511 			return -1;
512 		}
513 
514 		anonce = ftie->anonce;
515 		snonce = ftie->snonce;
516 	} else {
517 		struct rsn_ftie *ftie;
518 
519 		ftie = (struct rsn_ftie *) parse.ftie;
520 		if (!ftie || parse.ftie_len < sizeof(*ftie)) {
521 			wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
522 			return -1;
523 		}
524 
525 		anonce = ftie->anonce;
526 		snonce = ftie->snonce;
527 	}
528 
529 	if (os_memcmp(snonce, sm->snonce, WPA_NONCE_LEN) != 0) {
530 		wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
531 		wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
532 			    snonce, WPA_NONCE_LEN);
533 		wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
534 			    sm->snonce, WPA_NONCE_LEN);
535 		return -1;
536 	}
537 
538 	if (parse.r0kh_id == NULL) {
539 		wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE");
540 		return -1;
541 	}
542 
543 	if (parse.r0kh_id_len != sm->r0kh_id_len ||
544 	    os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
545 	{
546 		wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
547 			   "the current R0KH-ID");
548 		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
549 			    parse.r0kh_id, parse.r0kh_id_len);
550 		wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID",
551 			    sm->r0kh_id, sm->r0kh_id_len);
552 		return -1;
553 	}
554 
555 	if (parse.r1kh_id == NULL) {
556 		wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE");
557 		return -1;
558 	}
559 
560 	if (parse.rsn_pmkid == NULL ||
561 	    os_memcmp_const(parse.rsn_pmkid, sm->pmk_r0_name, WPA_PMK_NAME_LEN))
562 	{
563 		wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name (PMKID) in "
564 			   "RSNIE");
565 		return -1;
566 	}
567 
568 	os_memcpy(sm->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN);
569 	wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", sm->r1kh_id, FT_R1KH_ID_LEN);
570 	wpa_hexdump(MSG_DEBUG, "FT: SNonce", sm->snonce, WPA_NONCE_LEN);
571 	wpa_hexdump(MSG_DEBUG, "FT: ANonce", anonce, WPA_NONCE_LEN);
572 	os_memcpy(sm->anonce, anonce, WPA_NONCE_LEN);
573 	if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name,
574 			      sm->r1kh_id, sm->own_addr, sm->pmk_r1,
575 			      sm->pmk_r1_name) < 0)
576 		return -1;
577 	sm->pmk_r1_len = sm->pmk_r0_len;
578 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", sm->pmk_r1, sm->pmk_r1_len);
579 	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name",
580 		    sm->pmk_r1_name, WPA_PMK_NAME_LEN);
581 
582 	bssid = target_ap;
583 	if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce,
584 			      anonce, sm->own_addr, bssid,
585 			      sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt,
586 			      sm->pairwise_cipher) < 0)
587 		return -1;
588 
589 	if (wpa_key_mgmt_fils(sm->key_mgmt)) {
590 		kck = sm->ptk.kck2;
591 		kck_len = sm->ptk.kck2_len;
592 	} else {
593 		kck = sm->ptk.kck;
594 		kck_len = sm->ptk.kck_len;
595 	}
596 	ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, anonce,
597 				    sm->pmk_r1_name,
598 				    kck, kck_len, bssid,
599 				    ric_ies, ric_ies_len,
600 				    parse.mdie ? parse.mdie - 2 : NULL);
601 	if (ft_ies) {
602 		wpa_sm_update_ft_ies(sm, sm->mobility_domain,
603 				     ft_ies, ft_ies_len);
604 		os_free(ft_ies);
605 	}
606 
607 	wpa_sm_mark_authenticated(sm, bssid);
608 	ret = wpa_ft_install_ptk(sm, bssid);
609 	if (ret) {
610 		/*
611 		 * Some drivers do not support key configuration when we are
612 		 * not associated with the target AP. Work around this by
613 		 * trying again after the following reassociation gets
614 		 * completed.
615 		 */
616 		wpa_printf(MSG_DEBUG, "FT: Failed to set PTK prior to "
617 			   "association - try again after reassociation");
618 		sm->set_ptk_after_assoc = 1;
619 	} else
620 		sm->set_ptk_after_assoc = 0;
621 
622 	sm->ft_completed = 1;
623 	if (ft_action) {
624 		/*
625 		 * The caller is expected trigger re-association with the
626 		 * Target AP.
627 		 */
628 		os_memcpy(sm->bssid, target_ap, ETH_ALEN);
629 	}
630 
631 	return 0;
632 }
633 
634 
635 int wpa_ft_is_completed(struct wpa_sm *sm)
636 {
637 	if (sm == NULL)
638 		return 0;
639 
640 	if (!wpa_key_mgmt_ft(sm->key_mgmt))
641 		return 0;
642 
643 	return sm->ft_completed;
644 }
645 
646 
647 void wpa_reset_ft_completed(struct wpa_sm *sm)
648 {
649 	if (sm != NULL)
650 		sm->ft_completed = 0;
651 }
652 
653 
654 static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
655 				      size_t gtk_elem_len)
656 {
657 	u8 gtk[32];
658 	int keyidx;
659 	enum wpa_alg alg;
660 	size_t gtk_len, keylen, rsc_len;
661 	const u8 *kek;
662 	size_t kek_len;
663 
664 	if (wpa_key_mgmt_fils(sm->key_mgmt)) {
665 		kek = sm->ptk.kek2;
666 		kek_len = sm->ptk.kek2_len;
667 	} else {
668 		kek = sm->ptk.kek;
669 		kek_len = sm->ptk.kek_len;
670 	}
671 
672 	if (gtk_elem == NULL) {
673 		wpa_printf(MSG_DEBUG, "FT: No GTK included in FTIE");
674 		return 0;
675 	}
676 
677 	wpa_hexdump_key(MSG_DEBUG, "FT: Received GTK in Reassoc Resp",
678 			gtk_elem, gtk_elem_len);
679 
680 	if (gtk_elem_len < 11 + 24 || (gtk_elem_len - 11) % 8 ||
681 	    gtk_elem_len - 19 > sizeof(gtk)) {
682 		wpa_printf(MSG_DEBUG, "FT: Invalid GTK sub-elem "
683 			   "length %lu", (unsigned long) gtk_elem_len);
684 		return -1;
685 	}
686 	gtk_len = gtk_elem_len - 19;
687 	if (aes_unwrap(kek, kek_len, gtk_len / 8, gtk_elem + 11, gtk)) {
688 		wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
689 			   "decrypt GTK");
690 		return -1;
691 	}
692 
693 	keylen = wpa_cipher_key_len(sm->group_cipher);
694 	rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
695 	alg = wpa_cipher_to_alg(sm->group_cipher);
696 	if (alg == WPA_ALG_NONE) {
697 		wpa_printf(MSG_WARNING, "WPA: Unsupported Group Cipher %d",
698 			   sm->group_cipher);
699 		return -1;
700 	}
701 
702 	if (gtk_len < keylen) {
703 		wpa_printf(MSG_DEBUG, "FT: Too short GTK in FTIE");
704 		return -1;
705 	}
706 
707 	/* Key Info[2] | Key Length[1] | RSC[8] | Key[5..32]. */
708 
709 	keyidx = WPA_GET_LE16(gtk_elem) & 0x03;
710 
711 	if (gtk_elem[2] != keylen) {
712 		wpa_printf(MSG_DEBUG, "FT: GTK length mismatch: received %d "
713 			   "negotiated %lu",
714 			   gtk_elem[2], (unsigned long) keylen);
715 		return -1;
716 	}
717 
718 	wpa_hexdump_key(MSG_DEBUG, "FT: GTK from Reassoc Resp", gtk, keylen);
719 	if (sm->group_cipher == WPA_CIPHER_TKIP) {
720 		/* Swap Tx/Rx keys for Michael MIC */
721 		u8 tmp[8];
722 		os_memcpy(tmp, gtk + 16, 8);
723 		os_memcpy(gtk + 16, gtk + 24, 8);
724 		os_memcpy(gtk + 24, tmp, 8);
725 	}
726 	if (wpa_sm_set_key(sm, alg, broadcast_ether_addr, keyidx, 0,
727 			   gtk_elem + 3, rsc_len, gtk, keylen) < 0) {
728 		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the "
729 			   "driver.");
730 		return -1;
731 	}
732 
733 	return 0;
734 }
735 
736 
737 #ifdef CONFIG_IEEE80211W
738 static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
739 				       size_t igtk_elem_len)
740 {
741 	u8 igtk[WPA_IGTK_MAX_LEN];
742 	size_t igtk_len;
743 	u16 keyidx;
744 	const u8 *kek;
745 	size_t kek_len;
746 
747 	if (wpa_key_mgmt_fils(sm->key_mgmt)) {
748 		kek = sm->ptk.kek2;
749 		kek_len = sm->ptk.kek2_len;
750 	} else {
751 		kek = sm->ptk.kek;
752 		kek_len = sm->ptk.kek_len;
753 	}
754 
755 	if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC &&
756 	    sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_128 &&
757 	    sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_256 &&
758 	    sm->mgmt_group_cipher != WPA_CIPHER_BIP_CMAC_256)
759 		return 0;
760 
761 	if (igtk_elem == NULL) {
762 		wpa_printf(MSG_DEBUG, "FT: No IGTK included in FTIE");
763 		return 0;
764 	}
765 
766 	wpa_hexdump_key(MSG_DEBUG, "FT: Received IGTK in Reassoc Resp",
767 			igtk_elem, igtk_elem_len);
768 
769 	igtk_len = wpa_cipher_key_len(sm->mgmt_group_cipher);
770 	if (igtk_elem_len != 2 + 6 + 1 + igtk_len + 8) {
771 		wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem "
772 			   "length %lu", (unsigned long) igtk_elem_len);
773 		return -1;
774 	}
775 	if (igtk_elem[8] != igtk_len) {
776 		wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem Key Length "
777 			   "%d", igtk_elem[8]);
778 		return -1;
779 	}
780 
781 	if (aes_unwrap(kek, kek_len, igtk_len / 8, igtk_elem + 9, igtk)) {
782 		wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
783 			   "decrypt IGTK");
784 		return -1;
785 	}
786 
787 	/* KeyID[2] | IPN[6] | Key Length[1] | Key[16+8] */
788 
789 	keyidx = WPA_GET_LE16(igtk_elem);
790 
791 	wpa_hexdump_key(MSG_DEBUG, "FT: IGTK from Reassoc Resp", igtk,
792 			igtk_len);
793 	if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
794 			   broadcast_ether_addr, keyidx, 0,
795 			   igtk_elem + 2, 6, igtk, igtk_len) < 0) {
796 		wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the "
797 			   "driver.");
798 		os_memset(igtk, 0, sizeof(igtk));
799 		return -1;
800 	}
801 	os_memset(igtk, 0, sizeof(igtk));
802 
803 	return 0;
804 }
805 #endif /* CONFIG_IEEE80211W */
806 
807 
808 int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
809 				 size_t ies_len, const u8 *src_addr)
810 {
811 	struct wpa_ft_ies parse;
812 	struct rsn_mdie *mdie;
813 	unsigned int count;
814 	u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
815 	const u8 *kck;
816 	size_t kck_len;
817 	int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
818 	const u8 *anonce, *snonce, *fte_mic;
819 	u8 fte_elem_count;
820 
821 	wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len);
822 
823 	if (!wpa_key_mgmt_ft(sm->key_mgmt)) {
824 		wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not "
825 			   "enabled for this connection");
826 		return -1;
827 	}
828 
829 	if (sm->ft_reassoc_completed) {
830 		wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission");
831 		return 0;
832 	}
833 
834 	if (wpa_ft_parse_ies(ies, ies_len, &parse, use_sha384) < 0) {
835 		wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
836 		return -1;
837 	}
838 
839 	mdie = (struct rsn_mdie *) parse.mdie;
840 	if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
841 	    os_memcmp(mdie->mobility_domain, sm->mobility_domain,
842 		      MOBILITY_DOMAIN_ID_LEN) != 0) {
843 		wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
844 		return -1;
845 	}
846 
847 	if (use_sha384) {
848 		struct rsn_ftie_sha384 *ftie;
849 
850 		ftie = (struct rsn_ftie_sha384 *) parse.ftie;
851 		if (!ftie || parse.ftie_len < sizeof(*ftie)) {
852 			wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
853 			return -1;
854 		}
855 
856 		anonce = ftie->anonce;
857 		snonce = ftie->snonce;
858 		fte_elem_count = ftie->mic_control[1];
859 		fte_mic = ftie->mic;
860 	} else {
861 		struct rsn_ftie *ftie;
862 
863 		ftie = (struct rsn_ftie *) parse.ftie;
864 		if (!ftie || parse.ftie_len < sizeof(*ftie)) {
865 			wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
866 			return -1;
867 		}
868 
869 		anonce = ftie->anonce;
870 		snonce = ftie->snonce;
871 		fte_elem_count = ftie->mic_control[1];
872 		fte_mic = ftie->mic;
873 	}
874 
875 	if (os_memcmp(snonce, sm->snonce, WPA_NONCE_LEN) != 0) {
876 		wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE");
877 		wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
878 			    snonce, WPA_NONCE_LEN);
879 		wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce",
880 			    sm->snonce, WPA_NONCE_LEN);
881 		return -1;
882 	}
883 
884 	if (os_memcmp(anonce, sm->anonce, WPA_NONCE_LEN) != 0) {
885 		wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE");
886 		wpa_hexdump(MSG_DEBUG, "FT: Received ANonce",
887 			    anonce, WPA_NONCE_LEN);
888 		wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce",
889 			    sm->anonce, WPA_NONCE_LEN);
890 		return -1;
891 	}
892 
893 	if (parse.r0kh_id == NULL) {
894 		wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE");
895 		return -1;
896 	}
897 
898 	if (parse.r0kh_id_len != sm->r0kh_id_len ||
899 	    os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
900 	{
901 		wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
902 			   "the current R0KH-ID");
903 		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
904 			    parse.r0kh_id, parse.r0kh_id_len);
905 		wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID",
906 			    sm->r0kh_id, sm->r0kh_id_len);
907 		return -1;
908 	}
909 
910 	if (parse.r1kh_id == NULL) {
911 		wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE");
912 		return -1;
913 	}
914 
915 	if (os_memcmp_const(parse.r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN) != 0) {
916 		wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
917 			   "ReassocResp");
918 		return -1;
919 	}
920 
921 	if (parse.rsn_pmkid == NULL ||
922 	    os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN))
923 	{
924 		wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in "
925 			   "RSNIE (pmkid=%d)", !!parse.rsn_pmkid);
926 		return -1;
927 	}
928 
929 	count = 3;
930 	if (parse.ric)
931 		count += ieee802_11_ie_count(parse.ric, parse.ric_len);
932 	if (fte_elem_count != count) {
933 		wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC "
934 			   "Control: received %u expected %u",
935 			   fte_elem_count, count);
936 		return -1;
937 	}
938 
939 	if (wpa_key_mgmt_fils(sm->key_mgmt)) {
940 		kck = sm->ptk.kck2;
941 		kck_len = sm->ptk.kck2_len;
942 	} else {
943 		kck = sm->ptk.kck;
944 		kck_len = sm->ptk.kck_len;
945 	}
946 
947 	if (wpa_ft_mic(kck, kck_len, sm->own_addr, src_addr, 6,
948 		       parse.mdie - 2, parse.mdie_len + 2,
949 		       parse.ftie - 2, parse.ftie_len + 2,
950 		       parse.rsn - 2, parse.rsn_len + 2,
951 		       parse.ric, parse.ric_len,
952 		       mic) < 0) {
953 		wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
954 		return -1;
955 	}
956 
957 	if (os_memcmp_const(mic, fte_mic, 16) != 0) {
958 		wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
959 		wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", fte_mic, 16);
960 		wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16);
961 		return -1;
962 	}
963 
964 	sm->ft_reassoc_completed = 1;
965 
966 	if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0)
967 		return -1;
968 
969 #ifdef CONFIG_IEEE80211W
970 	if (wpa_ft_process_igtk_subelem(sm, parse.igtk, parse.igtk_len) < 0)
971 		return -1;
972 #endif /* CONFIG_IEEE80211W */
973 
974 	if (sm->set_ptk_after_assoc) {
975 		wpa_printf(MSG_DEBUG, "FT: Try to set PTK again now that we "
976 			   "are associated");
977 		if (wpa_ft_install_ptk(sm, src_addr) < 0)
978 			return -1;
979 		sm->set_ptk_after_assoc = 0;
980 	}
981 
982 	if (parse.ric) {
983 		wpa_hexdump(MSG_MSGDUMP, "FT: RIC Response",
984 			    parse.ric, parse.ric_len);
985 		/* TODO: parse response and inform driver about results when
986 		 * using wpa_supplicant SME */
987 	}
988 
989 	wpa_printf(MSG_DEBUG, "FT: Completed successfully");
990 
991 	return 0;
992 }
993 
994 
995 /**
996  * wpa_ft_start_over_ds - Generate over-the-DS auth request
997  * @sm: Pointer to WPA state machine data from wpa_sm_init()
998  * @target_ap: Target AP Address
999  * @mdie: Mobility Domain IE from the target AP
1000  * Returns: 0 on success, -1 on failure
1001  */
1002 int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap,
1003 			 const u8 *mdie)
1004 {
1005 	u8 *ft_ies;
1006 	size_t ft_ies_len;
1007 
1008 	wpa_printf(MSG_DEBUG, "FT: Request over-the-DS with " MACSTR,
1009 		   MAC2STR(target_ap));
1010 
1011 	/* Generate a new SNonce */
1012 	if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
1013 		wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce");
1014 		return -1;
1015 	}
1016 
1017 	ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name,
1018 				    NULL, 0, target_ap, NULL, 0, mdie);
1019 	if (ft_ies) {
1020 		sm->over_the_ds_in_progress = 1;
1021 		os_memcpy(sm->target_ap, target_ap, ETH_ALEN);
1022 		wpa_sm_send_ft_action(sm, 1, target_ap, ft_ies, ft_ies_len);
1023 		os_free(ft_ies);
1024 	}
1025 
1026 	return 0;
1027 }
1028 
1029 #endif /* CONFIG_IEEE80211R */
1030