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 "common/ocv.h" 18 #include "common/wpa_ctrl.h" 19 #include "drivers/driver.h" 20 #include "wpa.h" 21 #include "wpa_i.h" 22 #include "wpa_ie.h" 23 #include "pmksa_cache.h" 24 25 #ifdef CONFIG_IEEE80211R 26 27 #ifdef CONFIG_PASN 28 static void wpa_ft_pasn_store_r1kh(struct wpa_sm *sm, const u8 *bssid); 29 #else /* CONFIG_PASN */ 30 static void wpa_ft_pasn_store_r1kh(struct wpa_sm *sm, const u8 *bssid) 31 { 32 } 33 #endif /* CONFIG_PASN */ 34 35 36 int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, 37 const struct wpa_eapol_key *key, struct wpa_ptk *ptk) 38 { 39 u8 ptk_name[WPA_PMK_NAME_LEN]; 40 const u8 *anonce = key->key_nonce; 41 int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt); 42 const u8 *mpmk; 43 size_t mpmk_len, kdk_len; 44 45 if (sm->xxkey_len > 0) { 46 mpmk = sm->xxkey; 47 mpmk_len = sm->xxkey_len; 48 } else if (sm->cur_pmksa) { 49 mpmk = sm->cur_pmksa->pmk; 50 mpmk_len = sm->cur_pmksa->pmk_len; 51 } else { 52 wpa_printf(MSG_DEBUG, "FT: XXKey not available for key " 53 "derivation"); 54 return -1; 55 } 56 57 sm->pmk_r0_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN; 58 if (wpa_derive_pmk_r0(mpmk, mpmk_len, sm->ssid, 59 sm->ssid_len, sm->mobility_domain, 60 sm->r0kh_id, sm->r0kh_id_len, sm->own_addr, 61 sm->pmk_r0, sm->pmk_r0_name, use_sha384) < 0) 62 return -1; 63 sm->pmk_r1_len = sm->pmk_r0_len; 64 if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name, 65 sm->r1kh_id, sm->own_addr, sm->pmk_r1, 66 sm->pmk_r1_name) < 0) 67 return -1; 68 69 wpa_ft_pasn_store_r1kh(sm, src_addr); 70 71 if (sm->force_kdk_derivation || 72 (sm->secure_ltf && 73 ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF))) 74 kdk_len = WPA_KDK_MAX_LEN; 75 else 76 kdk_len = 0; 77 78 return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce, 79 sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk, 80 ptk_name, sm->key_mgmt, sm->pairwise_cipher, 81 kdk_len); 82 } 83 84 85 /** 86 * wpa_sm_set_ft_params - Set FT (IEEE 802.11r) parameters 87 * @sm: Pointer to WPA state machine data from wpa_sm_init() 88 * @ies: Association Response IEs or %NULL to clear FT parameters 89 * @ies_len: Length of ies buffer in octets 90 * Returns: 0 on success, -1 on failure 91 */ 92 int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len) 93 { 94 struct wpa_ft_ies ft; 95 int use_sha384; 96 97 if (sm == NULL) 98 return 0; 99 100 if (!get_ie(ies, ies_len, WLAN_EID_MOBILITY_DOMAIN)) { 101 os_free(sm->assoc_resp_ies); 102 sm->assoc_resp_ies = NULL; 103 sm->assoc_resp_ies_len = 0; 104 os_memset(sm->mobility_domain, 0, MOBILITY_DOMAIN_ID_LEN); 105 os_memset(sm->r0kh_id, 0, FT_R0KH_ID_MAX_LEN); 106 sm->r0kh_id_len = 0; 107 os_memset(sm->r1kh_id, 0, FT_R1KH_ID_LEN); 108 return 0; 109 } 110 111 use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt); 112 if (wpa_ft_parse_ies(ies, ies_len, &ft, use_sha384) < 0) 113 return -1; 114 115 if (ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) 116 return -1; 117 118 wpa_hexdump(MSG_DEBUG, "FT: Mobility domain", 119 ft.mdie, MOBILITY_DOMAIN_ID_LEN); 120 os_memcpy(sm->mobility_domain, ft.mdie, MOBILITY_DOMAIN_ID_LEN); 121 sm->mdie_ft_capab = ft.mdie[MOBILITY_DOMAIN_ID_LEN]; 122 wpa_printf(MSG_DEBUG, "FT: Capability and Policy: 0x%02x", 123 sm->mdie_ft_capab); 124 125 if (ft.r0kh_id) { 126 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID", 127 ft.r0kh_id, ft.r0kh_id_len); 128 os_memcpy(sm->r0kh_id, ft.r0kh_id, ft.r0kh_id_len); 129 sm->r0kh_id_len = ft.r0kh_id_len; 130 } else { 131 /* FIX: When should R0KH-ID be cleared? We need to keep the 132 * old R0KH-ID in order to be able to use this during FT. */ 133 /* 134 * os_memset(sm->r0kh_id, 0, FT_R0KH_ID_LEN); 135 * sm->r0kh_id_len = 0; 136 */ 137 } 138 139 if (ft.r1kh_id) { 140 wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", 141 ft.r1kh_id, FT_R1KH_ID_LEN); 142 os_memcpy(sm->r1kh_id, ft.r1kh_id, FT_R1KH_ID_LEN); 143 } else 144 os_memset(sm->r1kh_id, 0, FT_R1KH_ID_LEN); 145 146 os_free(sm->assoc_resp_ies); 147 sm->assoc_resp_ies = os_malloc(ft.mdie_len + 2 + ft.ftie_len + 2); 148 if (sm->assoc_resp_ies) { 149 u8 *pos = sm->assoc_resp_ies; 150 151 os_memcpy(pos, ft.mdie - 2, ft.mdie_len + 2); 152 pos += ft.mdie_len + 2; 153 154 if (ft.ftie) { 155 os_memcpy(pos, ft.ftie - 2, ft.ftie_len + 2); 156 pos += ft.ftie_len + 2; 157 } 158 sm->assoc_resp_ies_len = pos - sm->assoc_resp_ies; 159 wpa_hexdump(MSG_DEBUG, "FT: Stored MDIE and FTIE from " 160 "(Re)Association Response", 161 sm->assoc_resp_ies, sm->assoc_resp_ies_len); 162 } 163 164 return 0; 165 } 166 167 168 /** 169 * wpa_ft_gen_req_ies - Generate FT (IEEE 802.11r) IEs for Auth/ReAssoc Request 170 * @sm: Pointer to WPA state machine data from wpa_sm_init() 171 * @len: Buffer for returning the length of the IEs 172 * @anonce: ANonce or %NULL if not yet available 173 * @pmk_name: PMKR0Name or PMKR1Name to be added into the RSN IE PMKID List 174 * @kck: 128-bit KCK for MIC or %NULL if no MIC is used 175 * @kck_len: KCK length in octets 176 * @target_ap: Target AP address 177 * @ric_ies: Optional IE(s), e.g., WMM TSPEC(s), for RIC-Request or %NULL 178 * @ric_ies_len: Length of ric_ies buffer in octets 179 * @ap_mdie: Mobility Domain IE from the target AP 180 * @omit_rsnxe: Whether RSNXE is omitted from Reassociation Request frame 181 * Returns: Pointer to buffer with IEs or %NULL on failure 182 * 183 * Caller is responsible for freeing the returned buffer with os_free(); 184 */ 185 static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, 186 const u8 *anonce, const u8 *pmk_name, 187 const u8 *kck, size_t kck_len, 188 const u8 *target_ap, 189 const u8 *ric_ies, size_t ric_ies_len, 190 const u8 *ap_mdie, int omit_rsnxe) 191 { 192 size_t buf_len; 193 u8 *buf, *pos, *ftie_len, *ftie_pos, *fte_mic, *elem_count; 194 struct rsn_mdie *mdie; 195 struct rsn_ie_hdr *rsnie; 196 int mdie_len; 197 u8 rsnxe[10]; 198 size_t rsnxe_len; 199 int rsnxe_used; 200 int res; 201 202 sm->ft_completed = 0; 203 sm->ft_reassoc_completed = 0; 204 205 buf_len = 2 + sizeof(struct rsn_mdie) + 2 + 206 sizeof(struct rsn_ftie_sha384) + 207 2 + sm->r0kh_id_len + ric_ies_len + 100; 208 buf = os_zalloc(buf_len); 209 if (buf == NULL) 210 return NULL; 211 pos = buf; 212 213 /* RSNIE[PMKR0Name/PMKR1Name] */ 214 rsnie = (struct rsn_ie_hdr *) pos; 215 rsnie->elem_id = WLAN_EID_RSN; 216 WPA_PUT_LE16(rsnie->version, RSN_VERSION); 217 pos = (u8 *) (rsnie + 1); 218 219 /* Group Suite Selector */ 220 if (!wpa_cipher_valid_group(sm->group_cipher)) { 221 wpa_printf(MSG_WARNING, "FT: Invalid group cipher (%d)", 222 sm->group_cipher); 223 os_free(buf); 224 return NULL; 225 } 226 RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN, 227 sm->group_cipher)); 228 pos += RSN_SELECTOR_LEN; 229 230 /* Pairwise Suite Count */ 231 WPA_PUT_LE16(pos, 1); 232 pos += 2; 233 234 /* Pairwise Suite List */ 235 if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) { 236 wpa_printf(MSG_WARNING, "FT: Invalid pairwise cipher (%d)", 237 sm->pairwise_cipher); 238 os_free(buf); 239 return NULL; 240 } 241 RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN, 242 sm->pairwise_cipher)); 243 pos += RSN_SELECTOR_LEN; 244 245 /* Authenticated Key Management Suite Count */ 246 WPA_PUT_LE16(pos, 1); 247 pos += 2; 248 249 /* Authenticated Key Management Suite List */ 250 if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) 251 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X); 252 #ifdef CONFIG_SHA384 253 else if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X_SHA384) 254 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384); 255 #endif /* CONFIG_SHA384 */ 256 else if (sm->key_mgmt == WPA_KEY_MGMT_FT_PSK) 257 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK); 258 else if (sm->key_mgmt == WPA_KEY_MGMT_FT_SAE) 259 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE); 260 #ifdef CONFIG_FILS 261 else if (sm->key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA256) 262 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256); 263 else if (sm->key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA384) 264 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384); 265 #endif /* CONFIG_FILS */ 266 else { 267 wpa_printf(MSG_WARNING, "FT: Invalid key management type (%d)", 268 sm->key_mgmt); 269 os_free(buf); 270 return NULL; 271 } 272 pos += RSN_SELECTOR_LEN; 273 274 /* RSN Capabilities */ 275 WPA_PUT_LE16(pos, rsn_supp_capab(sm)); 276 pos += 2; 277 278 /* PMKID Count */ 279 WPA_PUT_LE16(pos, 1); 280 pos += 2; 281 282 /* PMKID List [PMKR0Name/PMKR1Name] */ 283 os_memcpy(pos, pmk_name, WPA_PMK_NAME_LEN); 284 pos += WPA_PMK_NAME_LEN; 285 286 /* Management Group Cipher Suite */ 287 switch (sm->mgmt_group_cipher) { 288 case WPA_CIPHER_AES_128_CMAC: 289 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); 290 pos += RSN_SELECTOR_LEN; 291 break; 292 case WPA_CIPHER_BIP_GMAC_128: 293 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_128); 294 pos += RSN_SELECTOR_LEN; 295 break; 296 case WPA_CIPHER_BIP_GMAC_256: 297 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_GMAC_256); 298 pos += RSN_SELECTOR_LEN; 299 break; 300 case WPA_CIPHER_BIP_CMAC_256: 301 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_BIP_CMAC_256); 302 pos += RSN_SELECTOR_LEN; 303 break; 304 } 305 306 rsnie->len = (pos - (u8 *) rsnie) - 2; 307 308 /* MDIE */ 309 mdie_len = wpa_ft_add_mdie(sm, pos, buf_len - (pos - buf), ap_mdie); 310 if (mdie_len <= 0) { 311 os_free(buf); 312 return NULL; 313 } 314 mdie = (struct rsn_mdie *) (pos + 2); 315 pos += mdie_len; 316 317 /* FTIE[SNonce, [R1KH-ID,] R0KH-ID ] */ 318 ftie_pos = pos; 319 *pos++ = WLAN_EID_FAST_BSS_TRANSITION; 320 ftie_len = pos++; 321 rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) && anonce && 322 (sm->sae_pwe == 1 || sm->sae_pwe == 2); 323 #ifdef CONFIG_TESTING_OPTIONS 324 if (anonce && sm->ft_rsnxe_used) { 325 rsnxe_used = sm->ft_rsnxe_used == 1; 326 wpa_printf(MSG_DEBUG, "TESTING: FT: Force RSNXE Used %d", 327 rsnxe_used); 328 } 329 #endif /* CONFIG_TESTING_OPTIONS */ 330 if (wpa_key_mgmt_sha384(sm->key_mgmt)) { 331 struct rsn_ftie_sha384 *ftie; 332 333 ftie = (struct rsn_ftie_sha384 *) pos; 334 ftie->mic_control[0] = !!rsnxe_used; 335 fte_mic = ftie->mic; 336 elem_count = &ftie->mic_control[1]; 337 pos += sizeof(*ftie); 338 os_memcpy(ftie->snonce, sm->snonce, WPA_NONCE_LEN); 339 if (anonce) 340 os_memcpy(ftie->anonce, anonce, WPA_NONCE_LEN); 341 } else { 342 struct rsn_ftie *ftie; 343 344 ftie = (struct rsn_ftie *) pos; 345 ftie->mic_control[0] = !!rsnxe_used; 346 fte_mic = ftie->mic; 347 elem_count = &ftie->mic_control[1]; 348 pos += sizeof(*ftie); 349 os_memcpy(ftie->snonce, sm->snonce, WPA_NONCE_LEN); 350 if (anonce) 351 os_memcpy(ftie->anonce, anonce, WPA_NONCE_LEN); 352 } 353 if (kck) { 354 /* R1KH-ID sub-element in third FT message */ 355 *pos++ = FTIE_SUBELEM_R1KH_ID; 356 *pos++ = FT_R1KH_ID_LEN; 357 os_memcpy(pos, sm->r1kh_id, FT_R1KH_ID_LEN); 358 pos += FT_R1KH_ID_LEN; 359 } 360 /* R0KH-ID sub-element */ 361 *pos++ = FTIE_SUBELEM_R0KH_ID; 362 *pos++ = sm->r0kh_id_len; 363 os_memcpy(pos, sm->r0kh_id, sm->r0kh_id_len); 364 pos += sm->r0kh_id_len; 365 #ifdef CONFIG_OCV 366 if (kck && wpa_sm_ocv_enabled(sm)) { 367 /* OCI sub-element in the third FT message */ 368 struct wpa_channel_info ci; 369 370 if (wpa_sm_channel_info(sm, &ci) != 0) { 371 wpa_printf(MSG_WARNING, 372 "Failed to get channel info for OCI element in FTE"); 373 os_free(buf); 374 return NULL; 375 } 376 #ifdef CONFIG_TESTING_OPTIONS 377 if (sm->oci_freq_override_ft_assoc) { 378 wpa_printf(MSG_INFO, 379 "TEST: Override OCI KDE frequency %d -> %d MHz", 380 ci.frequency, sm->oci_freq_override_ft_assoc); 381 ci.frequency = sm->oci_freq_override_ft_assoc; 382 } 383 #endif /* CONFIG_TESTING_OPTIONS */ 384 385 *pos++ = FTIE_SUBELEM_OCI; 386 *pos++ = OCV_OCI_LEN; 387 if (ocv_insert_oci(&ci, &pos) < 0) { 388 os_free(buf); 389 return NULL; 390 } 391 } 392 #endif /* CONFIG_OCV */ 393 *ftie_len = pos - ftie_len - 1; 394 395 if (ric_ies) { 396 /* RIC Request */ 397 os_memcpy(pos, ric_ies, ric_ies_len); 398 pos += ric_ies_len; 399 } 400 401 if (omit_rsnxe) { 402 rsnxe_len = 0; 403 } else { 404 res = wpa_gen_rsnxe(sm, rsnxe, sizeof(rsnxe)); 405 if (res < 0) { 406 os_free(buf); 407 return NULL; 408 } 409 rsnxe_len = res; 410 } 411 412 if (kck) { 413 /* 414 * IEEE Std 802.11r-2008, 11A.8.4 415 * MIC shall be calculated over: 416 * non-AP STA MAC address 417 * Target AP MAC address 418 * Transaction seq number (5 for ReassocReq, 3 otherwise) 419 * RSN IE 420 * MDIE 421 * FTIE (with MIC field set to 0) 422 * RIC-Request (if present) 423 * RSNXE (if present) 424 */ 425 /* Information element count */ 426 *elem_count = 3 + ieee802_11_ie_count(ric_ies, ric_ies_len); 427 if (rsnxe_len) 428 *elem_count += 1; 429 if (wpa_ft_mic(kck, kck_len, sm->own_addr, target_ap, 5, 430 ((u8 *) mdie) - 2, 2 + sizeof(*mdie), 431 ftie_pos, 2 + *ftie_len, 432 (u8 *) rsnie, 2 + rsnie->len, ric_ies, 433 ric_ies_len, rsnxe_len ? rsnxe : NULL, rsnxe_len, 434 fte_mic) < 0) { 435 wpa_printf(MSG_INFO, "FT: Failed to calculate MIC"); 436 os_free(buf); 437 return NULL; 438 } 439 } 440 441 *len = pos - buf; 442 443 return buf; 444 } 445 446 447 static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid) 448 { 449 int keylen; 450 enum wpa_alg alg; 451 u8 null_rsc[6] = { 0, 0, 0, 0, 0, 0 }; 452 453 wpa_printf(MSG_DEBUG, "FT: Installing PTK to the driver."); 454 455 if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) { 456 wpa_printf(MSG_WARNING, "FT: Unsupported pairwise cipher %d", 457 sm->pairwise_cipher); 458 return -1; 459 } 460 461 alg = wpa_cipher_to_alg(sm->pairwise_cipher); 462 keylen = wpa_cipher_key_len(sm->pairwise_cipher); 463 464 if (wpa_sm_set_key(sm, alg, bssid, 0, 1, null_rsc, sizeof(null_rsc), 465 (u8 *) sm->ptk.tk, keylen, 466 KEY_FLAG_PAIRWISE_RX_TX) < 0) { 467 wpa_printf(MSG_WARNING, "FT: Failed to set PTK to the driver"); 468 return -1; 469 } 470 471 wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher, 472 sm->dot11RSNAConfigPMKLifetime, &sm->ptk); 473 return 0; 474 } 475 476 477 /** 478 * wpa_ft_prepare_auth_request - Generate over-the-air auth request 479 * @sm: Pointer to WPA state machine data from wpa_sm_init() 480 * @mdie: Target AP MDIE 481 * Returns: 0 on success, -1 on failure 482 */ 483 int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie) 484 { 485 u8 *ft_ies; 486 size_t ft_ies_len; 487 488 /* Generate a new SNonce */ 489 if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) { 490 wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce"); 491 return -1; 492 } 493 494 ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name, 495 NULL, 0, sm->bssid, NULL, 0, mdie, 0); 496 if (ft_ies) { 497 wpa_sm_update_ft_ies(sm, sm->mobility_domain, 498 ft_ies, ft_ies_len); 499 os_free(ft_ies); 500 } 501 502 return 0; 503 } 504 505 506 int wpa_ft_add_mdie(struct wpa_sm *sm, u8 *buf, size_t buf_len, 507 const u8 *ap_mdie) 508 { 509 u8 *pos = buf; 510 struct rsn_mdie *mdie; 511 512 if (buf_len < 2 + sizeof(*mdie)) { 513 wpa_printf(MSG_INFO, 514 "FT: Failed to add MDIE: short buffer, length=%zu", 515 buf_len); 516 return 0; 517 } 518 519 *pos++ = WLAN_EID_MOBILITY_DOMAIN; 520 *pos++ = sizeof(*mdie); 521 mdie = (struct rsn_mdie *) pos; 522 os_memcpy(mdie->mobility_domain, sm->mobility_domain, 523 MOBILITY_DOMAIN_ID_LEN); 524 mdie->ft_capab = ap_mdie && ap_mdie[1] >= 3 ? ap_mdie[4] : 525 sm->mdie_ft_capab; 526 527 return 2 + sizeof(*mdie); 528 } 529 530 531 const u8 * wpa_sm_get_ft_md(struct wpa_sm *sm) 532 { 533 return sm->mobility_domain; 534 } 535 536 537 int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, 538 int ft_action, const u8 *target_ap, 539 const u8 *ric_ies, size_t ric_ies_len) 540 { 541 u8 *ft_ies; 542 size_t ft_ies_len; 543 struct wpa_ft_ies parse; 544 struct rsn_mdie *mdie; 545 u8 ptk_name[WPA_PMK_NAME_LEN]; 546 int ret; 547 const u8 *bssid; 548 const u8 *kck; 549 size_t kck_len, kdk_len; 550 int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt); 551 const u8 *anonce, *snonce; 552 553 wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len); 554 wpa_hexdump(MSG_DEBUG, "FT: RIC IEs", ric_ies, ric_ies_len); 555 556 if (ft_action) { 557 if (!sm->over_the_ds_in_progress) { 558 wpa_printf(MSG_DEBUG, "FT: No over-the-DS in progress " 559 "- drop FT Action Response"); 560 return -1; 561 } 562 563 if (os_memcmp(target_ap, sm->target_ap, ETH_ALEN) != 0) { 564 wpa_printf(MSG_DEBUG, "FT: No over-the-DS in progress " 565 "with this Target AP - drop FT Action " 566 "Response"); 567 return -1; 568 } 569 } 570 571 if (!wpa_key_mgmt_ft(sm->key_mgmt)) { 572 wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not " 573 "enabled for this connection"); 574 return -1; 575 } 576 577 if (wpa_ft_parse_ies(ies, ies_len, &parse, use_sha384) < 0) { 578 wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs"); 579 return -1; 580 } 581 582 mdie = (struct rsn_mdie *) parse.mdie; 583 if (mdie == NULL || parse.mdie_len < sizeof(*mdie) || 584 os_memcmp(mdie->mobility_domain, sm->mobility_domain, 585 MOBILITY_DOMAIN_ID_LEN) != 0) { 586 wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); 587 return -1; 588 } 589 590 if (use_sha384) { 591 struct rsn_ftie_sha384 *ftie; 592 593 ftie = (struct rsn_ftie_sha384 *) parse.ftie; 594 if (!ftie || parse.ftie_len < sizeof(*ftie)) { 595 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); 596 return -1; 597 } 598 599 anonce = ftie->anonce; 600 snonce = ftie->snonce; 601 } else { 602 struct rsn_ftie *ftie; 603 604 ftie = (struct rsn_ftie *) parse.ftie; 605 if (!ftie || parse.ftie_len < sizeof(*ftie)) { 606 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); 607 return -1; 608 } 609 610 anonce = ftie->anonce; 611 snonce = ftie->snonce; 612 } 613 614 if (os_memcmp(snonce, sm->snonce, WPA_NONCE_LEN) != 0) { 615 wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE"); 616 wpa_hexdump(MSG_DEBUG, "FT: Received SNonce", 617 snonce, WPA_NONCE_LEN); 618 wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", 619 sm->snonce, WPA_NONCE_LEN); 620 return -1; 621 } 622 623 if (parse.r0kh_id == NULL) { 624 wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE"); 625 return -1; 626 } 627 628 if (parse.r0kh_id_len != sm->r0kh_id_len || 629 os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) 630 { 631 wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with " 632 "the current R0KH-ID"); 633 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE", 634 parse.r0kh_id, parse.r0kh_id_len); 635 wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID", 636 sm->r0kh_id, sm->r0kh_id_len); 637 return -1; 638 } 639 640 if (parse.r1kh_id == NULL) { 641 wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE"); 642 return -1; 643 } 644 645 if (parse.rsn_pmkid == NULL || 646 os_memcmp_const(parse.rsn_pmkid, sm->pmk_r0_name, WPA_PMK_NAME_LEN)) 647 { 648 wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name (PMKID) in " 649 "RSNIE"); 650 return -1; 651 } 652 653 if (sm->mfp == 2 && !(parse.rsn_capab & WPA_CAPABILITY_MFPC)) { 654 wpa_printf(MSG_INFO, 655 "FT: Target AP does not support PMF, but local configuration requires that"); 656 return -1; 657 } 658 659 os_memcpy(sm->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN); 660 wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID", sm->r1kh_id, FT_R1KH_ID_LEN); 661 wpa_hexdump(MSG_DEBUG, "FT: SNonce", sm->snonce, WPA_NONCE_LEN); 662 wpa_hexdump(MSG_DEBUG, "FT: ANonce", anonce, WPA_NONCE_LEN); 663 os_memcpy(sm->anonce, anonce, WPA_NONCE_LEN); 664 if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name, 665 sm->r1kh_id, sm->own_addr, sm->pmk_r1, 666 sm->pmk_r1_name) < 0) 667 return -1; 668 sm->pmk_r1_len = sm->pmk_r0_len; 669 670 bssid = target_ap; 671 672 wpa_ft_pasn_store_r1kh(sm, bssid); 673 674 if (sm->force_kdk_derivation || 675 (sm->secure_ltf && 676 ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF))) 677 kdk_len = WPA_KDK_MAX_LEN; 678 else 679 kdk_len = 0; 680 681 if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, 682 anonce, sm->own_addr, bssid, 683 sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt, 684 sm->pairwise_cipher, 685 kdk_len) < 0) 686 return -1; 687 688 if (wpa_key_mgmt_fils(sm->key_mgmt)) { 689 kck = sm->ptk.kck2; 690 kck_len = sm->ptk.kck2_len; 691 } else { 692 kck = sm->ptk.kck; 693 kck_len = sm->ptk.kck_len; 694 } 695 ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, anonce, 696 sm->pmk_r1_name, 697 kck, kck_len, bssid, 698 ric_ies, ric_ies_len, 699 parse.mdie ? parse.mdie - 2 : NULL, 700 !sm->ap_rsnxe); 701 if (ft_ies) { 702 wpa_sm_update_ft_ies(sm, sm->mobility_domain, 703 ft_ies, ft_ies_len); 704 os_free(ft_ies); 705 } 706 707 wpa_sm_mark_authenticated(sm, bssid); 708 ret = wpa_ft_install_ptk(sm, bssid); 709 if (ret) { 710 /* 711 * Some drivers do not support key configuration when we are 712 * not associated with the target AP. Work around this by 713 * trying again after the following reassociation gets 714 * completed. 715 */ 716 wpa_printf(MSG_DEBUG, "FT: Failed to set PTK prior to " 717 "association - try again after reassociation"); 718 sm->set_ptk_after_assoc = 1; 719 } else 720 sm->set_ptk_after_assoc = 0; 721 722 sm->ft_completed = 1; 723 if (ft_action) { 724 /* 725 * The caller is expected trigger re-association with the 726 * Target AP. 727 */ 728 os_memcpy(sm->bssid, target_ap, ETH_ALEN); 729 } 730 731 return 0; 732 } 733 734 735 int wpa_ft_is_completed(struct wpa_sm *sm) 736 { 737 if (sm == NULL) 738 return 0; 739 740 if (!wpa_key_mgmt_ft(sm->key_mgmt)) 741 return 0; 742 743 return sm->ft_completed; 744 } 745 746 747 void wpa_reset_ft_completed(struct wpa_sm *sm) 748 { 749 if (sm != NULL) 750 sm->ft_completed = 0; 751 } 752 753 754 static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem, 755 size_t gtk_elem_len) 756 { 757 u8 gtk[32]; 758 int keyidx; 759 enum wpa_alg alg; 760 size_t gtk_len, keylen, rsc_len; 761 const u8 *kek; 762 size_t kek_len; 763 764 if (wpa_key_mgmt_fils(sm->key_mgmt)) { 765 kek = sm->ptk.kek2; 766 kek_len = sm->ptk.kek2_len; 767 } else { 768 kek = sm->ptk.kek; 769 kek_len = sm->ptk.kek_len; 770 } 771 772 if (gtk_elem == NULL) { 773 wpa_printf(MSG_DEBUG, "FT: No GTK included in FTIE"); 774 return 0; 775 } 776 777 wpa_hexdump_key(MSG_DEBUG, "FT: Received GTK in Reassoc Resp", 778 gtk_elem, gtk_elem_len); 779 780 if (gtk_elem_len < 11 + 24 || (gtk_elem_len - 11) % 8 || 781 gtk_elem_len - 19 > sizeof(gtk)) { 782 wpa_printf(MSG_DEBUG, "FT: Invalid GTK sub-elem " 783 "length %lu", (unsigned long) gtk_elem_len); 784 return -1; 785 } 786 gtk_len = gtk_elem_len - 19; 787 if (aes_unwrap(kek, kek_len, gtk_len / 8, gtk_elem + 11, gtk)) { 788 wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not " 789 "decrypt GTK"); 790 return -1; 791 } 792 793 keylen = wpa_cipher_key_len(sm->group_cipher); 794 rsc_len = wpa_cipher_rsc_len(sm->group_cipher); 795 alg = wpa_cipher_to_alg(sm->group_cipher); 796 if (alg == WPA_ALG_NONE) { 797 wpa_printf(MSG_WARNING, "WPA: Unsupported Group Cipher %d", 798 sm->group_cipher); 799 return -1; 800 } 801 802 if (gtk_len < keylen) { 803 wpa_printf(MSG_DEBUG, "FT: Too short GTK in FTIE"); 804 return -1; 805 } 806 807 /* Key Info[2] | Key Length[1] | RSC[8] | Key[5..32]. */ 808 809 keyidx = WPA_GET_LE16(gtk_elem) & 0x03; 810 811 if (gtk_elem[2] != keylen) { 812 wpa_printf(MSG_DEBUG, "FT: GTK length mismatch: received %d " 813 "negotiated %lu", 814 gtk_elem[2], (unsigned long) keylen); 815 return -1; 816 } 817 818 wpa_hexdump_key(MSG_DEBUG, "FT: GTK from Reassoc Resp", gtk, keylen); 819 if (sm->group_cipher == WPA_CIPHER_TKIP) { 820 /* Swap Tx/Rx keys for Michael MIC */ 821 u8 tmp[8]; 822 os_memcpy(tmp, gtk + 16, 8); 823 os_memcpy(gtk + 16, gtk + 24, 8); 824 os_memcpy(gtk + 24, tmp, 8); 825 } 826 if (wpa_sm_set_key(sm, alg, broadcast_ether_addr, keyidx, 0, 827 gtk_elem + 3, rsc_len, gtk, keylen, 828 KEY_FLAG_GROUP_RX) < 0) { 829 wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the " 830 "driver."); 831 return -1; 832 } 833 834 return 0; 835 } 836 837 838 static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem, 839 size_t igtk_elem_len) 840 { 841 u8 igtk[WPA_IGTK_MAX_LEN]; 842 size_t igtk_len; 843 u16 keyidx; 844 const u8 *kek; 845 size_t kek_len; 846 847 if (wpa_key_mgmt_fils(sm->key_mgmt)) { 848 kek = sm->ptk.kek2; 849 kek_len = sm->ptk.kek2_len; 850 } else { 851 kek = sm->ptk.kek; 852 kek_len = sm->ptk.kek_len; 853 } 854 855 if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC && 856 sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_128 && 857 sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_256 && 858 sm->mgmt_group_cipher != WPA_CIPHER_BIP_CMAC_256) 859 return 0; 860 861 if (igtk_elem == NULL) { 862 wpa_printf(MSG_DEBUG, "FT: No IGTK included in FTIE"); 863 return 0; 864 } 865 866 wpa_hexdump_key(MSG_DEBUG, "FT: Received IGTK in Reassoc Resp", 867 igtk_elem, igtk_elem_len); 868 869 igtk_len = wpa_cipher_key_len(sm->mgmt_group_cipher); 870 if (igtk_elem_len != 2 + 6 + 1 + igtk_len + 8) { 871 wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem " 872 "length %lu", (unsigned long) igtk_elem_len); 873 return -1; 874 } 875 if (igtk_elem[8] != igtk_len) { 876 wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem Key Length " 877 "%d", igtk_elem[8]); 878 return -1; 879 } 880 881 if (aes_unwrap(kek, kek_len, igtk_len / 8, igtk_elem + 9, igtk)) { 882 wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not " 883 "decrypt IGTK"); 884 return -1; 885 } 886 887 /* KeyID[2] | IPN[6] | Key Length[1] | Key[16+8] */ 888 889 keyidx = WPA_GET_LE16(igtk_elem); 890 891 wpa_hexdump_key(MSG_DEBUG, "FT: IGTK from Reassoc Resp", igtk, 892 igtk_len); 893 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), 894 broadcast_ether_addr, keyidx, 0, 895 igtk_elem + 2, 6, igtk, igtk_len, 896 KEY_FLAG_GROUP_RX) < 0) { 897 wpa_printf(MSG_WARNING, "WPA: Failed to set IGTK to the " 898 "driver."); 899 forced_memzero(igtk, sizeof(igtk)); 900 return -1; 901 } 902 forced_memzero(igtk, sizeof(igtk)); 903 904 return 0; 905 } 906 907 908 static int wpa_ft_process_bigtk_subelem(struct wpa_sm *sm, const u8 *bigtk_elem, 909 size_t bigtk_elem_len) 910 { 911 u8 bigtk[WPA_BIGTK_MAX_LEN]; 912 size_t bigtk_len; 913 u16 keyidx; 914 const u8 *kek; 915 size_t kek_len; 916 917 if (!sm->beacon_prot || !bigtk_elem || 918 (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC && 919 sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_128 && 920 sm->mgmt_group_cipher != WPA_CIPHER_BIP_GMAC_256 && 921 sm->mgmt_group_cipher != WPA_CIPHER_BIP_CMAC_256)) 922 return 0; 923 924 if (wpa_key_mgmt_fils(sm->key_mgmt)) { 925 kek = sm->ptk.kek2; 926 kek_len = sm->ptk.kek2_len; 927 } else { 928 kek = sm->ptk.kek; 929 kek_len = sm->ptk.kek_len; 930 } 931 932 wpa_hexdump_key(MSG_DEBUG, "FT: Received BIGTK in Reassoc Resp", 933 bigtk_elem, bigtk_elem_len); 934 935 bigtk_len = wpa_cipher_key_len(sm->mgmt_group_cipher); 936 if (bigtk_elem_len != 2 + 6 + 1 + bigtk_len + 8) { 937 wpa_printf(MSG_DEBUG, 938 "FT: Invalid BIGTK sub-elem length %lu", 939 (unsigned long) bigtk_elem_len); 940 return -1; 941 } 942 if (bigtk_elem[8] != bigtk_len) { 943 wpa_printf(MSG_DEBUG, 944 "FT: Invalid BIGTK sub-elem Key Length %d", 945 bigtk_elem[8]); 946 return -1; 947 } 948 949 if (aes_unwrap(kek, kek_len, bigtk_len / 8, bigtk_elem + 9, bigtk)) { 950 wpa_printf(MSG_WARNING, 951 "FT: AES unwrap failed - could not decrypt BIGTK"); 952 return -1; 953 } 954 955 /* KeyID[2] | IPN[6] | Key Length[1] | Key[16+8] */ 956 957 keyidx = WPA_GET_LE16(bigtk_elem); 958 959 wpa_hexdump_key(MSG_DEBUG, "FT: BIGTK from Reassoc Resp", bigtk, 960 bigtk_len); 961 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), 962 broadcast_ether_addr, keyidx, 0, 963 bigtk_elem + 2, 6, bigtk, bigtk_len, 964 KEY_FLAG_GROUP_RX) < 0) { 965 wpa_printf(MSG_WARNING, 966 "WPA: Failed to set BIGTK to the driver"); 967 forced_memzero(bigtk, sizeof(bigtk)); 968 return -1; 969 } 970 forced_memzero(bigtk, sizeof(bigtk)); 971 972 return 0; 973 } 974 975 976 int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, 977 size_t ies_len, const u8 *src_addr) 978 { 979 struct wpa_ft_ies parse; 980 struct rsn_mdie *mdie; 981 unsigned int count; 982 u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN]; 983 const u8 *kck; 984 size_t kck_len; 985 int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt); 986 const u8 *anonce, *snonce, *fte_mic; 987 u8 fte_elem_count; 988 int own_rsnxe_used, rsnxe_used; 989 990 wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len); 991 992 if (!wpa_key_mgmt_ft(sm->key_mgmt)) { 993 wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not " 994 "enabled for this connection"); 995 return -1; 996 } 997 998 if (sm->ft_reassoc_completed) { 999 wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission"); 1000 return 0; 1001 } 1002 1003 if (wpa_ft_parse_ies(ies, ies_len, &parse, use_sha384) < 0) { 1004 wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs"); 1005 return -1; 1006 } 1007 1008 mdie = (struct rsn_mdie *) parse.mdie; 1009 if (mdie == NULL || parse.mdie_len < sizeof(*mdie) || 1010 os_memcmp(mdie->mobility_domain, sm->mobility_domain, 1011 MOBILITY_DOMAIN_ID_LEN) != 0) { 1012 wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); 1013 return -1; 1014 } 1015 1016 if (use_sha384) { 1017 struct rsn_ftie_sha384 *ftie; 1018 1019 ftie = (struct rsn_ftie_sha384 *) parse.ftie; 1020 if (!ftie || parse.ftie_len < sizeof(*ftie)) { 1021 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); 1022 return -1; 1023 } 1024 1025 anonce = ftie->anonce; 1026 snonce = ftie->snonce; 1027 rsnxe_used = ftie->mic_control[0] & 0x01; 1028 fte_elem_count = ftie->mic_control[1]; 1029 fte_mic = ftie->mic; 1030 } else { 1031 struct rsn_ftie *ftie; 1032 1033 ftie = (struct rsn_ftie *) parse.ftie; 1034 if (!ftie || parse.ftie_len < sizeof(*ftie)) { 1035 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); 1036 return -1; 1037 } 1038 1039 anonce = ftie->anonce; 1040 snonce = ftie->snonce; 1041 rsnxe_used = ftie->mic_control[0] & 0x01; 1042 fte_elem_count = ftie->mic_control[1]; 1043 fte_mic = ftie->mic; 1044 } 1045 1046 if (os_memcmp(snonce, sm->snonce, WPA_NONCE_LEN) != 0) { 1047 wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE"); 1048 wpa_hexdump(MSG_DEBUG, "FT: Received SNonce", 1049 snonce, WPA_NONCE_LEN); 1050 wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", 1051 sm->snonce, WPA_NONCE_LEN); 1052 return -1; 1053 } 1054 1055 if (os_memcmp(anonce, sm->anonce, WPA_NONCE_LEN) != 0) { 1056 wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE"); 1057 wpa_hexdump(MSG_DEBUG, "FT: Received ANonce", 1058 anonce, WPA_NONCE_LEN); 1059 wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce", 1060 sm->anonce, WPA_NONCE_LEN); 1061 return -1; 1062 } 1063 1064 if (parse.r0kh_id == NULL) { 1065 wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE"); 1066 return -1; 1067 } 1068 1069 if (parse.r0kh_id_len != sm->r0kh_id_len || 1070 os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) 1071 { 1072 wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with " 1073 "the current R0KH-ID"); 1074 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE", 1075 parse.r0kh_id, parse.r0kh_id_len); 1076 wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID", 1077 sm->r0kh_id, sm->r0kh_id_len); 1078 return -1; 1079 } 1080 1081 if (parse.r1kh_id == NULL) { 1082 wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE"); 1083 return -1; 1084 } 1085 1086 if (os_memcmp_const(parse.r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN) != 0) { 1087 wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in " 1088 "ReassocResp"); 1089 return -1; 1090 } 1091 1092 if (parse.rsn_pmkid == NULL || 1093 os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)) 1094 { 1095 wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in " 1096 "RSNIE (pmkid=%d)", !!parse.rsn_pmkid); 1097 return -1; 1098 } 1099 1100 count = 3; 1101 if (parse.ric) 1102 count += ieee802_11_ie_count(parse.ric, parse.ric_len); 1103 if (parse.rsnxe) 1104 count++; 1105 if (fte_elem_count != count) { 1106 wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC " 1107 "Control: received %u expected %u", 1108 fte_elem_count, count); 1109 return -1; 1110 } 1111 1112 if (wpa_key_mgmt_fils(sm->key_mgmt)) { 1113 kck = sm->ptk.kck2; 1114 kck_len = sm->ptk.kck2_len; 1115 } else { 1116 kck = sm->ptk.kck; 1117 kck_len = sm->ptk.kck_len; 1118 } 1119 1120 if (wpa_ft_mic(kck, kck_len, sm->own_addr, src_addr, 6, 1121 parse.mdie - 2, parse.mdie_len + 2, 1122 parse.ftie - 2, parse.ftie_len + 2, 1123 parse.rsn - 2, parse.rsn_len + 2, 1124 parse.ric, parse.ric_len, 1125 parse.rsnxe ? parse.rsnxe - 2 : NULL, 1126 parse.rsnxe ? parse.rsnxe_len + 2 : 0, 1127 mic) < 0) { 1128 wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); 1129 return -1; 1130 } 1131 1132 if (os_memcmp_const(mic, fte_mic, 16) != 0) { 1133 wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE"); 1134 wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", fte_mic, 16); 1135 wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16); 1136 return -1; 1137 } 1138 1139 if (rsnxe_used && !sm->ap_rsnxe) { 1140 wpa_printf(MSG_INFO, 1141 "FT: FTE indicated that AP uses RSNXE, but RSNXE was not included in Beacon/Probe Response frames"); 1142 return -1; 1143 } 1144 1145 if (!sm->ap_rsn_ie) { 1146 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, 1147 "FT: No RSNE for this AP known - trying to get from scan results"); 1148 if (wpa_sm_get_beacon_ie(sm) < 0) { 1149 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, 1150 "FT: Could not find AP from the scan results"); 1151 return -1; 1152 } 1153 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, 1154 "FT: Found the current AP from updated scan results"); 1155 } 1156 1157 if (sm->ap_rsn_ie && 1158 wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt), 1159 sm->ap_rsn_ie, sm->ap_rsn_ie_len, 1160 parse.rsn - 2, parse.rsn_len + 2)) { 1161 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 1162 "FT: RSNE mismatch between Beacon/ProbeResp and FT protocol Reassociation Response frame"); 1163 wpa_hexdump(MSG_INFO, "RSNE in Beacon/ProbeResp", 1164 sm->ap_rsn_ie, sm->ap_rsn_ie_len); 1165 wpa_hexdump(MSG_INFO, 1166 "RSNE in FT protocol Reassociation Response frame", 1167 parse.rsn ? parse.rsn - 2 : NULL, 1168 parse.rsn ? parse.rsn_len + 2 : 0); 1169 return -1; 1170 } 1171 1172 own_rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) && 1173 (sm->sae_pwe == 1 || sm->sae_pwe == 2); 1174 if ((sm->ap_rsnxe && !parse.rsnxe && own_rsnxe_used) || 1175 (!sm->ap_rsnxe && parse.rsnxe) || 1176 (sm->ap_rsnxe && parse.rsnxe && 1177 (sm->ap_rsnxe_len != 2 + parse.rsnxe_len || 1178 os_memcmp(sm->ap_rsnxe, parse.rsnxe - 2, 1179 sm->ap_rsnxe_len) != 0))) { 1180 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, 1181 "FT: RSNXE mismatch between Beacon/ProbeResp and FT protocol Reassociation Response frame"); 1182 wpa_hexdump(MSG_INFO, "RSNXE in Beacon/ProbeResp", 1183 sm->ap_rsnxe, sm->ap_rsnxe_len); 1184 wpa_hexdump(MSG_INFO, 1185 "RSNXE in FT protocol Reassociation Response frame", 1186 parse.rsnxe ? parse.rsnxe - 2 : NULL, 1187 parse.rsnxe ? parse.rsnxe_len + 2 : 0); 1188 return -1; 1189 } 1190 1191 #ifdef CONFIG_OCV 1192 if (wpa_sm_ocv_enabled(sm)) { 1193 struct wpa_channel_info ci; 1194 1195 if (wpa_sm_channel_info(sm, &ci) != 0) { 1196 wpa_printf(MSG_WARNING, 1197 "Failed to get channel info to validate received OCI in (Re)Assoc Response"); 1198 return -1; 1199 } 1200 1201 if (ocv_verify_tx_params(parse.oci, parse.oci_len, &ci, 1202 channel_width_to_int(ci.chanwidth), 1203 ci.seg1_idx) != OCI_SUCCESS) { 1204 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE 1205 "addr=" MACSTR " frame=ft-assoc error=%s", 1206 MAC2STR(src_addr), ocv_errorstr); 1207 return -1; 1208 } 1209 } 1210 #endif /* CONFIG_OCV */ 1211 1212 sm->ft_reassoc_completed = 1; 1213 1214 if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0 || 1215 wpa_ft_process_igtk_subelem(sm, parse.igtk, parse.igtk_len) < 0 || 1216 wpa_ft_process_bigtk_subelem(sm, parse.bigtk, parse.bigtk_len) < 0) 1217 return -1; 1218 1219 if (sm->set_ptk_after_assoc) { 1220 wpa_printf(MSG_DEBUG, "FT: Try to set PTK again now that we " 1221 "are associated"); 1222 if (wpa_ft_install_ptk(sm, src_addr) < 0) 1223 return -1; 1224 sm->set_ptk_after_assoc = 0; 1225 } 1226 1227 if (parse.ric) { 1228 wpa_hexdump(MSG_MSGDUMP, "FT: RIC Response", 1229 parse.ric, parse.ric_len); 1230 /* TODO: parse response and inform driver about results when 1231 * using wpa_supplicant SME */ 1232 } 1233 1234 wpa_printf(MSG_DEBUG, "FT: Completed successfully"); 1235 1236 return 0; 1237 } 1238 1239 1240 /** 1241 * wpa_ft_start_over_ds - Generate over-the-DS auth request 1242 * @sm: Pointer to WPA state machine data from wpa_sm_init() 1243 * @target_ap: Target AP Address 1244 * @mdie: Mobility Domain IE from the target AP 1245 * Returns: 0 on success, -1 on failure 1246 */ 1247 int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap, 1248 const u8 *mdie) 1249 { 1250 u8 *ft_ies; 1251 size_t ft_ies_len; 1252 1253 wpa_printf(MSG_DEBUG, "FT: Request over-the-DS with " MACSTR, 1254 MAC2STR(target_ap)); 1255 1256 /* Generate a new SNonce */ 1257 if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) { 1258 wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce"); 1259 return -1; 1260 } 1261 1262 ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name, 1263 NULL, 0, target_ap, NULL, 0, mdie, 0); 1264 if (ft_ies) { 1265 sm->over_the_ds_in_progress = 1; 1266 os_memcpy(sm->target_ap, target_ap, ETH_ALEN); 1267 wpa_sm_send_ft_action(sm, 1, target_ap, ft_ies, ft_ies_len); 1268 os_free(ft_ies); 1269 } 1270 1271 return 0; 1272 } 1273 1274 1275 #ifdef CONFIG_PASN 1276 1277 static struct pasn_ft_r1kh * wpa_ft_pasn_get_r1kh(struct wpa_sm *sm, 1278 const u8 *bssid) 1279 { 1280 size_t i; 1281 1282 for (i = 0; i < sm->n_pasn_r1kh; i++) 1283 if (os_memcmp(sm->pasn_r1kh[i].bssid, bssid, ETH_ALEN) == 0) 1284 return &sm->pasn_r1kh[i]; 1285 1286 return NULL; 1287 } 1288 1289 1290 static void wpa_ft_pasn_store_r1kh(struct wpa_sm *sm, const u8 *bssid) 1291 { 1292 struct pasn_ft_r1kh *tmp = wpa_ft_pasn_get_r1kh(sm, bssid); 1293 1294 if (tmp) 1295 return; 1296 1297 tmp = os_realloc_array(sm->pasn_r1kh, sm->n_pasn_r1kh + 1, 1298 sizeof(*tmp)); 1299 if (!tmp) { 1300 wpa_printf(MSG_DEBUG, "PASN: FT: Failed to store R1KH"); 1301 return; 1302 } 1303 1304 sm->pasn_r1kh = tmp; 1305 tmp = &sm->pasn_r1kh[sm->n_pasn_r1kh]; 1306 1307 wpa_printf(MSG_DEBUG, "PASN: FT: Store R1KH for " MACSTR, 1308 MAC2STR(bssid)); 1309 1310 os_memcpy(tmp->bssid, bssid, ETH_ALEN); 1311 os_memcpy(tmp->r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN); 1312 1313 sm->n_pasn_r1kh++; 1314 } 1315 1316 1317 int wpa_pasn_ft_derive_pmk_r1(struct wpa_sm *sm, int akmp, const u8 *bssid, 1318 u8 *pmk_r1, size_t *pmk_r1_len, u8 *pmk_r1_name) 1319 { 1320 struct pasn_ft_r1kh *r1kh_entry; 1321 1322 if (sm->key_mgmt != (unsigned int) akmp) { 1323 wpa_printf(MSG_DEBUG, 1324 "PASN: FT: Key management mismatch: %u != %u", 1325 sm->key_mgmt, akmp); 1326 return -1; 1327 } 1328 1329 r1kh_entry = wpa_ft_pasn_get_r1kh(sm, bssid); 1330 if (!r1kh_entry) { 1331 wpa_printf(MSG_DEBUG, 1332 "PASN: FT: Cannot find R1KH-ID for " MACSTR, 1333 MAC2STR(bssid)); 1334 return -1; 1335 } 1336 1337 /* 1338 * Note: PMK R0 etc. were already derived and are maintained by the 1339 * state machine, and as the same key hierarchy is used, there is no 1340 * need to derive them again, so only derive PMK R1 etc. 1341 */ 1342 if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name, 1343 r1kh_entry->r1kh_id, sm->own_addr, pmk_r1, 1344 pmk_r1_name) < 0) 1345 return -1; 1346 1347 *pmk_r1_len = sm->pmk_r0_len; 1348 1349 wpa_hexdump_key(MSG_DEBUG, "PASN: FT: PMK-R1", pmk_r1, sm->pmk_r0_len); 1350 wpa_hexdump(MSG_DEBUG, "PASN: FT: PMKR1Name", pmk_r1_name, 1351 WPA_PMK_NAME_LEN); 1352 1353 return 0; 1354 } 1355 1356 #endif /* CONFIG_PASN */ 1357 1358 #endif /* CONFIG_IEEE80211R */ 1359