1 /* 2 * hostapd - IEEE 802.11r - Fast BSS Transition 3 * Copyright (c) 2004-2014, Jouni Malinen <j (at) 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 "utils/includes.h" 10 11 #include "utils/common.h" 12 #include "utils/eloop.h" 13 #include "common/ieee802_11_defs.h" 14 #include "common/ieee802_11_common.h" 15 #include "crypto/aes_wrap.h" 16 #include "crypto/random.h" 17 #include "ap_config.h" 18 #include "ieee802_11.h" 19 #include "wmm.h" 20 #include "wpa_auth.h" 21 #include "wpa_auth_i.h" 22 23 24 #ifdef CONFIG_IEEE80211R 25 26 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm, 27 const u8 *current_ap, const u8 *sta_addr, 28 u16 status, const u8 *resp_ies, 29 size_t resp_ies_len); 30 31 32 static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst, 33 const u8 *data, size_t data_len) 34 { 35 if (wpa_auth->cb.send_ether == NULL) 36 return -1; 37 wpa_printf(MSG_DEBUG, "FT: RRB send to " MACSTR, MAC2STR(dst)); 38 return wpa_auth->cb.send_ether(wpa_auth->cb.ctx, dst, ETH_P_RRB, 39 data, data_len); 40 } 41 42 43 static int wpa_ft_action_send(struct wpa_authenticator *wpa_auth, 44 const u8 *dst, const u8 *data, size_t data_len) 45 { 46 if (wpa_auth->cb.send_ft_action == NULL) 47 return -1; 48 return wpa_auth->cb.send_ft_action(wpa_auth->cb.ctx, dst, 49 data, data_len); 50 } 51 52 53 static struct wpa_state_machine * 54 wpa_ft_add_sta(struct wpa_authenticator *wpa_auth, const u8 *sta_addr) 55 { 56 if (wpa_auth->cb.add_sta == NULL) 57 return NULL; 58 return wpa_auth->cb.add_sta(wpa_auth->cb.ctx, sta_addr); 59 } 60 61 62 static int wpa_ft_add_tspec(struct wpa_authenticator *wpa_auth, 63 const u8 *sta_addr, 64 u8 *tspec_ie, size_t tspec_ielen) 65 { 66 if (wpa_auth->cb.add_tspec == NULL) { 67 wpa_printf(MSG_DEBUG, "FT: add_tspec is not initialized"); 68 return -1; 69 } 70 return wpa_auth->cb.add_tspec(wpa_auth->cb.ctx, sta_addr, tspec_ie, 71 tspec_ielen); 72 } 73 74 75 int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len) 76 { 77 u8 *pos = buf; 78 u8 capab; 79 if (len < 2 + sizeof(struct rsn_mdie)) 80 return -1; 81 82 *pos++ = WLAN_EID_MOBILITY_DOMAIN; 83 *pos++ = MOBILITY_DOMAIN_ID_LEN + 1; 84 os_memcpy(pos, conf->mobility_domain, MOBILITY_DOMAIN_ID_LEN); 85 pos += MOBILITY_DOMAIN_ID_LEN; 86 capab = 0; 87 if (conf->ft_over_ds) 88 capab |= RSN_FT_CAPAB_FT_OVER_DS; 89 *pos++ = capab; 90 91 return pos - buf; 92 } 93 94 95 int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id, 96 size_t r0kh_id_len, 97 const u8 *anonce, const u8 *snonce, 98 u8 *buf, size_t len, const u8 *subelem, 99 size_t subelem_len) 100 { 101 u8 *pos = buf, *ielen; 102 struct rsn_ftie *hdr; 103 104 if (len < 2 + sizeof(*hdr) + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len + 105 subelem_len) 106 return -1; 107 108 *pos++ = WLAN_EID_FAST_BSS_TRANSITION; 109 ielen = pos++; 110 111 hdr = (struct rsn_ftie *) pos; 112 os_memset(hdr, 0, sizeof(*hdr)); 113 pos += sizeof(*hdr); 114 WPA_PUT_LE16(hdr->mic_control, 0); 115 if (anonce) 116 os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN); 117 if (snonce) 118 os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN); 119 120 /* Optional Parameters */ 121 *pos++ = FTIE_SUBELEM_R1KH_ID; 122 *pos++ = FT_R1KH_ID_LEN; 123 os_memcpy(pos, conf->r1_key_holder, FT_R1KH_ID_LEN); 124 pos += FT_R1KH_ID_LEN; 125 126 if (r0kh_id) { 127 *pos++ = FTIE_SUBELEM_R0KH_ID; 128 *pos++ = r0kh_id_len; 129 os_memcpy(pos, r0kh_id, r0kh_id_len); 130 pos += r0kh_id_len; 131 } 132 133 if (subelem) { 134 os_memcpy(pos, subelem, subelem_len); 135 pos += subelem_len; 136 } 137 138 *ielen = pos - buf - 2; 139 140 return pos - buf; 141 } 142 143 144 struct wpa_ft_pmk_r0_sa { 145 struct wpa_ft_pmk_r0_sa *next; 146 u8 pmk_r0[PMK_LEN]; 147 u8 pmk_r0_name[WPA_PMK_NAME_LEN]; 148 u8 spa[ETH_ALEN]; 149 int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */ 150 /* TODO: expiration, identity, radius_class, EAP type, VLAN ID */ 151 int pmk_r1_pushed; 152 }; 153 154 struct wpa_ft_pmk_r1_sa { 155 struct wpa_ft_pmk_r1_sa *next; 156 u8 pmk_r1[PMK_LEN]; 157 u8 pmk_r1_name[WPA_PMK_NAME_LEN]; 158 u8 spa[ETH_ALEN]; 159 int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */ 160 /* TODO: expiration, identity, radius_class, EAP type, VLAN ID */ 161 }; 162 163 struct wpa_ft_pmk_cache { 164 struct wpa_ft_pmk_r0_sa *pmk_r0; 165 struct wpa_ft_pmk_r1_sa *pmk_r1; 166 }; 167 168 struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void) 169 { 170 struct wpa_ft_pmk_cache *cache; 171 172 cache = os_zalloc(sizeof(*cache)); 173 174 return cache; 175 } 176 177 178 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache) 179 { 180 struct wpa_ft_pmk_r0_sa *r0, *r0prev; 181 struct wpa_ft_pmk_r1_sa *r1, *r1prev; 182 183 r0 = cache->pmk_r0; 184 while (r0) { 185 r0prev = r0; 186 r0 = r0->next; 187 os_memset(r0prev->pmk_r0, 0, PMK_LEN); 188 os_free(r0prev); 189 } 190 191 r1 = cache->pmk_r1; 192 while (r1) { 193 r1prev = r1; 194 r1 = r1->next; 195 os_memset(r1prev->pmk_r1, 0, PMK_LEN); 196 os_free(r1prev); 197 } 198 199 os_free(cache); 200 } 201 202 203 static int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth, 204 const u8 *spa, const u8 *pmk_r0, 205 const u8 *pmk_r0_name, int pairwise) 206 { 207 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; 208 struct wpa_ft_pmk_r0_sa *r0; 209 210 /* TODO: add expiration and limit on number of entries in cache */ 211 212 r0 = os_zalloc(sizeof(*r0)); 213 if (r0 == NULL) 214 return -1; 215 216 os_memcpy(r0->pmk_r0, pmk_r0, PMK_LEN); 217 os_memcpy(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN); 218 os_memcpy(r0->spa, spa, ETH_ALEN); 219 r0->pairwise = pairwise; 220 221 r0->next = cache->pmk_r0; 222 cache->pmk_r0 = r0; 223 224 return 0; 225 } 226 227 228 static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator *wpa_auth, 229 const u8 *spa, const u8 *pmk_r0_name, 230 u8 *pmk_r0, int *pairwise) 231 { 232 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; 233 struct wpa_ft_pmk_r0_sa *r0; 234 235 r0 = cache->pmk_r0; 236 while (r0) { 237 if (os_memcmp(r0->spa, spa, ETH_ALEN) == 0 && 238 os_memcmp_const(r0->pmk_r0_name, pmk_r0_name, 239 WPA_PMK_NAME_LEN) == 0) { 240 os_memcpy(pmk_r0, r0->pmk_r0, PMK_LEN); 241 if (pairwise) 242 *pairwise = r0->pairwise; 243 return 0; 244 } 245 246 r0 = r0->next; 247 } 248 249 return -1; 250 } 251 252 253 static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth, 254 const u8 *spa, const u8 *pmk_r1, 255 const u8 *pmk_r1_name, int pairwise) 256 { 257 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; 258 struct wpa_ft_pmk_r1_sa *r1; 259 260 /* TODO: add expiration and limit on number of entries in cache */ 261 262 r1 = os_zalloc(sizeof(*r1)); 263 if (r1 == NULL) 264 return -1; 265 266 os_memcpy(r1->pmk_r1, pmk_r1, PMK_LEN); 267 os_memcpy(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN); 268 os_memcpy(r1->spa, spa, ETH_ALEN); 269 r1->pairwise = pairwise; 270 271 r1->next = cache->pmk_r1; 272 cache->pmk_r1 = r1; 273 274 return 0; 275 } 276 277 278 static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth, 279 const u8 *spa, const u8 *pmk_r1_name, 280 u8 *pmk_r1, int *pairwise) 281 { 282 struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; 283 struct wpa_ft_pmk_r1_sa *r1; 284 285 r1 = cache->pmk_r1; 286 while (r1) { 287 if (os_memcmp(r1->spa, spa, ETH_ALEN) == 0 && 288 os_memcmp_const(r1->pmk_r1_name, pmk_r1_name, 289 WPA_PMK_NAME_LEN) == 0) { 290 os_memcpy(pmk_r1, r1->pmk_r1, PMK_LEN); 291 if (pairwise) 292 *pairwise = r1->pairwise; 293 return 0; 294 } 295 296 r1 = r1->next; 297 } 298 299 return -1; 300 } 301 302 303 static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm, 304 const u8 *ies, size_t ies_len, 305 const u8 *pmk_r0_name) 306 { 307 struct ft_remote_r0kh *r0kh; 308 struct ft_r0kh_r1kh_pull_frame frame, f; 309 310 r0kh = sm->wpa_auth->conf.r0kh_list; 311 while (r0kh) { 312 if (r0kh->id_len == sm->r0kh_id_len && 313 os_memcmp_const(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) == 314 0) 315 break; 316 r0kh = r0kh->next; 317 } 318 if (r0kh == NULL) { 319 wpa_hexdump(MSG_DEBUG, "FT: Did not find R0KH-ID", 320 sm->r0kh_id, sm->r0kh_id_len); 321 return -1; 322 } 323 324 wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH " 325 "address " MACSTR, MAC2STR(r0kh->addr)); 326 327 os_memset(&frame, 0, sizeof(frame)); 328 frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB; 329 frame.packet_type = FT_PACKET_R0KH_R1KH_PULL; 330 frame.data_length = host_to_le16(FT_R0KH_R1KH_PULL_DATA_LEN); 331 os_memcpy(frame.ap_address, sm->wpa_auth->addr, ETH_ALEN); 332 333 /* aes_wrap() does not support inplace encryption, so use a temporary 334 * buffer for the data. */ 335 if (random_get_bytes(f.nonce, FT_R0KH_R1KH_PULL_NONCE_LEN)) { 336 wpa_printf(MSG_DEBUG, "FT: Failed to get random data for " 337 "nonce"); 338 return -1; 339 } 340 os_memcpy(sm->ft_pending_pull_nonce, f.nonce, 341 FT_R0KH_R1KH_PULL_NONCE_LEN); 342 os_memcpy(f.pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN); 343 os_memcpy(f.r1kh_id, sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN); 344 os_memcpy(f.s1kh_id, sm->addr, ETH_ALEN); 345 os_memset(f.pad, 0, sizeof(f.pad)); 346 347 if (aes_wrap(r0kh->key, sizeof(r0kh->key), 348 (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8, 349 f.nonce, frame.nonce) < 0) 350 return -1; 351 352 wpabuf_free(sm->ft_pending_req_ies); 353 sm->ft_pending_req_ies = wpabuf_alloc_copy(ies, ies_len); 354 if (sm->ft_pending_req_ies == NULL) 355 return -1; 356 357 wpa_ft_rrb_send(sm->wpa_auth, r0kh->addr, (u8 *) &frame, sizeof(frame)); 358 359 return 0; 360 } 361 362 363 int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, 364 struct wpa_ptk *ptk, size_t ptk_len) 365 { 366 u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN]; 367 u8 pmk_r1[PMK_LEN]; 368 u8 ptk_name[WPA_PMK_NAME_LEN]; 369 const u8 *mdid = sm->wpa_auth->conf.mobility_domain; 370 const u8 *r0kh = sm->wpa_auth->conf.r0_key_holder; 371 size_t r0kh_len = sm->wpa_auth->conf.r0_key_holder_len; 372 const u8 *r1kh = sm->wpa_auth->conf.r1_key_holder; 373 const u8 *ssid = sm->wpa_auth->conf.ssid; 374 size_t ssid_len = sm->wpa_auth->conf.ssid_len; 375 376 377 if (sm->xxkey_len == 0) { 378 wpa_printf(MSG_DEBUG, "FT: XXKey not available for key " 379 "derivation"); 380 return -1; 381 } 382 383 wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, ssid, ssid_len, mdid, 384 r0kh, r0kh_len, sm->addr, pmk_r0, pmk_r0_name); 385 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN); 386 wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN); 387 wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_name, 388 sm->pairwise); 389 390 wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr, 391 pmk_r1, sm->pmk_r1_name); 392 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN); 393 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name, 394 WPA_PMK_NAME_LEN); 395 wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, sm->pmk_r1_name, 396 sm->pairwise); 397 398 wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr, 399 sm->wpa_auth->addr, sm->pmk_r1_name, 400 (u8 *) ptk, ptk_len, ptk_name); 401 wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, ptk_len); 402 wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); 403 404 return 0; 405 } 406 407 408 static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, 409 const u8 *addr, int idx, u8 *seq) 410 { 411 if (wpa_auth->cb.get_seqnum == NULL) 412 return -1; 413 return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq); 414 } 415 416 417 static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len) 418 { 419 u8 *subelem; 420 struct wpa_group *gsm = sm->group; 421 size_t subelem_len, pad_len; 422 const u8 *key; 423 size_t key_len; 424 u8 keybuf[32]; 425 426 key_len = gsm->GTK_len; 427 if (key_len > sizeof(keybuf)) 428 return NULL; 429 430 /* 431 * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less 432 * than 16 bytes. 433 */ 434 pad_len = key_len % 8; 435 if (pad_len) 436 pad_len = 8 - pad_len; 437 if (key_len + pad_len < 16) 438 pad_len += 8; 439 if (pad_len && key_len < sizeof(keybuf)) { 440 os_memcpy(keybuf, gsm->GTK[gsm->GN - 1], key_len); 441 os_memset(keybuf + key_len, 0, pad_len); 442 keybuf[key_len] = 0xdd; 443 key_len += pad_len; 444 key = keybuf; 445 } else 446 key = gsm->GTK[gsm->GN - 1]; 447 448 /* 449 * Sub-elem ID[1] | Length[1] | Key Info[2] | Key Length[1] | RSC[8] | 450 * Key[5..32]. 451 */ 452 subelem_len = 13 + key_len + 8; 453 subelem = os_zalloc(subelem_len); 454 if (subelem == NULL) 455 return NULL; 456 457 subelem[0] = FTIE_SUBELEM_GTK; 458 subelem[1] = 11 + key_len + 8; 459 /* Key ID in B0-B1 of Key Info */ 460 WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03); 461 subelem[4] = gsm->GTK_len; 462 wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5); 463 if (aes_wrap(sm->PTK.kek, 16, key_len / 8, key, subelem + 13)) { 464 os_free(subelem); 465 return NULL; 466 } 467 468 *len = subelem_len; 469 return subelem; 470 } 471 472 473 #ifdef CONFIG_IEEE80211W 474 static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len) 475 { 476 u8 *subelem, *pos; 477 struct wpa_group *gsm = sm->group; 478 size_t subelem_len; 479 480 /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] | 481 * Key[16+8] */ 482 subelem_len = 1 + 1 + 2 + 6 + 1 + WPA_IGTK_LEN + 8; 483 subelem = os_zalloc(subelem_len); 484 if (subelem == NULL) 485 return NULL; 486 487 pos = subelem; 488 *pos++ = FTIE_SUBELEM_IGTK; 489 *pos++ = subelem_len - 2; 490 WPA_PUT_LE16(pos, gsm->GN_igtk); 491 pos += 2; 492 wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos); 493 pos += 6; 494 *pos++ = WPA_IGTK_LEN; 495 if (aes_wrap(sm->PTK.kek, 16, WPA_IGTK_LEN / 8, 496 gsm->IGTK[gsm->GN_igtk - 4], pos)) { 497 os_free(subelem); 498 return NULL; 499 } 500 501 *len = subelem_len; 502 return subelem; 503 } 504 #endif /* CONFIG_IEEE80211W */ 505 506 507 static u8 * wpa_ft_process_rdie(struct wpa_state_machine *sm, 508 u8 *pos, u8 *end, u8 id, u8 descr_count, 509 const u8 *ies, size_t ies_len) 510 { 511 struct ieee802_11_elems parse; 512 struct rsn_rdie *rdie; 513 514 wpa_printf(MSG_DEBUG, "FT: Resource Request: id=%d descr_count=%d", 515 id, descr_count); 516 wpa_hexdump(MSG_MSGDUMP, "FT: Resource descriptor IE(s)", 517 ies, ies_len); 518 519 if (end - pos < (int) sizeof(*rdie)) { 520 wpa_printf(MSG_ERROR, "FT: Not enough room for response RDIE"); 521 return pos; 522 } 523 524 *pos++ = WLAN_EID_RIC_DATA; 525 *pos++ = sizeof(*rdie); 526 rdie = (struct rsn_rdie *) pos; 527 rdie->id = id; 528 rdie->descr_count = 0; 529 rdie->status_code = host_to_le16(WLAN_STATUS_SUCCESS); 530 pos += sizeof(*rdie); 531 532 if (ieee802_11_parse_elems((u8 *) ies, ies_len, &parse, 1) == 533 ParseFailed) { 534 wpa_printf(MSG_DEBUG, "FT: Failed to parse request IEs"); 535 rdie->status_code = 536 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE); 537 return pos; 538 } 539 540 #ifdef NEED_AP_MLME 541 if (parse.wmm_tspec && sm->wpa_auth->conf.ap_mlme) { 542 struct wmm_tspec_element *tspec; 543 int res; 544 545 if (parse.wmm_tspec_len + 2 < (int) sizeof(*tspec)) { 546 wpa_printf(MSG_DEBUG, "FT: Too short WMM TSPEC IE " 547 "(%d)", (int) parse.wmm_tspec_len); 548 rdie->status_code = 549 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE); 550 return pos; 551 } 552 if (end - pos < (int) sizeof(*tspec)) { 553 wpa_printf(MSG_ERROR, "FT: Not enough room for " 554 "response TSPEC"); 555 rdie->status_code = 556 host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE); 557 return pos; 558 } 559 tspec = (struct wmm_tspec_element *) pos; 560 os_memcpy(tspec, parse.wmm_tspec - 2, sizeof(*tspec)); 561 res = wmm_process_tspec(tspec); 562 wpa_printf(MSG_DEBUG, "FT: ADDTS processing result: %d", res); 563 if (res == WMM_ADDTS_STATUS_INVALID_PARAMETERS) 564 rdie->status_code = 565 host_to_le16(WLAN_STATUS_INVALID_PARAMETERS); 566 else if (res == WMM_ADDTS_STATUS_REFUSED) 567 rdie->status_code = 568 host_to_le16(WLAN_STATUS_REQUEST_DECLINED); 569 else { 570 /* TSPEC accepted; include updated TSPEC in response */ 571 rdie->descr_count = 1; 572 pos += sizeof(*tspec); 573 } 574 return pos; 575 } 576 #endif /* NEED_AP_MLME */ 577 578 if (parse.wmm_tspec && !sm->wpa_auth->conf.ap_mlme) { 579 struct wmm_tspec_element *tspec; 580 int res; 581 582 tspec = (struct wmm_tspec_element *) pos; 583 os_memcpy(tspec, parse.wmm_tspec - 2, sizeof(*tspec)); 584 res = wpa_ft_add_tspec(sm->wpa_auth, sm->addr, pos, 585 sizeof(*tspec)); 586 if (res >= 0) { 587 if (res) 588 rdie->status_code = host_to_le16(res); 589 else { 590 /* TSPEC accepted; include updated TSPEC in 591 * response */ 592 rdie->descr_count = 1; 593 pos += sizeof(*tspec); 594 } 595 return pos; 596 } 597 } 598 599 wpa_printf(MSG_DEBUG, "FT: No supported resource requested"); 600 rdie->status_code = host_to_le16(WLAN_STATUS_UNSPECIFIED_FAILURE); 601 return pos; 602 } 603 604 605 static u8 * wpa_ft_process_ric(struct wpa_state_machine *sm, u8 *pos, u8 *end, 606 const u8 *ric, size_t ric_len) 607 { 608 const u8 *rpos, *start; 609 const struct rsn_rdie *rdie; 610 611 wpa_hexdump(MSG_MSGDUMP, "FT: RIC Request", ric, ric_len); 612 613 rpos = ric; 614 while (rpos + sizeof(*rdie) < ric + ric_len) { 615 if (rpos[0] != WLAN_EID_RIC_DATA || rpos[1] < sizeof(*rdie) || 616 rpos + 2 + rpos[1] > ric + ric_len) 617 break; 618 rdie = (const struct rsn_rdie *) (rpos + 2); 619 rpos += 2 + rpos[1]; 620 start = rpos; 621 622 while (rpos + 2 <= ric + ric_len && 623 rpos + 2 + rpos[1] <= ric + ric_len) { 624 if (rpos[0] == WLAN_EID_RIC_DATA) 625 break; 626 rpos += 2 + rpos[1]; 627 } 628 pos = wpa_ft_process_rdie(sm, pos, end, rdie->id, 629 rdie->descr_count, 630 start, rpos - start); 631 } 632 633 return pos; 634 } 635 636 637 u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, 638 size_t max_len, int auth_alg, 639 const u8 *req_ies, size_t req_ies_len) 640 { 641 u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL; 642 size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0; 643 int res; 644 struct wpa_auth_config *conf; 645 struct rsn_ftie *_ftie; 646 struct wpa_ft_ies parse; 647 u8 *ric_start; 648 u8 *anonce, *snonce; 649 650 if (sm == NULL) 651 return pos; 652 653 conf = &sm->wpa_auth->conf; 654 655 if (!wpa_key_mgmt_ft(sm->wpa_key_mgmt)) 656 return pos; 657 658 end = pos + max_len; 659 660 if (auth_alg == WLAN_AUTH_FT) { 661 /* 662 * RSN (only present if this is a Reassociation Response and 663 * part of a fast BSS transition) 664 */ 665 res = wpa_write_rsn_ie(conf, pos, end - pos, sm->pmk_r1_name); 666 if (res < 0) 667 return pos; 668 rsnie = pos; 669 rsnie_len = res; 670 pos += res; 671 } 672 673 /* Mobility Domain Information */ 674 res = wpa_write_mdie(conf, pos, end - pos); 675 if (res < 0) 676 return pos; 677 mdie = pos; 678 mdie_len = res; 679 pos += res; 680 681 /* Fast BSS Transition Information */ 682 if (auth_alg == WLAN_AUTH_FT) { 683 subelem = wpa_ft_gtk_subelem(sm, &subelem_len); 684 r0kh_id = sm->r0kh_id; 685 r0kh_id_len = sm->r0kh_id_len; 686 anonce = sm->ANonce; 687 snonce = sm->SNonce; 688 #ifdef CONFIG_IEEE80211W 689 if (sm->mgmt_frame_prot) { 690 u8 *igtk; 691 size_t igtk_len; 692 u8 *nbuf; 693 igtk = wpa_ft_igtk_subelem(sm, &igtk_len); 694 if (igtk == NULL) { 695 os_free(subelem); 696 return pos; 697 } 698 nbuf = os_realloc(subelem, subelem_len + igtk_len); 699 if (nbuf == NULL) { 700 os_free(subelem); 701 os_free(igtk); 702 return pos; 703 } 704 subelem = nbuf; 705 os_memcpy(subelem + subelem_len, igtk, igtk_len); 706 subelem_len += igtk_len; 707 os_free(igtk); 708 } 709 #endif /* CONFIG_IEEE80211W */ 710 } else { 711 r0kh_id = conf->r0_key_holder; 712 r0kh_id_len = conf->r0_key_holder_len; 713 anonce = NULL; 714 snonce = NULL; 715 } 716 res = wpa_write_ftie(conf, r0kh_id, r0kh_id_len, anonce, snonce, pos, 717 end - pos, subelem, subelem_len); 718 os_free(subelem); 719 if (res < 0) 720 return pos; 721 ftie = pos; 722 ftie_len = res; 723 pos += res; 724 725 os_free(sm->assoc_resp_ftie); 726 sm->assoc_resp_ftie = os_malloc(ftie_len); 727 if (sm->assoc_resp_ftie) 728 os_memcpy(sm->assoc_resp_ftie, ftie, ftie_len); 729 730 _ftie = (struct rsn_ftie *) (ftie + 2); 731 if (auth_alg == WLAN_AUTH_FT) 732 _ftie->mic_control[1] = 3; /* Information element count */ 733 734 ric_start = pos; 735 if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse) == 0 && parse.ric) { 736 pos = wpa_ft_process_ric(sm, pos, end, parse.ric, 737 parse.ric_len); 738 if (auth_alg == WLAN_AUTH_FT) 739 _ftie->mic_control[1] += 740 ieee802_11_ie_count(ric_start, 741 pos - ric_start); 742 } 743 if (ric_start == pos) 744 ric_start = NULL; 745 746 if (auth_alg == WLAN_AUTH_FT && 747 wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 6, 748 mdie, mdie_len, ftie, ftie_len, 749 rsnie, rsnie_len, 750 ric_start, ric_start ? pos - ric_start : 0, 751 _ftie->mic) < 0) 752 wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); 753 754 return pos; 755 } 756 757 758 static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth, 759 int vlan_id, 760 enum wpa_alg alg, const u8 *addr, int idx, 761 u8 *key, size_t key_len) 762 { 763 if (wpa_auth->cb.set_key == NULL) 764 return -1; 765 return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx, 766 key, key_len); 767 } 768 769 770 void wpa_ft_install_ptk(struct wpa_state_machine *sm) 771 { 772 enum wpa_alg alg; 773 int klen; 774 775 /* MLME-SETKEYS.request(PTK) */ 776 alg = wpa_cipher_to_alg(sm->pairwise); 777 klen = wpa_cipher_key_len(sm->pairwise); 778 if (!wpa_cipher_valid_pairwise(sm->pairwise)) { 779 wpa_printf(MSG_DEBUG, "FT: Unknown pairwise alg 0x%x - skip " 780 "PTK configuration", sm->pairwise); 781 return; 782 } 783 784 /* FIX: add STA entry to kernel/driver here? The set_key will fail 785 * most likely without this.. At the moment, STA entry is added only 786 * after association has been completed. This function will be called 787 * again after association to get the PTK configured, but that could be 788 * optimized by adding the STA entry earlier. 789 */ 790 if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, 791 sm->PTK.tk1, klen)) 792 return; 793 794 /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ 795 sm->pairwise_set = TRUE; 796 } 797 798 799 static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, 800 const u8 *ies, size_t ies_len, 801 u8 **resp_ies, size_t *resp_ies_len) 802 { 803 struct rsn_mdie *mdie; 804 struct rsn_ftie *ftie; 805 u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN]; 806 u8 ptk_name[WPA_PMK_NAME_LEN]; 807 struct wpa_auth_config *conf; 808 struct wpa_ft_ies parse; 809 size_t buflen, ptk_len; 810 int ret; 811 u8 *pos, *end; 812 int pairwise; 813 814 *resp_ies = NULL; 815 *resp_ies_len = 0; 816 817 sm->pmk_r1_name_valid = 0; 818 conf = &sm->wpa_auth->conf; 819 820 wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs", 821 ies, ies_len); 822 823 if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) { 824 wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs"); 825 return WLAN_STATUS_UNSPECIFIED_FAILURE; 826 } 827 828 mdie = (struct rsn_mdie *) parse.mdie; 829 if (mdie == NULL || parse.mdie_len < sizeof(*mdie) || 830 os_memcmp(mdie->mobility_domain, 831 sm->wpa_auth->conf.mobility_domain, 832 MOBILITY_DOMAIN_ID_LEN) != 0) { 833 wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); 834 return WLAN_STATUS_INVALID_MDIE; 835 } 836 837 ftie = (struct rsn_ftie *) parse.ftie; 838 if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) { 839 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); 840 return WLAN_STATUS_INVALID_FTIE; 841 } 842 843 os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN); 844 845 if (parse.r0kh_id == NULL) { 846 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID"); 847 return WLAN_STATUS_INVALID_FTIE; 848 } 849 850 wpa_hexdump(MSG_DEBUG, "FT: STA R0KH-ID", 851 parse.r0kh_id, parse.r0kh_id_len); 852 os_memcpy(sm->r0kh_id, parse.r0kh_id, parse.r0kh_id_len); 853 sm->r0kh_id_len = parse.r0kh_id_len; 854 855 if (parse.rsn_pmkid == NULL) { 856 wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE"); 857 return WLAN_STATUS_INVALID_PMKID; 858 } 859 860 wpa_hexdump(MSG_DEBUG, "FT: Requested PMKR0Name", 861 parse.rsn_pmkid, WPA_PMK_NAME_LEN); 862 wpa_derive_pmk_r1_name(parse.rsn_pmkid, 863 sm->wpa_auth->conf.r1_key_holder, sm->addr, 864 pmk_r1_name); 865 wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name", 866 pmk_r1_name, WPA_PMK_NAME_LEN); 867 868 if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name, pmk_r1, 869 &pairwise) < 0) { 870 if (wpa_ft_pull_pmk_r1(sm, ies, ies_len, parse.rsn_pmkid) < 0) { 871 wpa_printf(MSG_DEBUG, "FT: Did not have matching " 872 "PMK-R1 and unknown R0KH-ID"); 873 return WLAN_STATUS_INVALID_PMKID; 874 } 875 876 return -1; /* Status pending */ 877 } 878 879 wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, PMK_LEN); 880 sm->pmk_r1_name_valid = 1; 881 os_memcpy(sm->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN); 882 883 if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { 884 wpa_printf(MSG_DEBUG, "FT: Failed to get random data for " 885 "ANonce"); 886 return WLAN_STATUS_UNSPECIFIED_FAILURE; 887 } 888 889 wpa_hexdump(MSG_DEBUG, "FT: Received SNonce", 890 sm->SNonce, WPA_NONCE_LEN); 891 wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce", 892 sm->ANonce, WPA_NONCE_LEN); 893 894 ptk_len = pairwise == WPA_CIPHER_TKIP ? 64 : 48; 895 wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr, 896 sm->wpa_auth->addr, pmk_r1_name, 897 (u8 *) &sm->PTK, ptk_len, ptk_name); 898 wpa_hexdump_key(MSG_DEBUG, "FT: PTK", 899 (u8 *) &sm->PTK, ptk_len); 900 wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); 901 902 sm->pairwise = pairwise; 903 sm->PTK_valid = TRUE; 904 wpa_ft_install_ptk(sm); 905 906 buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + 907 2 + FT_R1KH_ID_LEN + 200; 908 *resp_ies = os_zalloc(buflen); 909 if (*resp_ies == NULL) { 910 return WLAN_STATUS_UNSPECIFIED_FAILURE; 911 } 912 913 pos = *resp_ies; 914 end = *resp_ies + buflen; 915 916 ret = wpa_write_rsn_ie(conf, pos, end - pos, parse.rsn_pmkid); 917 if (ret < 0) { 918 os_free(*resp_ies); 919 *resp_ies = NULL; 920 return WLAN_STATUS_UNSPECIFIED_FAILURE; 921 } 922 pos += ret; 923 924 ret = wpa_write_mdie(conf, pos, end - pos); 925 if (ret < 0) { 926 os_free(*resp_ies); 927 *resp_ies = NULL; 928 return WLAN_STATUS_UNSPECIFIED_FAILURE; 929 } 930 pos += ret; 931 932 ret = wpa_write_ftie(conf, parse.r0kh_id, parse.r0kh_id_len, 933 sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0); 934 if (ret < 0) { 935 os_free(*resp_ies); 936 *resp_ies = NULL; 937 return WLAN_STATUS_UNSPECIFIED_FAILURE; 938 } 939 pos += ret; 940 941 *resp_ies_len = pos - *resp_ies; 942 943 return WLAN_STATUS_SUCCESS; 944 } 945 946 947 void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid, 948 u16 auth_transaction, const u8 *ies, size_t ies_len, 949 void (*cb)(void *ctx, const u8 *dst, const u8 *bssid, 950 u16 auth_transaction, u16 status, 951 const u8 *ies, size_t ies_len), 952 void *ctx) 953 { 954 u16 status; 955 u8 *resp_ies; 956 size_t resp_ies_len; 957 int res; 958 959 if (sm == NULL) { 960 wpa_printf(MSG_DEBUG, "FT: Received authentication frame, but " 961 "WPA SM not available"); 962 return; 963 } 964 965 wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR 966 " BSSID=" MACSTR " transaction=%d", 967 MAC2STR(sm->addr), MAC2STR(bssid), auth_transaction); 968 sm->ft_pending_cb = cb; 969 sm->ft_pending_cb_ctx = ctx; 970 sm->ft_pending_auth_transaction = auth_transaction; 971 res = wpa_ft_process_auth_req(sm, ies, ies_len, &resp_ies, 972 &resp_ies_len); 973 if (res < 0) { 974 wpa_printf(MSG_DEBUG, "FT: Callback postponed until response is available"); 975 return; 976 } 977 status = res; 978 979 wpa_printf(MSG_DEBUG, "FT: FT authentication response: dst=" MACSTR 980 " auth_transaction=%d status=%d", 981 MAC2STR(sm->addr), auth_transaction + 1, status); 982 wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len); 983 cb(ctx, sm->addr, bssid, auth_transaction + 1, status, 984 resp_ies, resp_ies_len); 985 os_free(resp_ies); 986 } 987 988 989 u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, 990 size_t ies_len) 991 { 992 struct wpa_ft_ies parse; 993 struct rsn_mdie *mdie; 994 struct rsn_ftie *ftie; 995 u8 mic[16]; 996 unsigned int count; 997 998 if (sm == NULL) 999 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1000 1001 wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len); 1002 1003 if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) { 1004 wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs"); 1005 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1006 } 1007 1008 if (parse.rsn == NULL) { 1009 wpa_printf(MSG_DEBUG, "FT: No RSNIE in Reassoc Req"); 1010 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1011 } 1012 1013 if (parse.rsn_pmkid == NULL) { 1014 wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE"); 1015 return WLAN_STATUS_INVALID_PMKID; 1016 } 1017 1018 if (os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) 1019 != 0) { 1020 wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match " 1021 "with the PMKR1Name derived from auth request"); 1022 return WLAN_STATUS_INVALID_PMKID; 1023 } 1024 1025 mdie = (struct rsn_mdie *) parse.mdie; 1026 if (mdie == NULL || parse.mdie_len < sizeof(*mdie) || 1027 os_memcmp(mdie->mobility_domain, 1028 sm->wpa_auth->conf.mobility_domain, 1029 MOBILITY_DOMAIN_ID_LEN) != 0) { 1030 wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); 1031 return WLAN_STATUS_INVALID_MDIE; 1032 } 1033 1034 ftie = (struct rsn_ftie *) parse.ftie; 1035 if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) { 1036 wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); 1037 return WLAN_STATUS_INVALID_FTIE; 1038 } 1039 1040 if (os_memcmp(ftie->snonce, sm->SNonce, WPA_NONCE_LEN) != 0) { 1041 wpa_printf(MSG_DEBUG, "FT: SNonce mismatch in FTIE"); 1042 wpa_hexdump(MSG_DEBUG, "FT: Received SNonce", 1043 ftie->snonce, WPA_NONCE_LEN); 1044 wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", 1045 sm->SNonce, WPA_NONCE_LEN); 1046 return -1; 1047 } 1048 1049 if (os_memcmp(ftie->anonce, sm->ANonce, WPA_NONCE_LEN) != 0) { 1050 wpa_printf(MSG_DEBUG, "FT: ANonce mismatch in FTIE"); 1051 wpa_hexdump(MSG_DEBUG, "FT: Received ANonce", 1052 ftie->anonce, WPA_NONCE_LEN); 1053 wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce", 1054 sm->ANonce, WPA_NONCE_LEN); 1055 return -1; 1056 } 1057 1058 1059 if (parse.r0kh_id == NULL) { 1060 wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE"); 1061 return -1; 1062 } 1063 1064 if (parse.r0kh_id_len != sm->r0kh_id_len || 1065 os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) 1066 { 1067 wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with " 1068 "the current R0KH-ID"); 1069 wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE", 1070 parse.r0kh_id, parse.r0kh_id_len); 1071 wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID", 1072 sm->r0kh_id, sm->r0kh_id_len); 1073 return -1; 1074 } 1075 1076 if (parse.r1kh_id == NULL) { 1077 wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE"); 1078 return -1; 1079 } 1080 1081 if (os_memcmp_const(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder, 1082 FT_R1KH_ID_LEN) != 0) { 1083 wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in " 1084 "ReassocReq"); 1085 wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID in FTIE", 1086 parse.r1kh_id, FT_R1KH_ID_LEN); 1087 wpa_hexdump(MSG_DEBUG, "FT: Expected R1KH-ID", 1088 sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN); 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 (ftie->mic_control[1] != count) { 1104 wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC " 1105 "Control: received %u expected %u", 1106 ftie->mic_control[1], count); 1107 return -1; 1108 } 1109 1110 if (wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 5, 1111 parse.mdie - 2, parse.mdie_len + 2, 1112 parse.ftie - 2, parse.ftie_len + 2, 1113 parse.rsn - 2, parse.rsn_len + 2, 1114 parse.ric, parse.ric_len, 1115 mic) < 0) { 1116 wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); 1117 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1118 } 1119 1120 if (os_memcmp_const(mic, ftie->mic, 16) != 0) { 1121 wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE"); 1122 wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR, 1123 MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr)); 1124 wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16); 1125 wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16); 1126 wpa_hexdump(MSG_MSGDUMP, "FT: MDIE", 1127 parse.mdie - 2, parse.mdie_len + 2); 1128 wpa_hexdump(MSG_MSGDUMP, "FT: FTIE", 1129 parse.ftie - 2, parse.ftie_len + 2); 1130 wpa_hexdump(MSG_MSGDUMP, "FT: RSN", 1131 parse.rsn - 2, parse.rsn_len + 2); 1132 return WLAN_STATUS_INVALID_FTIE; 1133 } 1134 1135 return WLAN_STATUS_SUCCESS; 1136 } 1137 1138 1139 int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len) 1140 { 1141 const u8 *sta_addr, *target_ap; 1142 const u8 *ies; 1143 size_t ies_len; 1144 u8 action; 1145 struct ft_rrb_frame *frame; 1146 1147 if (sm == NULL) 1148 return -1; 1149 1150 /* 1151 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6] 1152 * FT Request action frame body[variable] 1153 */ 1154 1155 if (len < 14) { 1156 wpa_printf(MSG_DEBUG, "FT: Too short FT Action frame " 1157 "(len=%lu)", (unsigned long) len); 1158 return -1; 1159 } 1160 1161 action = data[1]; 1162 sta_addr = data + 2; 1163 target_ap = data + 8; 1164 ies = data + 14; 1165 ies_len = len - 14; 1166 1167 wpa_printf(MSG_DEBUG, "FT: Received FT Action frame (STA=" MACSTR 1168 " Target AP=" MACSTR " Action=%d)", 1169 MAC2STR(sta_addr), MAC2STR(target_ap), action); 1170 1171 if (os_memcmp(sta_addr, sm->addr, ETH_ALEN) != 0) { 1172 wpa_printf(MSG_DEBUG, "FT: Mismatch in FT Action STA address: " 1173 "STA=" MACSTR " STA-Address=" MACSTR, 1174 MAC2STR(sm->addr), MAC2STR(sta_addr)); 1175 return -1; 1176 } 1177 1178 /* 1179 * Do some sanity checking on the target AP address (not own and not 1180 * broadcast. This could be extended to filter based on a list of known 1181 * APs in the MD (if such a list were configured). 1182 */ 1183 if ((target_ap[0] & 0x01) || 1184 os_memcmp(target_ap, sm->wpa_auth->addr, ETH_ALEN) == 0) { 1185 wpa_printf(MSG_DEBUG, "FT: Invalid Target AP in FT Action " 1186 "frame"); 1187 return -1; 1188 } 1189 1190 wpa_hexdump(MSG_MSGDUMP, "FT: Action frame body", ies, ies_len); 1191 1192 /* RRB - Forward action frame to the target AP */ 1193 frame = os_malloc(sizeof(*frame) + len); 1194 if (frame == NULL) 1195 return -1; 1196 frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB; 1197 frame->packet_type = FT_PACKET_REQUEST; 1198 frame->action_length = host_to_le16(len); 1199 os_memcpy(frame->ap_address, sm->wpa_auth->addr, ETH_ALEN); 1200 os_memcpy(frame + 1, data, len); 1201 1202 wpa_ft_rrb_send(sm->wpa_auth, target_ap, (u8 *) frame, 1203 sizeof(*frame) + len); 1204 os_free(frame); 1205 1206 return 0; 1207 } 1208 1209 1210 static void wpa_ft_rrb_rx_request_cb(void *ctx, const u8 *dst, const u8 *bssid, 1211 u16 auth_transaction, u16 resp, 1212 const u8 *ies, size_t ies_len) 1213 { 1214 struct wpa_state_machine *sm = ctx; 1215 wpa_printf(MSG_DEBUG, "FT: Over-the-DS RX request cb for " MACSTR, 1216 MAC2STR(sm->addr)); 1217 wpa_ft_send_rrb_auth_resp(sm, sm->ft_pending_current_ap, sm->addr, 1218 WLAN_STATUS_SUCCESS, ies, ies_len); 1219 } 1220 1221 1222 static int wpa_ft_rrb_rx_request(struct wpa_authenticator *wpa_auth, 1223 const u8 *current_ap, const u8 *sta_addr, 1224 const u8 *body, size_t len) 1225 { 1226 struct wpa_state_machine *sm; 1227 u16 status; 1228 u8 *resp_ies; 1229 size_t resp_ies_len; 1230 int res; 1231 1232 sm = wpa_ft_add_sta(wpa_auth, sta_addr); 1233 if (sm == NULL) { 1234 wpa_printf(MSG_DEBUG, "FT: Failed to add new STA based on " 1235 "RRB Request"); 1236 return -1; 1237 } 1238 1239 wpa_hexdump(MSG_MSGDUMP, "FT: RRB Request Frame body", body, len); 1240 1241 sm->ft_pending_cb = wpa_ft_rrb_rx_request_cb; 1242 sm->ft_pending_cb_ctx = sm; 1243 os_memcpy(sm->ft_pending_current_ap, current_ap, ETH_ALEN); 1244 res = wpa_ft_process_auth_req(sm, body, len, &resp_ies, 1245 &resp_ies_len); 1246 if (res < 0) { 1247 wpa_printf(MSG_DEBUG, "FT: No immediate response available - wait for pull response"); 1248 return 0; 1249 } 1250 status = res; 1251 1252 res = wpa_ft_send_rrb_auth_resp(sm, current_ap, sta_addr, status, 1253 resp_ies, resp_ies_len); 1254 os_free(resp_ies); 1255 return res; 1256 } 1257 1258 1259 static int wpa_ft_send_rrb_auth_resp(struct wpa_state_machine *sm, 1260 const u8 *current_ap, const u8 *sta_addr, 1261 u16 status, const u8 *resp_ies, 1262 size_t resp_ies_len) 1263 { 1264 struct wpa_authenticator *wpa_auth = sm->wpa_auth; 1265 size_t rlen; 1266 struct ft_rrb_frame *frame; 1267 u8 *pos; 1268 1269 wpa_printf(MSG_DEBUG, "FT: RRB authentication response: STA=" MACSTR 1270 " CurrentAP=" MACSTR " status=%d", 1271 MAC2STR(sm->addr), MAC2STR(current_ap), status); 1272 wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len); 1273 1274 /* RRB - Forward action frame response to the Current AP */ 1275 1276 /* 1277 * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6] 1278 * Status_Code[2] FT Request action frame body[variable] 1279 */ 1280 rlen = 2 + 2 * ETH_ALEN + 2 + resp_ies_len; 1281 1282 frame = os_malloc(sizeof(*frame) + rlen); 1283 if (frame == NULL) 1284 return -1; 1285 frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB; 1286 frame->packet_type = FT_PACKET_RESPONSE; 1287 frame->action_length = host_to_le16(rlen); 1288 os_memcpy(frame->ap_address, wpa_auth->addr, ETH_ALEN); 1289 pos = (u8 *) (frame + 1); 1290 *pos++ = WLAN_ACTION_FT; 1291 *pos++ = 2; /* Action: Response */ 1292 os_memcpy(pos, sta_addr, ETH_ALEN); 1293 pos += ETH_ALEN; 1294 os_memcpy(pos, wpa_auth->addr, ETH_ALEN); 1295 pos += ETH_ALEN; 1296 WPA_PUT_LE16(pos, status); 1297 pos += 2; 1298 if (resp_ies) 1299 os_memcpy(pos, resp_ies, resp_ies_len); 1300 1301 wpa_ft_rrb_send(wpa_auth, current_ap, (u8 *) frame, 1302 sizeof(*frame) + rlen); 1303 os_free(frame); 1304 1305 return 0; 1306 } 1307 1308 1309 static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth, 1310 const u8 *src_addr, 1311 const u8 *data, size_t data_len) 1312 { 1313 struct ft_r0kh_r1kh_pull_frame *frame, f; 1314 struct ft_remote_r1kh *r1kh; 1315 struct ft_r0kh_r1kh_resp_frame resp, r; 1316 u8 pmk_r0[PMK_LEN]; 1317 int pairwise; 1318 1319 wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull"); 1320 1321 if (data_len < sizeof(*frame)) 1322 return -1; 1323 1324 r1kh = wpa_auth->conf.r1kh_list; 1325 while (r1kh) { 1326 if (os_memcmp(r1kh->addr, src_addr, ETH_ALEN) == 0) 1327 break; 1328 r1kh = r1kh->next; 1329 } 1330 if (r1kh == NULL) { 1331 wpa_printf(MSG_DEBUG, "FT: No matching R1KH address found for " 1332 "PMK-R1 pull source address " MACSTR, 1333 MAC2STR(src_addr)); 1334 return -1; 1335 } 1336 1337 frame = (struct ft_r0kh_r1kh_pull_frame *) data; 1338 /* aes_unwrap() does not support inplace decryption, so use a temporary 1339 * buffer for the data. */ 1340 if (aes_unwrap(r1kh->key, sizeof(r1kh->key), 1341 (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8, 1342 frame->nonce, f.nonce) < 0) { 1343 wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull " 1344 "request from " MACSTR, MAC2STR(src_addr)); 1345 return -1; 1346 } 1347 1348 wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce", 1349 f.nonce, sizeof(f.nonce)); 1350 wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR0Name", 1351 f.pmk_r0_name, WPA_PMK_NAME_LEN); 1352 wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID=" 1353 MACSTR, MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id)); 1354 1355 os_memset(&resp, 0, sizeof(resp)); 1356 resp.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB; 1357 resp.packet_type = FT_PACKET_R0KH_R1KH_RESP; 1358 resp.data_length = host_to_le16(FT_R0KH_R1KH_RESP_DATA_LEN); 1359 os_memcpy(resp.ap_address, wpa_auth->addr, ETH_ALEN); 1360 1361 /* aes_wrap() does not support inplace encryption, so use a temporary 1362 * buffer for the data. */ 1363 os_memcpy(r.nonce, f.nonce, sizeof(f.nonce)); 1364 os_memcpy(r.r1kh_id, f.r1kh_id, FT_R1KH_ID_LEN); 1365 os_memcpy(r.s1kh_id, f.s1kh_id, ETH_ALEN); 1366 if (wpa_ft_fetch_pmk_r0(wpa_auth, f.s1kh_id, f.pmk_r0_name, pmk_r0, 1367 &pairwise) < 0) { 1368 wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name found for " 1369 "PMK-R1 pull"); 1370 return -1; 1371 } 1372 1373 wpa_derive_pmk_r1(pmk_r0, f.pmk_r0_name, f.r1kh_id, f.s1kh_id, 1374 r.pmk_r1, r.pmk_r1_name); 1375 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", r.pmk_r1, PMK_LEN); 1376 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", r.pmk_r1_name, 1377 WPA_PMK_NAME_LEN); 1378 r.pairwise = host_to_le16(pairwise); 1379 os_memset(r.pad, 0, sizeof(r.pad)); 1380 1381 if (aes_wrap(r1kh->key, sizeof(r1kh->key), 1382 (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8, 1383 r.nonce, resp.nonce) < 0) { 1384 os_memset(pmk_r0, 0, PMK_LEN); 1385 return -1; 1386 } 1387 1388 os_memset(pmk_r0, 0, PMK_LEN); 1389 1390 wpa_ft_rrb_send(wpa_auth, src_addr, (u8 *) &resp, sizeof(resp)); 1391 1392 return 0; 1393 } 1394 1395 1396 static void ft_pull_resp_cb_finish(void *eloop_ctx, void *timeout_ctx) 1397 { 1398 struct wpa_state_machine *sm = eloop_ctx; 1399 int res; 1400 u8 *resp_ies; 1401 size_t resp_ies_len; 1402 u16 status; 1403 1404 res = wpa_ft_process_auth_req(sm, wpabuf_head(sm->ft_pending_req_ies), 1405 wpabuf_len(sm->ft_pending_req_ies), 1406 &resp_ies, &resp_ies_len); 1407 wpabuf_free(sm->ft_pending_req_ies); 1408 sm->ft_pending_req_ies = NULL; 1409 if (res < 0) 1410 res = WLAN_STATUS_UNSPECIFIED_FAILURE; 1411 status = res; 1412 wpa_printf(MSG_DEBUG, "FT: Postponed auth callback result for " MACSTR 1413 " - status %u", MAC2STR(sm->addr), status); 1414 1415 sm->ft_pending_cb(sm->ft_pending_cb_ctx, sm->addr, sm->wpa_auth->addr, 1416 sm->ft_pending_auth_transaction + 1, status, 1417 resp_ies, resp_ies_len); 1418 os_free(resp_ies); 1419 } 1420 1421 1422 static int ft_pull_resp_cb(struct wpa_state_machine *sm, void *ctx) 1423 { 1424 struct ft_r0kh_r1kh_resp_frame *frame = ctx; 1425 1426 if (os_memcmp(frame->s1kh_id, sm->addr, ETH_ALEN) != 0) 1427 return 0; 1428 if (os_memcmp(frame->nonce, sm->ft_pending_pull_nonce, 1429 FT_R0KH_R1KH_PULL_NONCE_LEN) != 0) 1430 return 0; 1431 if (sm->ft_pending_cb == NULL || sm->ft_pending_req_ies == NULL) 1432 return 0; 1433 1434 wpa_printf(MSG_DEBUG, "FT: Response to a pending pull request for " 1435 MACSTR " - process from timeout", MAC2STR(sm->addr)); 1436 eloop_register_timeout(0, 0, ft_pull_resp_cb_finish, sm, NULL); 1437 return 1; 1438 } 1439 1440 1441 static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth, 1442 const u8 *src_addr, 1443 const u8 *data, size_t data_len) 1444 { 1445 struct ft_r0kh_r1kh_resp_frame *frame, f; 1446 struct ft_remote_r0kh *r0kh; 1447 int pairwise, res; 1448 1449 wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull response"); 1450 1451 if (data_len < sizeof(*frame)) 1452 return -1; 1453 1454 r0kh = wpa_auth->conf.r0kh_list; 1455 while (r0kh) { 1456 if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0) 1457 break; 1458 r0kh = r0kh->next; 1459 } 1460 if (r0kh == NULL) { 1461 wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for " 1462 "PMK-R0 pull response source address " MACSTR, 1463 MAC2STR(src_addr)); 1464 return -1; 1465 } 1466 1467 frame = (struct ft_r0kh_r1kh_resp_frame *) data; 1468 /* aes_unwrap() does not support inplace decryption, so use a temporary 1469 * buffer for the data. */ 1470 if (aes_unwrap(r0kh->key, sizeof(r0kh->key), 1471 (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8, 1472 frame->nonce, f.nonce) < 0) { 1473 wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull " 1474 "response from " MACSTR, MAC2STR(src_addr)); 1475 return -1; 1476 } 1477 1478 if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder, 1479 FT_R1KH_ID_LEN) != 0) { 1480 wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull response did not use a " 1481 "matching R1KH-ID"); 1482 return -1; 1483 } 1484 1485 pairwise = le_to_host16(f.pairwise); 1486 wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce", 1487 f.nonce, sizeof(f.nonce)); 1488 wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR " S1KH-ID=" 1489 MACSTR " pairwise=0x%x", 1490 MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id), pairwise); 1491 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 pull - PMK-R1", 1492 f.pmk_r1, PMK_LEN); 1493 wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR1Name", 1494 f.pmk_r1_name, WPA_PMK_NAME_LEN); 1495 1496 res = wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name, 1497 pairwise); 1498 wpa_printf(MSG_DEBUG, "FT: Look for pending pull request"); 1499 wpa_auth_for_each_sta(wpa_auth, ft_pull_resp_cb, &f); 1500 os_memset(f.pmk_r1, 0, PMK_LEN); 1501 1502 return res ? 0 : -1; 1503 } 1504 1505 1506 static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth, 1507 const u8 *src_addr, 1508 const u8 *data, size_t data_len) 1509 { 1510 struct ft_r0kh_r1kh_push_frame *frame, f; 1511 struct ft_remote_r0kh *r0kh; 1512 struct os_time now; 1513 os_time_t tsend; 1514 int pairwise; 1515 1516 wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 push"); 1517 1518 if (data_len < sizeof(*frame)) 1519 return -1; 1520 1521 r0kh = wpa_auth->conf.r0kh_list; 1522 while (r0kh) { 1523 if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0) 1524 break; 1525 r0kh = r0kh->next; 1526 } 1527 if (r0kh == NULL) { 1528 wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for " 1529 "PMK-R0 push source address " MACSTR, 1530 MAC2STR(src_addr)); 1531 return -1; 1532 } 1533 1534 frame = (struct ft_r0kh_r1kh_push_frame *) data; 1535 /* aes_unwrap() does not support inplace decryption, so use a temporary 1536 * buffer for the data. */ 1537 if (aes_unwrap(r0kh->key, sizeof(r0kh->key), 1538 (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8, 1539 frame->timestamp, f.timestamp) < 0) { 1540 wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 push from " 1541 MACSTR, MAC2STR(src_addr)); 1542 return -1; 1543 } 1544 1545 os_get_time(&now); 1546 tsend = WPA_GET_LE32(f.timestamp); 1547 if ((now.sec > tsend && now.sec - tsend > 60) || 1548 (now.sec < tsend && tsend - now.sec > 60)) { 1549 wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not have a valid " 1550 "timestamp: sender time %d own time %d\n", 1551 (int) tsend, (int) now.sec); 1552 return -1; 1553 } 1554 1555 if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder, 1556 FT_R1KH_ID_LEN) != 0) { 1557 wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not use a matching " 1558 "R1KH-ID (received " MACSTR " own " MACSTR ")", 1559 MAC2STR(f.r1kh_id), 1560 MAC2STR(wpa_auth->conf.r1_key_holder)); 1561 return -1; 1562 } 1563 1564 pairwise = le_to_host16(f.pairwise); 1565 wpa_printf(MSG_DEBUG, "FT: PMK-R1 push - R1KH-ID=" MACSTR " S1KH-ID=" 1566 MACSTR " pairwise=0x%x", 1567 MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id), pairwise); 1568 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 push - PMK-R1", 1569 f.pmk_r1, PMK_LEN); 1570 wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 push - PMKR1Name", 1571 f.pmk_r1_name, WPA_PMK_NAME_LEN); 1572 1573 wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name, 1574 pairwise); 1575 os_memset(f.pmk_r1, 0, PMK_LEN); 1576 1577 return 0; 1578 } 1579 1580 1581 int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr, 1582 const u8 *data, size_t data_len) 1583 { 1584 struct ft_rrb_frame *frame; 1585 u16 alen; 1586 const u8 *pos, *end, *start; 1587 u8 action; 1588 const u8 *sta_addr, *target_ap_addr; 1589 1590 wpa_printf(MSG_DEBUG, "FT: RRB received frame from remote AP " MACSTR, 1591 MAC2STR(src_addr)); 1592 1593 if (data_len < sizeof(*frame)) { 1594 wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (data_len=%lu)", 1595 (unsigned long) data_len); 1596 return -1; 1597 } 1598 1599 pos = data; 1600 frame = (struct ft_rrb_frame *) pos; 1601 pos += sizeof(*frame); 1602 1603 alen = le_to_host16(frame->action_length); 1604 wpa_printf(MSG_DEBUG, "FT: RRB frame - frame_type=%d packet_type=%d " 1605 "action_length=%d ap_address=" MACSTR, 1606 frame->frame_type, frame->packet_type, alen, 1607 MAC2STR(frame->ap_address)); 1608 1609 if (frame->frame_type != RSN_REMOTE_FRAME_TYPE_FT_RRB) { 1610 /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */ 1611 wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with " 1612 "unrecognized type %d", frame->frame_type); 1613 return -1; 1614 } 1615 1616 if (alen > data_len - sizeof(*frame)) { 1617 wpa_printf(MSG_DEBUG, "FT: RRB frame too short for action " 1618 "frame"); 1619 return -1; 1620 } 1621 1622 if (frame->packet_type == FT_PACKET_R0KH_R1KH_PULL) 1623 return wpa_ft_rrb_rx_pull(wpa_auth, src_addr, data, data_len); 1624 if (frame->packet_type == FT_PACKET_R0KH_R1KH_RESP) 1625 return wpa_ft_rrb_rx_resp(wpa_auth, src_addr, data, data_len); 1626 if (frame->packet_type == FT_PACKET_R0KH_R1KH_PUSH) 1627 return wpa_ft_rrb_rx_push(wpa_auth, src_addr, data, data_len); 1628 1629 wpa_hexdump(MSG_MSGDUMP, "FT: RRB - FT Action frame", pos, alen); 1630 1631 if (alen < 1 + 1 + 2 * ETH_ALEN) { 1632 wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (not enough " 1633 "room for Action Frame body); alen=%lu", 1634 (unsigned long) alen); 1635 return -1; 1636 } 1637 start = pos; 1638 end = pos + alen; 1639 1640 if (*pos != WLAN_ACTION_FT) { 1641 wpa_printf(MSG_DEBUG, "FT: Unexpected Action frame category " 1642 "%d", *pos); 1643 return -1; 1644 } 1645 1646 pos++; 1647 action = *pos++; 1648 sta_addr = pos; 1649 pos += ETH_ALEN; 1650 target_ap_addr = pos; 1651 pos += ETH_ALEN; 1652 wpa_printf(MSG_DEBUG, "FT: RRB Action Frame: action=%d sta_addr=" 1653 MACSTR " target_ap_addr=" MACSTR, 1654 action, MAC2STR(sta_addr), MAC2STR(target_ap_addr)); 1655 1656 if (frame->packet_type == FT_PACKET_REQUEST) { 1657 wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Request"); 1658 1659 if (action != 1) { 1660 wpa_printf(MSG_DEBUG, "FT: Unexpected Action %d in " 1661 "RRB Request", action); 1662 return -1; 1663 } 1664 1665 if (os_memcmp(target_ap_addr, wpa_auth->addr, ETH_ALEN) != 0) { 1666 wpa_printf(MSG_DEBUG, "FT: Target AP address in the " 1667 "RRB Request does not match with own " 1668 "address"); 1669 return -1; 1670 } 1671 1672 if (wpa_ft_rrb_rx_request(wpa_auth, frame->ap_address, 1673 sta_addr, pos, end - pos) < 0) 1674 return -1; 1675 } else if (frame->packet_type == FT_PACKET_RESPONSE) { 1676 u16 status_code; 1677 1678 if (end - pos < 2) { 1679 wpa_printf(MSG_DEBUG, "FT: Not enough room for status " 1680 "code in RRB Response"); 1681 return -1; 1682 } 1683 status_code = WPA_GET_LE16(pos); 1684 pos += 2; 1685 1686 wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Response " 1687 "(status_code=%d)", status_code); 1688 1689 if (wpa_ft_action_send(wpa_auth, sta_addr, start, alen) < 0) 1690 return -1; 1691 } else { 1692 wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with unknown " 1693 "packet_type %d", frame->packet_type); 1694 return -1; 1695 } 1696 1697 if (end > pos) { 1698 wpa_hexdump(MSG_DEBUG, "FT: Ignore extra data in end", 1699 pos, end - pos); 1700 } 1701 1702 return 0; 1703 } 1704 1705 1706 static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth, 1707 struct wpa_ft_pmk_r0_sa *pmk_r0, 1708 struct ft_remote_r1kh *r1kh, 1709 const u8 *s1kh_id, int pairwise) 1710 { 1711 struct ft_r0kh_r1kh_push_frame frame, f; 1712 struct os_time now; 1713 1714 os_memset(&frame, 0, sizeof(frame)); 1715 frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB; 1716 frame.packet_type = FT_PACKET_R0KH_R1KH_PUSH; 1717 frame.data_length = host_to_le16(FT_R0KH_R1KH_PUSH_DATA_LEN); 1718 os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN); 1719 1720 /* aes_wrap() does not support inplace encryption, so use a temporary 1721 * buffer for the data. */ 1722 os_memcpy(f.r1kh_id, r1kh->id, FT_R1KH_ID_LEN); 1723 os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN); 1724 os_memcpy(f.pmk_r0_name, pmk_r0->pmk_r0_name, WPA_PMK_NAME_LEN); 1725 wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh->id, 1726 s1kh_id, f.pmk_r1, f.pmk_r1_name); 1727 wpa_printf(MSG_DEBUG, "FT: R1KH-ID " MACSTR, MAC2STR(r1kh->id)); 1728 wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", f.pmk_r1, PMK_LEN); 1729 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", f.pmk_r1_name, 1730 WPA_PMK_NAME_LEN); 1731 os_get_time(&now); 1732 WPA_PUT_LE32(f.timestamp, now.sec); 1733 f.pairwise = host_to_le16(pairwise); 1734 os_memset(f.pad, 0, sizeof(f.pad)); 1735 if (aes_wrap(r1kh->key, sizeof(r1kh->key), 1736 (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8, 1737 f.timestamp, frame.timestamp) < 0) 1738 return; 1739 1740 wpa_ft_rrb_send(wpa_auth, r1kh->addr, (u8 *) &frame, sizeof(frame)); 1741 } 1742 1743 1744 void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr) 1745 { 1746 struct wpa_ft_pmk_r0_sa *r0; 1747 struct ft_remote_r1kh *r1kh; 1748 1749 if (!wpa_auth->conf.pmk_r1_push) 1750 return; 1751 1752 r0 = wpa_auth->ft_pmk_cache->pmk_r0; 1753 while (r0) { 1754 if (os_memcmp(r0->spa, addr, ETH_ALEN) == 0) 1755 break; 1756 r0 = r0->next; 1757 } 1758 1759 if (r0 == NULL || r0->pmk_r1_pushed) 1760 return; 1761 r0->pmk_r1_pushed = 1; 1762 1763 wpa_printf(MSG_DEBUG, "FT: Deriving and pushing PMK-R1 keys to R1KHs " 1764 "for STA " MACSTR, MAC2STR(addr)); 1765 1766 r1kh = wpa_auth->conf.r1kh_list; 1767 while (r1kh) { 1768 wpa_ft_generate_pmk_r1(wpa_auth, r0, r1kh, addr, r0->pairwise); 1769 r1kh = r1kh->next; 1770 } 1771 } 1772 1773 #endif /* CONFIG_IEEE80211R */ 1774