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