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