1 /* 2 * WPA Supplicant - Mesh RSN routines 3 * Copyright (c) 2013-2014, cozybit, Inc. All rights reserved. 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 "crypto/sha256.h" 14 #include "crypto/random.h" 15 #include "crypto/aes.h" 16 #include "crypto/aes_siv.h" 17 #include "rsn_supp/wpa.h" 18 #include "ap/hostapd.h" 19 #include "ap/wpa_auth.h" 20 #include "ap/sta_info.h" 21 #include "ap/ieee802_11.h" 22 #include "wpa_supplicant_i.h" 23 #include "driver_i.h" 24 #include "wpas_glue.h" 25 #include "mesh_mpm.h" 26 #include "mesh_rsn.h" 27 28 #define MESH_AUTH_TIMEOUT 10 29 #define MESH_AUTH_RETRY 3 30 31 void mesh_auth_timer(void *eloop_ctx, void *user_data) 32 { 33 struct wpa_supplicant *wpa_s = eloop_ctx; 34 struct sta_info *sta = user_data; 35 struct hostapd_data *hapd; 36 37 if (sta->sae->state != SAE_ACCEPTED) { 38 wpa_printf(MSG_DEBUG, "AUTH: Re-authenticate with " MACSTR 39 " (attempt %d) ", 40 MAC2STR(sta->addr), sta->sae_auth_retry); 41 wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_FAILURE "addr=" MACSTR, 42 MAC2STR(sta->addr)); 43 if (sta->sae_auth_retry < MESH_AUTH_RETRY) { 44 mesh_rsn_auth_sae_sta(wpa_s, sta); 45 } else { 46 hapd = wpa_s->ifmsh->bss[0]; 47 48 if (sta->sae_auth_retry > MESH_AUTH_RETRY) { 49 ap_free_sta(hapd, sta); 50 return; 51 } 52 53 /* block the STA if exceeded the number of attempts */ 54 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_BLOCKED); 55 sta->sae->state = SAE_NOTHING; 56 wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_BLOCKED "addr=" 57 MACSTR " duration=%d", 58 MAC2STR(sta->addr), 59 hapd->conf->ap_max_inactivity); 60 } 61 sta->sae_auth_retry++; 62 } 63 } 64 65 66 static void auth_logger(void *ctx, const u8 *addr, logger_level level, 67 const char *txt) 68 { 69 if (addr) 70 wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s", 71 MAC2STR(addr), txt); 72 else 73 wpa_printf(MSG_DEBUG, "AUTH: %s", txt); 74 } 75 76 77 static const u8 *auth_get_psk(void *ctx, const u8 *addr, 78 const u8 *p2p_dev_addr, const u8 *prev_psk, 79 size_t *psk_len) 80 { 81 struct mesh_rsn *mesh_rsn = ctx; 82 struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0]; 83 struct sta_info *sta = ap_get_sta(hapd, addr); 84 85 if (psk_len) 86 *psk_len = PMK_LEN; 87 wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)", 88 __func__, MAC2STR(addr), prev_psk); 89 90 if (sta && sta->auth_alg == WLAN_AUTH_SAE) { 91 if (!sta->sae || prev_psk) 92 return NULL; 93 return sta->sae->pmk; 94 } 95 96 return NULL; 97 } 98 99 100 static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, 101 const u8 *addr, int idx, u8 *key, size_t key_len) 102 { 103 struct mesh_rsn *mesh_rsn = ctx; 104 u8 seq[6]; 105 106 os_memset(seq, 0, sizeof(seq)); 107 108 if (addr) { 109 wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR 110 " key_idx=%d)", 111 __func__, alg, MAC2STR(addr), idx); 112 } else { 113 wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)", 114 __func__, alg, idx); 115 } 116 wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len); 117 118 return wpa_drv_set_key(mesh_rsn->wpa_s, alg, addr, idx, 119 1, seq, 6, key, key_len); 120 } 121 122 123 static int auth_start_ampe(void *ctx, const u8 *addr) 124 { 125 struct mesh_rsn *mesh_rsn = ctx; 126 struct hostapd_data *hapd; 127 struct sta_info *sta; 128 129 if (mesh_rsn->wpa_s->current_ssid->mode != WPAS_MODE_MESH) 130 return -1; 131 132 hapd = mesh_rsn->wpa_s->ifmsh->bss[0]; 133 sta = ap_get_sta(hapd, addr); 134 if (sta) 135 eloop_cancel_timeout(mesh_auth_timer, mesh_rsn->wpa_s, sta); 136 137 mesh_mpm_auth_peer(mesh_rsn->wpa_s, addr); 138 return 0; 139 } 140 141 142 static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr, 143 enum mfp_options ieee80211w) 144 { 145 struct wpa_auth_config conf; 146 static const struct wpa_auth_callbacks cb = { 147 .logger = auth_logger, 148 .get_psk = auth_get_psk, 149 .set_key = auth_set_key, 150 .start_ampe = auth_start_ampe, 151 }; 152 u8 seq[6] = {}; 153 154 wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine"); 155 156 os_memset(&conf, 0, sizeof(conf)); 157 conf.wpa = WPA_PROTO_RSN; 158 conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE; 159 conf.wpa_pairwise = rsn->pairwise_cipher; 160 conf.rsn_pairwise = rsn->pairwise_cipher; 161 conf.wpa_group = rsn->group_cipher; 162 conf.eapol_version = 0; 163 conf.wpa_group_rekey = -1; 164 conf.wpa_group_update_count = 4; 165 conf.wpa_pairwise_update_count = 4; 166 #ifdef CONFIG_IEEE80211W 167 conf.ieee80211w = ieee80211w; 168 if (ieee80211w != NO_MGMT_FRAME_PROTECTION) 169 conf.group_mgmt_cipher = rsn->mgmt_group_cipher; 170 #endif /* CONFIG_IEEE80211W */ 171 172 rsn->auth = wpa_init(addr, &conf, &cb, rsn); 173 if (rsn->auth == NULL) { 174 wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed"); 175 return -1; 176 } 177 178 /* TODO: support rekeying */ 179 rsn->mgtk_len = wpa_cipher_key_len(conf.wpa_group); 180 if (random_get_bytes(rsn->mgtk, rsn->mgtk_len) < 0) 181 return -1; 182 rsn->mgtk_key_id = 1; 183 184 #ifdef CONFIG_IEEE80211W 185 if (ieee80211w != NO_MGMT_FRAME_PROTECTION) { 186 rsn->igtk_len = wpa_cipher_key_len(conf.group_mgmt_cipher); 187 if (random_get_bytes(rsn->igtk, rsn->igtk_len) < 0) 188 return -1; 189 rsn->igtk_key_id = 4; 190 191 /* group mgmt */ 192 wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX IGTK", 193 rsn->igtk, rsn->igtk_len); 194 wpa_drv_set_key(rsn->wpa_s, 195 wpa_cipher_to_alg(rsn->mgmt_group_cipher), NULL, 196 rsn->igtk_key_id, 1, 197 seq, sizeof(seq), rsn->igtk, rsn->igtk_len); 198 } 199 #endif /* CONFIG_IEEE80211W */ 200 201 /* group privacy / data frames */ 202 wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX MGTK", 203 rsn->mgtk, rsn->mgtk_len); 204 wpa_drv_set_key(rsn->wpa_s, wpa_cipher_to_alg(rsn->group_cipher), NULL, 205 rsn->mgtk_key_id, 1, seq, sizeof(seq), 206 rsn->mgtk, rsn->mgtk_len); 207 208 return 0; 209 } 210 211 212 static void mesh_rsn_deinit(struct mesh_rsn *rsn) 213 { 214 os_memset(rsn->mgtk, 0, sizeof(rsn->mgtk)); 215 rsn->mgtk_len = 0; 216 os_memset(rsn->igtk, 0, sizeof(rsn->igtk)); 217 rsn->igtk_len = 0; 218 if (rsn->auth) 219 wpa_deinit(rsn->auth); 220 } 221 222 223 struct mesh_rsn *mesh_rsn_auth_init(struct wpa_supplicant *wpa_s, 224 struct mesh_conf *conf) 225 { 226 struct mesh_rsn *mesh_rsn; 227 struct hostapd_data *bss = wpa_s->ifmsh->bss[0]; 228 const u8 *ie; 229 size_t ie_len; 230 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL 231 struct external_pmksa_cache *entry; 232 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 233 234 mesh_rsn = os_zalloc(sizeof(*mesh_rsn)); 235 if (mesh_rsn == NULL) 236 return NULL; 237 mesh_rsn->wpa_s = wpa_s; 238 mesh_rsn->pairwise_cipher = conf->pairwise_cipher; 239 mesh_rsn->group_cipher = conf->group_cipher; 240 mesh_rsn->mgmt_group_cipher = conf->mgmt_group_cipher; 241 242 if (__mesh_rsn_auth_init(mesh_rsn, wpa_s->own_addr, 243 conf->ieee80211w) < 0) { 244 mesh_rsn_deinit(mesh_rsn); 245 os_free(mesh_rsn); 246 return NULL; 247 } 248 249 bss->wpa_auth = mesh_rsn->auth; 250 251 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL 252 while ((entry = dl_list_last(&wpa_s->mesh_external_pmksa_cache, 253 struct external_pmksa_cache, 254 list)) != NULL) { 255 int ret; 256 257 ret = wpa_auth_pmksa_add_entry(bss->wpa_auth, 258 entry->pmksa_cache); 259 dl_list_del(&entry->list); 260 os_free(entry); 261 262 if (ret < 0) 263 return NULL; 264 } 265 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 266 267 ie = wpa_auth_get_wpa_ie(mesh_rsn->auth, &ie_len); 268 conf->rsn_ie = (u8 *) ie; 269 conf->rsn_ie_len = ie_len; 270 271 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); 272 273 return mesh_rsn; 274 } 275 276 277 static int index_within_array(const int *array, int idx) 278 { 279 int i; 280 281 for (i = 0; i < idx; i++) { 282 if (array[i] == -1) 283 return 0; 284 } 285 286 return 1; 287 } 288 289 290 static int mesh_rsn_sae_group(struct wpa_supplicant *wpa_s, 291 struct sae_data *sae) 292 { 293 int *groups = wpa_s->ifmsh->bss[0]->conf->sae_groups; 294 295 /* Configuration may have changed, so validate current index */ 296 if (!index_within_array(groups, wpa_s->mesh_rsn->sae_group_index)) 297 return -1; 298 299 for (;;) { 300 int group = groups[wpa_s->mesh_rsn->sae_group_index]; 301 302 if (group <= 0) 303 break; 304 if (sae_set_group(sae, group) == 0) { 305 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d", 306 sae->group); 307 return 0; 308 } 309 wpa_s->mesh_rsn->sae_group_index++; 310 } 311 312 return -1; 313 } 314 315 316 static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s, 317 struct wpa_ssid *ssid, 318 struct sta_info *sta) 319 { 320 const char *password; 321 322 password = ssid->sae_password; 323 if (!password) 324 password = ssid->passphrase; 325 if (!password) { 326 wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available"); 327 return -1; 328 } 329 330 if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) { 331 wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group"); 332 return -1; 333 } 334 335 return sae_prepare_commit(wpa_s->own_addr, sta->addr, 336 (u8 *) password, os_strlen(password), 337 sta->sae); 338 } 339 340 341 /* initiate new SAE authentication with sta */ 342 int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s, 343 struct sta_info *sta) 344 { 345 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; 346 struct wpa_ssid *ssid = wpa_s->current_ssid; 347 struct rsn_pmksa_cache_entry *pmksa; 348 unsigned int rnd; 349 int ret; 350 351 if (!ssid) { 352 wpa_msg(wpa_s, MSG_DEBUG, 353 "AUTH: No current_ssid known to initiate new SAE"); 354 return -1; 355 } 356 357 if (!sta->sae) { 358 sta->sae = os_zalloc(sizeof(*sta->sae)); 359 if (sta->sae == NULL) 360 return -1; 361 } 362 363 pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr, NULL); 364 if (pmksa) { 365 if (!sta->wpa_sm) 366 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 367 sta->addr, NULL); 368 if (!sta->wpa_sm) { 369 wpa_printf(MSG_ERROR, 370 "mesh: Failed to initialize RSN state machine"); 371 return -1; 372 } 373 374 wpa_printf(MSG_DEBUG, 375 "AUTH: Mesh PMKSA cache entry found for " MACSTR 376 " - try to use PMKSA caching instead of new SAE authentication", 377 MAC2STR(sta->addr)); 378 wpa_auth_pmksa_set_to_sm(pmksa, sta->wpa_sm, hapd->wpa_auth, 379 sta->sae->pmkid, sta->sae->pmk); 380 sae_accept_sta(hapd, sta); 381 sta->mesh_sae_pmksa_caching = 1; 382 return 0; 383 } 384 sta->mesh_sae_pmksa_caching = 0; 385 386 if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta)) 387 return -1; 388 389 wpa_msg(wpa_s, MSG_DEBUG, 390 "AUTH: started authentication with SAE peer: " MACSTR, 391 MAC2STR(sta->addr)); 392 393 ret = auth_sae_init_committed(hapd, sta); 394 if (ret) 395 return ret; 396 397 eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta); 398 rnd = rand() % MESH_AUTH_TIMEOUT; 399 eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer, 400 wpa_s, sta); 401 return 0; 402 } 403 404 405 void mesh_rsn_get_pmkid(struct mesh_rsn *rsn, struct sta_info *sta, u8 *pmkid) 406 { 407 os_memcpy(pmkid, sta->sae->pmkid, SAE_PMKID_LEN); 408 } 409 410 411 static void 412 mesh_rsn_derive_aek(struct mesh_rsn *rsn, struct sta_info *sta) 413 { 414 u8 *myaddr = rsn->wpa_s->own_addr; 415 u8 *peer = sta->addr; 416 u8 *addr1, *addr2; 417 u8 context[RSN_SELECTOR_LEN + 2 * ETH_ALEN], *ptr = context; 418 419 /* 420 * AEK = KDF-Hash-256(PMK, "AEK Derivation", Selected AKM Suite || 421 * min(localMAC, peerMAC) || max(localMAC, peerMAC)) 422 */ 423 /* Selected AKM Suite: SAE */ 424 RSN_SELECTOR_PUT(ptr, RSN_AUTH_KEY_MGMT_SAE); 425 ptr += RSN_SELECTOR_LEN; 426 427 if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) { 428 addr1 = myaddr; 429 addr2 = peer; 430 } else { 431 addr1 = peer; 432 addr2 = myaddr; 433 } 434 os_memcpy(ptr, addr1, ETH_ALEN); 435 ptr += ETH_ALEN; 436 os_memcpy(ptr, addr2, ETH_ALEN); 437 438 sha256_prf(sta->sae->pmk, sizeof(sta->sae->pmk), "AEK Derivation", 439 context, sizeof(context), sta->aek, sizeof(sta->aek)); 440 } 441 442 443 /* derive mesh temporal key from pmk */ 444 int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta) 445 { 446 u8 *ptr; 447 u8 *min, *max; 448 u8 *myaddr = wpa_s->own_addr; 449 u8 *peer = sta->addr; 450 u8 context[2 * WPA_NONCE_LEN + 2 * 2 + RSN_SELECTOR_LEN + 2 * ETH_ALEN]; 451 452 /* 453 * MTK = KDF-Hash-Length(PMK, "Temporal Key Derivation", min(localNonce, 454 * peerNonce) || max(localNonce, peerNonce) || min(localLinkID, 455 * peerLinkID) || max(localLinkID, peerLinkID) || Selected AKM Suite || 456 * min(localMAC, peerMAC) || max(localMAC, peerMAC)) 457 */ 458 ptr = context; 459 if (os_memcmp(sta->my_nonce, sta->peer_nonce, WPA_NONCE_LEN) < 0) { 460 min = sta->my_nonce; 461 max = sta->peer_nonce; 462 } else { 463 min = sta->peer_nonce; 464 max = sta->my_nonce; 465 } 466 os_memcpy(ptr, min, WPA_NONCE_LEN); 467 ptr += WPA_NONCE_LEN; 468 os_memcpy(ptr, max, WPA_NONCE_LEN); 469 ptr += WPA_NONCE_LEN; 470 471 if (sta->my_lid < sta->peer_lid) { 472 WPA_PUT_LE16(ptr, sta->my_lid); 473 ptr += 2; 474 WPA_PUT_LE16(ptr, sta->peer_lid); 475 ptr += 2; 476 } else { 477 WPA_PUT_LE16(ptr, sta->peer_lid); 478 ptr += 2; 479 WPA_PUT_LE16(ptr, sta->my_lid); 480 ptr += 2; 481 } 482 483 /* Selected AKM Suite: SAE */ 484 RSN_SELECTOR_PUT(ptr, RSN_AUTH_KEY_MGMT_SAE); 485 ptr += RSN_SELECTOR_LEN; 486 487 if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) { 488 min = myaddr; 489 max = peer; 490 } else { 491 min = peer; 492 max = myaddr; 493 } 494 os_memcpy(ptr, min, ETH_ALEN); 495 ptr += ETH_ALEN; 496 os_memcpy(ptr, max, ETH_ALEN); 497 498 sta->mtk_len = wpa_cipher_key_len(wpa_s->mesh_rsn->pairwise_cipher); 499 sha256_prf(sta->sae->pmk, SAE_PMK_LEN, 500 "Temporal Key Derivation", context, sizeof(context), 501 sta->mtk, sta->mtk_len); 502 return 0; 503 } 504 505 506 void mesh_rsn_init_ampe_sta(struct wpa_supplicant *wpa_s, struct sta_info *sta) 507 { 508 if (random_get_bytes(sta->my_nonce, WPA_NONCE_LEN) < 0) { 509 wpa_printf(MSG_INFO, "mesh: Failed to derive random nonce"); 510 /* TODO: How to handle this more cleanly? */ 511 } 512 os_memset(sta->peer_nonce, 0, WPA_NONCE_LEN); 513 mesh_rsn_derive_aek(wpa_s->mesh_rsn, sta); 514 } 515 516 517 /* insert AMPE and encrypted MIC at @ie. 518 * @mesh_rsn: mesh RSN context 519 * @sta: STA we're sending to 520 * @cat: pointer to category code in frame header. 521 * @buf: wpabuf to add encrypted AMPE and MIC to. 522 * */ 523 int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta, 524 const u8 *cat, struct wpabuf *buf) 525 { 526 struct ieee80211_ampe_ie *ampe; 527 u8 const *ie = wpabuf_head_u8(buf) + wpabuf_len(buf); 528 u8 *ampe_ie, *pos, *mic_payload; 529 const u8 *aad[] = { rsn->wpa_s->own_addr, sta->addr, cat }; 530 const size_t aad_len[] = { ETH_ALEN, ETH_ALEN, ie - cat }; 531 int ret = 0; 532 size_t len; 533 534 len = sizeof(*ampe); 535 if (cat[1] == PLINK_OPEN) 536 len += rsn->mgtk_len + WPA_KEY_RSC_LEN + 4; 537 #ifdef CONFIG_IEEE80211W 538 if (cat[1] == PLINK_OPEN && rsn->igtk_len) 539 len += 2 + 6 + rsn->igtk_len; 540 #endif /* CONFIG_IEEE80211W */ 541 542 if (2 + AES_BLOCK_SIZE + 2 + len > wpabuf_tailroom(buf)) { 543 wpa_printf(MSG_ERROR, "protect frame: buffer too small"); 544 return -EINVAL; 545 } 546 547 ampe_ie = os_zalloc(2 + len); 548 if (!ampe_ie) { 549 wpa_printf(MSG_ERROR, "protect frame: out of memory"); 550 return -ENOMEM; 551 } 552 553 /* IE: AMPE */ 554 ampe_ie[0] = WLAN_EID_AMPE; 555 ampe_ie[1] = len; 556 ampe = (struct ieee80211_ampe_ie *) (ampe_ie + 2); 557 558 RSN_SELECTOR_PUT(ampe->selected_pairwise_suite, 559 RSN_CIPHER_SUITE_CCMP); 560 os_memcpy(ampe->local_nonce, sta->my_nonce, WPA_NONCE_LEN); 561 os_memcpy(ampe->peer_nonce, sta->peer_nonce, WPA_NONCE_LEN); 562 563 pos = (u8 *) (ampe + 1); 564 if (cat[1] != PLINK_OPEN) 565 goto skip_keys; 566 567 /* TODO: Key Replay Counter[8] optionally for 568 * Mesh Group Key Inform/Acknowledge frames */ 569 570 /* TODO: static mgtk for now since we don't support rekeying! */ 571 /* 572 * GTKdata[variable]: 573 * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4] 574 */ 575 os_memcpy(pos, rsn->mgtk, rsn->mgtk_len); 576 pos += rsn->mgtk_len; 577 wpa_drv_get_seqnum(rsn->wpa_s, NULL, rsn->mgtk_key_id, pos); 578 pos += WPA_KEY_RSC_LEN; 579 /* Use fixed GTKExpirationTime for now */ 580 WPA_PUT_LE32(pos, 0xffffffff); 581 pos += 4; 582 583 #ifdef CONFIG_IEEE80211W 584 /* 585 * IGTKdata[variable]: 586 * Key ID[2], IPN[6], IGTK[variable] 587 */ 588 if (rsn->igtk_len) { 589 WPA_PUT_LE16(pos, rsn->igtk_key_id); 590 pos += 2; 591 wpa_drv_get_seqnum(rsn->wpa_s, NULL, rsn->igtk_key_id, pos); 592 pos += 6; 593 os_memcpy(pos, rsn->igtk, rsn->igtk_len); 594 } 595 #endif /* CONFIG_IEEE80211W */ 596 597 skip_keys: 598 wpa_hexdump_key(MSG_DEBUG, "mesh: Plaintext AMPE element", 599 ampe_ie, 2 + len); 600 601 /* IE: MIC */ 602 wpabuf_put_u8(buf, WLAN_EID_MIC); 603 wpabuf_put_u8(buf, AES_BLOCK_SIZE); 604 /* MIC field is output ciphertext */ 605 606 /* encrypt after MIC */ 607 mic_payload = wpabuf_put(buf, 2 + len + AES_BLOCK_SIZE); 608 609 if (aes_siv_encrypt(sta->aek, sizeof(sta->aek), ampe_ie, 2 + len, 3, 610 aad, aad_len, mic_payload)) { 611 wpa_printf(MSG_ERROR, "protect frame: failed to encrypt"); 612 ret = -ENOMEM; 613 } 614 615 os_free(ampe_ie); 616 617 return ret; 618 } 619 620 621 int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta, 622 struct ieee802_11_elems *elems, const u8 *cat, 623 const u8 *chosen_pmk, 624 const u8 *start, size_t elems_len) 625 { 626 int ret = 0; 627 struct ieee80211_ampe_ie *ampe; 628 u8 null_nonce[WPA_NONCE_LEN] = {}; 629 u8 ampe_eid; 630 u8 ampe_ie_len; 631 u8 *ampe_buf, *crypt = NULL, *pos, *end; 632 size_t crypt_len; 633 const u8 *aad[] = { sta->addr, wpa_s->own_addr, cat }; 634 const size_t aad_len[] = { ETH_ALEN, ETH_ALEN, 635 (elems->mic - 2) - cat }; 636 size_t key_len; 637 638 if (!sta->sae) { 639 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; 640 641 if (!wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr, NULL)) { 642 wpa_printf(MSG_INFO, 643 "Mesh RSN: SAE is not prepared yet"); 644 return -1; 645 } 646 mesh_rsn_auth_sae_sta(wpa_s, sta); 647 } 648 649 if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) { 650 wpa_msg(wpa_s, MSG_DEBUG, 651 "Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)"); 652 return -1; 653 } 654 655 if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) { 656 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie"); 657 return -1; 658 } 659 660 ampe_buf = (u8 *) elems->mic + elems->mic_len; 661 if ((int) elems_len < ampe_buf - start) 662 return -1; 663 664 crypt_len = elems_len - (elems->mic - start); 665 if (crypt_len < 2 + AES_BLOCK_SIZE) { 666 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing ampe ie"); 667 return -1; 668 } 669 670 /* crypt is modified by siv_decrypt */ 671 crypt = os_zalloc(crypt_len); 672 if (!crypt) { 673 wpa_printf(MSG_ERROR, "Mesh RSN: out of memory"); 674 ret = -ENOMEM; 675 goto free; 676 } 677 678 os_memcpy(crypt, elems->mic, crypt_len); 679 680 if (aes_siv_decrypt(sta->aek, sizeof(sta->aek), crypt, crypt_len, 3, 681 aad, aad_len, ampe_buf)) { 682 wpa_printf(MSG_ERROR, "Mesh RSN: frame verification failed!"); 683 ret = -2; 684 goto free; 685 } 686 687 crypt_len -= AES_BLOCK_SIZE; 688 wpa_hexdump_key(MSG_DEBUG, "mesh: Decrypted AMPE element", 689 ampe_buf, crypt_len); 690 691 ampe_eid = *ampe_buf++; 692 ampe_ie_len = *ampe_buf++; 693 694 if (ampe_eid != WLAN_EID_AMPE || 695 (size_t) 2 + ampe_ie_len > crypt_len || 696 ampe_ie_len < sizeof(struct ieee80211_ampe_ie)) { 697 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid ampe ie"); 698 ret = -1; 699 goto free; 700 } 701 702 ampe = (struct ieee80211_ampe_ie *) ampe_buf; 703 pos = (u8 *) (ampe + 1); 704 end = ampe_buf + ampe_ie_len; 705 if (os_memcmp(ampe->peer_nonce, null_nonce, WPA_NONCE_LEN) != 0 && 706 os_memcmp(ampe->peer_nonce, sta->my_nonce, WPA_NONCE_LEN) != 0) { 707 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid peer nonce"); 708 ret = -1; 709 goto free; 710 } 711 os_memcpy(sta->peer_nonce, ampe->local_nonce, 712 sizeof(ampe->local_nonce)); 713 714 /* TODO: Key Replay Counter[8] in Mesh Group Key Inform/Acknowledge 715 * frames */ 716 717 /* 718 * GTKdata shall not be included in Mesh Peering Confirm. While the 719 * standard does not state the same about IGTKdata, that same constraint 720 * needs to apply for it. It makes no sense to include the keys in Mesh 721 * Peering Close frames either, so while the standard does not seem to 722 * have a shall statement for these, they are described without 723 * mentioning GTKdata. 724 * 725 * An earlier implementation used to add GTKdata to both Mesh Peering 726 * Open and Mesh Peering Confirm frames, so ignore the possibly present 727 * GTKdata frame without rejecting the frame as a backwards 728 * compatibility mechanism. 729 */ 730 if (cat[1] != PLINK_OPEN) { 731 if (end > pos) { 732 wpa_hexdump_key(MSG_DEBUG, 733 "mesh: Ignore unexpected GTKdata(etc.) fields in the end of AMPE element in Mesh Peering Confirm/Close", 734 pos, end - pos); 735 } 736 goto free; 737 } 738 739 /* 740 * GTKdata[variable]: 741 * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4] 742 */ 743 sta->mgtk_key_id = 1; /* FIX: Where to get Key ID? */ 744 key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->group_cipher); 745 if ((int) key_len + WPA_KEY_RSC_LEN + 4 > end - pos) { 746 wpa_dbg(wpa_s, MSG_DEBUG, "mesh: Truncated AMPE element"); 747 ret = -1; 748 goto free; 749 } 750 sta->mgtk_len = key_len; 751 os_memcpy(sta->mgtk, pos, sta->mgtk_len); 752 wpa_hexdump_key(MSG_DEBUG, "mesh: GTKdata - MGTK", 753 sta->mgtk, sta->mgtk_len); 754 pos += sta->mgtk_len; 755 wpa_hexdump(MSG_DEBUG, "mesh: GTKdata - MGTK - Key RSC", 756 pos, WPA_KEY_RSC_LEN); 757 os_memcpy(sta->mgtk_rsc, pos, sizeof(sta->mgtk_rsc)); 758 pos += WPA_KEY_RSC_LEN; 759 wpa_printf(MSG_DEBUG, 760 "mesh: GTKdata - MGTK - GTKExpirationTime: %u seconds", 761 WPA_GET_LE32(pos)); 762 pos += 4; 763 764 #ifdef CONFIG_IEEE80211W 765 /* 766 * IGTKdata[variable]: 767 * Key ID[2], IPN[6], IGTK[variable] 768 */ 769 key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->mgmt_group_cipher); 770 if (end - pos >= (int) (2 + 6 + key_len)) { 771 sta->igtk_key_id = WPA_GET_LE16(pos); 772 wpa_printf(MSG_DEBUG, "mesh: IGTKdata - Key ID %u", 773 sta->igtk_key_id); 774 pos += 2; 775 os_memcpy(sta->igtk_rsc, pos, sizeof(sta->igtk_rsc)); 776 wpa_hexdump(MSG_DEBUG, "mesh: IGTKdata - IPN", 777 sta->igtk_rsc, sizeof(sta->igtk_rsc)); 778 pos += 6; 779 os_memcpy(sta->igtk, pos, key_len); 780 sta->igtk_len = key_len; 781 wpa_hexdump_key(MSG_DEBUG, "mesh: IGTKdata - IGTK", 782 sta->igtk, sta->igtk_len); 783 } 784 #endif /* CONFIG_IEEE80211W */ 785 786 free: 787 os_free(crypt); 788 return ret; 789 } 790