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 if (sta->sae->tmp && !sta->sae->tmp->pw_id && ssid->sae_password_id) { 336 sta->sae->tmp->pw_id = os_strdup(ssid->sae_password_id); 337 if (!sta->sae->tmp->pw_id) 338 return -1; 339 } 340 return sae_prepare_commit(wpa_s->own_addr, sta->addr, 341 (u8 *) password, os_strlen(password), 342 ssid->sae_password_id, 343 sta->sae); 344 } 345 346 347 /* initiate new SAE authentication with sta */ 348 int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s, 349 struct sta_info *sta) 350 { 351 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; 352 struct wpa_ssid *ssid = wpa_s->current_ssid; 353 struct rsn_pmksa_cache_entry *pmksa; 354 unsigned int rnd; 355 int ret; 356 357 if (!ssid) { 358 wpa_msg(wpa_s, MSG_DEBUG, 359 "AUTH: No current_ssid known to initiate new SAE"); 360 return -1; 361 } 362 363 if (!sta->sae) { 364 sta->sae = os_zalloc(sizeof(*sta->sae)); 365 if (sta->sae == NULL) 366 return -1; 367 } 368 369 pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr, NULL); 370 if (pmksa) { 371 if (!sta->wpa_sm) 372 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 373 sta->addr, NULL); 374 if (!sta->wpa_sm) { 375 wpa_printf(MSG_ERROR, 376 "mesh: Failed to initialize RSN state machine"); 377 return -1; 378 } 379 380 wpa_printf(MSG_DEBUG, 381 "AUTH: Mesh PMKSA cache entry found for " MACSTR 382 " - try to use PMKSA caching instead of new SAE authentication", 383 MAC2STR(sta->addr)); 384 wpa_auth_pmksa_set_to_sm(pmksa, sta->wpa_sm, hapd->wpa_auth, 385 sta->sae->pmkid, sta->sae->pmk); 386 sae_accept_sta(hapd, sta); 387 sta->mesh_sae_pmksa_caching = 1; 388 return 0; 389 } 390 sta->mesh_sae_pmksa_caching = 0; 391 392 if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta)) 393 return -1; 394 395 wpa_msg(wpa_s, MSG_DEBUG, 396 "AUTH: started authentication with SAE peer: " MACSTR, 397 MAC2STR(sta->addr)); 398 399 ret = auth_sae_init_committed(hapd, sta); 400 if (ret) 401 return ret; 402 403 eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta); 404 rnd = rand() % MESH_AUTH_TIMEOUT; 405 eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer, 406 wpa_s, sta); 407 return 0; 408 } 409 410 411 void mesh_rsn_get_pmkid(struct mesh_rsn *rsn, struct sta_info *sta, u8 *pmkid) 412 { 413 os_memcpy(pmkid, sta->sae->pmkid, SAE_PMKID_LEN); 414 } 415 416 417 static void 418 mesh_rsn_derive_aek(struct mesh_rsn *rsn, struct sta_info *sta) 419 { 420 u8 *myaddr = rsn->wpa_s->own_addr; 421 u8 *peer = sta->addr; 422 u8 *addr1, *addr2; 423 u8 context[RSN_SELECTOR_LEN + 2 * ETH_ALEN], *ptr = context; 424 425 /* 426 * AEK = KDF-Hash-256(PMK, "AEK Derivation", Selected AKM Suite || 427 * min(localMAC, peerMAC) || max(localMAC, peerMAC)) 428 */ 429 /* Selected AKM Suite: SAE */ 430 RSN_SELECTOR_PUT(ptr, RSN_AUTH_KEY_MGMT_SAE); 431 ptr += RSN_SELECTOR_LEN; 432 433 if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) { 434 addr1 = myaddr; 435 addr2 = peer; 436 } else { 437 addr1 = peer; 438 addr2 = myaddr; 439 } 440 os_memcpy(ptr, addr1, ETH_ALEN); 441 ptr += ETH_ALEN; 442 os_memcpy(ptr, addr2, ETH_ALEN); 443 444 sha256_prf(sta->sae->pmk, sizeof(sta->sae->pmk), "AEK Derivation", 445 context, sizeof(context), sta->aek, sizeof(sta->aek)); 446 } 447 448 449 /* derive mesh temporal key from pmk */ 450 int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta) 451 { 452 u8 *ptr; 453 u8 *min, *max; 454 u8 *myaddr = wpa_s->own_addr; 455 u8 *peer = sta->addr; 456 u8 context[2 * WPA_NONCE_LEN + 2 * 2 + RSN_SELECTOR_LEN + 2 * ETH_ALEN]; 457 458 /* 459 * MTK = KDF-Hash-Length(PMK, "Temporal Key Derivation", min(localNonce, 460 * peerNonce) || max(localNonce, peerNonce) || min(localLinkID, 461 * peerLinkID) || max(localLinkID, peerLinkID) || Selected AKM Suite || 462 * min(localMAC, peerMAC) || max(localMAC, peerMAC)) 463 */ 464 ptr = context; 465 if (os_memcmp(sta->my_nonce, sta->peer_nonce, WPA_NONCE_LEN) < 0) { 466 min = sta->my_nonce; 467 max = sta->peer_nonce; 468 } else { 469 min = sta->peer_nonce; 470 max = sta->my_nonce; 471 } 472 os_memcpy(ptr, min, WPA_NONCE_LEN); 473 ptr += WPA_NONCE_LEN; 474 os_memcpy(ptr, max, WPA_NONCE_LEN); 475 ptr += WPA_NONCE_LEN; 476 477 if (sta->my_lid < sta->peer_lid) { 478 WPA_PUT_LE16(ptr, sta->my_lid); 479 ptr += 2; 480 WPA_PUT_LE16(ptr, sta->peer_lid); 481 ptr += 2; 482 } else { 483 WPA_PUT_LE16(ptr, sta->peer_lid); 484 ptr += 2; 485 WPA_PUT_LE16(ptr, sta->my_lid); 486 ptr += 2; 487 } 488 489 /* Selected AKM Suite: SAE */ 490 RSN_SELECTOR_PUT(ptr, RSN_AUTH_KEY_MGMT_SAE); 491 ptr += RSN_SELECTOR_LEN; 492 493 if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) { 494 min = myaddr; 495 max = peer; 496 } else { 497 min = peer; 498 max = myaddr; 499 } 500 os_memcpy(ptr, min, ETH_ALEN); 501 ptr += ETH_ALEN; 502 os_memcpy(ptr, max, ETH_ALEN); 503 504 sta->mtk_len = wpa_cipher_key_len(wpa_s->mesh_rsn->pairwise_cipher); 505 sha256_prf(sta->sae->pmk, SAE_PMK_LEN, 506 "Temporal Key Derivation", context, sizeof(context), 507 sta->mtk, sta->mtk_len); 508 return 0; 509 } 510 511 512 void mesh_rsn_init_ampe_sta(struct wpa_supplicant *wpa_s, struct sta_info *sta) 513 { 514 if (random_get_bytes(sta->my_nonce, WPA_NONCE_LEN) < 0) { 515 wpa_printf(MSG_INFO, "mesh: Failed to derive random nonce"); 516 /* TODO: How to handle this more cleanly? */ 517 } 518 os_memset(sta->peer_nonce, 0, WPA_NONCE_LEN); 519 mesh_rsn_derive_aek(wpa_s->mesh_rsn, sta); 520 } 521 522 523 /* insert AMPE and encrypted MIC at @ie. 524 * @mesh_rsn: mesh RSN context 525 * @sta: STA we're sending to 526 * @cat: pointer to category code in frame header. 527 * @buf: wpabuf to add encrypted AMPE and MIC to. 528 * */ 529 int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta, 530 const u8 *cat, struct wpabuf *buf) 531 { 532 struct ieee80211_ampe_ie *ampe; 533 u8 const *ie = wpabuf_head_u8(buf) + wpabuf_len(buf); 534 u8 *ampe_ie, *pos, *mic_payload; 535 const u8 *aad[] = { rsn->wpa_s->own_addr, sta->addr, cat }; 536 const size_t aad_len[] = { ETH_ALEN, ETH_ALEN, ie - cat }; 537 int ret = 0; 538 size_t len; 539 540 len = sizeof(*ampe); 541 if (cat[1] == PLINK_OPEN) 542 len += rsn->mgtk_len + WPA_KEY_RSC_LEN + 4; 543 #ifdef CONFIG_IEEE80211W 544 if (cat[1] == PLINK_OPEN && rsn->igtk_len) 545 len += 2 + 6 + rsn->igtk_len; 546 #endif /* CONFIG_IEEE80211W */ 547 548 if (2 + AES_BLOCK_SIZE + 2 + len > wpabuf_tailroom(buf)) { 549 wpa_printf(MSG_ERROR, "protect frame: buffer too small"); 550 return -EINVAL; 551 } 552 553 ampe_ie = os_zalloc(2 + len); 554 if (!ampe_ie) { 555 wpa_printf(MSG_ERROR, "protect frame: out of memory"); 556 return -ENOMEM; 557 } 558 559 /* IE: AMPE */ 560 ampe_ie[0] = WLAN_EID_AMPE; 561 ampe_ie[1] = len; 562 ampe = (struct ieee80211_ampe_ie *) (ampe_ie + 2); 563 564 RSN_SELECTOR_PUT(ampe->selected_pairwise_suite, 565 RSN_CIPHER_SUITE_CCMP); 566 os_memcpy(ampe->local_nonce, sta->my_nonce, WPA_NONCE_LEN); 567 os_memcpy(ampe->peer_nonce, sta->peer_nonce, WPA_NONCE_LEN); 568 569 pos = (u8 *) (ampe + 1); 570 if (cat[1] != PLINK_OPEN) 571 goto skip_keys; 572 573 /* TODO: Key Replay Counter[8] optionally for 574 * Mesh Group Key Inform/Acknowledge frames */ 575 576 /* TODO: static mgtk for now since we don't support rekeying! */ 577 /* 578 * GTKdata[variable]: 579 * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4] 580 */ 581 os_memcpy(pos, rsn->mgtk, rsn->mgtk_len); 582 pos += rsn->mgtk_len; 583 wpa_drv_get_seqnum(rsn->wpa_s, NULL, rsn->mgtk_key_id, pos); 584 pos += WPA_KEY_RSC_LEN; 585 /* Use fixed GTKExpirationTime for now */ 586 WPA_PUT_LE32(pos, 0xffffffff); 587 pos += 4; 588 589 #ifdef CONFIG_IEEE80211W 590 /* 591 * IGTKdata[variable]: 592 * Key ID[2], IPN[6], IGTK[variable] 593 */ 594 if (rsn->igtk_len) { 595 WPA_PUT_LE16(pos, rsn->igtk_key_id); 596 pos += 2; 597 wpa_drv_get_seqnum(rsn->wpa_s, NULL, rsn->igtk_key_id, pos); 598 pos += 6; 599 os_memcpy(pos, rsn->igtk, rsn->igtk_len); 600 } 601 #endif /* CONFIG_IEEE80211W */ 602 603 skip_keys: 604 wpa_hexdump_key(MSG_DEBUG, "mesh: Plaintext AMPE element", 605 ampe_ie, 2 + len); 606 607 /* IE: MIC */ 608 wpabuf_put_u8(buf, WLAN_EID_MIC); 609 wpabuf_put_u8(buf, AES_BLOCK_SIZE); 610 /* MIC field is output ciphertext */ 611 612 /* encrypt after MIC */ 613 mic_payload = wpabuf_put(buf, 2 + len + AES_BLOCK_SIZE); 614 615 if (aes_siv_encrypt(sta->aek, sizeof(sta->aek), ampe_ie, 2 + len, 3, 616 aad, aad_len, mic_payload)) { 617 wpa_printf(MSG_ERROR, "protect frame: failed to encrypt"); 618 ret = -ENOMEM; 619 } 620 621 os_free(ampe_ie); 622 623 return ret; 624 } 625 626 627 int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta, 628 struct ieee802_11_elems *elems, const u8 *cat, 629 const u8 *chosen_pmk, 630 const u8 *start, size_t elems_len) 631 { 632 int ret = 0; 633 struct ieee80211_ampe_ie *ampe; 634 u8 null_nonce[WPA_NONCE_LEN] = {}; 635 u8 ampe_eid; 636 u8 ampe_ie_len; 637 u8 *ampe_buf, *crypt = NULL, *pos, *end; 638 size_t crypt_len; 639 const u8 *aad[] = { sta->addr, wpa_s->own_addr, cat }; 640 const size_t aad_len[] = { ETH_ALEN, ETH_ALEN, 641 (elems->mic - 2) - cat }; 642 size_t key_len; 643 644 if (!sta->sae) { 645 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; 646 647 if (!wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr, NULL)) { 648 wpa_printf(MSG_INFO, 649 "Mesh RSN: SAE is not prepared yet"); 650 return -1; 651 } 652 mesh_rsn_auth_sae_sta(wpa_s, sta); 653 } 654 655 if (chosen_pmk && os_memcmp(chosen_pmk, sta->sae->pmkid, PMKID_LEN)) { 656 wpa_msg(wpa_s, MSG_DEBUG, 657 "Mesh RSN: Invalid PMKID (Chosen PMK did not match calculated PMKID)"); 658 return -1; 659 } 660 661 if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) { 662 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie"); 663 return -1; 664 } 665 666 ampe_buf = (u8 *) elems->mic + elems->mic_len; 667 if ((int) elems_len < ampe_buf - start) 668 return -1; 669 670 crypt_len = elems_len - (elems->mic - start); 671 if (crypt_len < 2 + AES_BLOCK_SIZE) { 672 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing ampe ie"); 673 return -1; 674 } 675 676 /* crypt is modified by siv_decrypt */ 677 crypt = os_zalloc(crypt_len); 678 if (!crypt) { 679 wpa_printf(MSG_ERROR, "Mesh RSN: out of memory"); 680 ret = -ENOMEM; 681 goto free; 682 } 683 684 os_memcpy(crypt, elems->mic, crypt_len); 685 686 if (aes_siv_decrypt(sta->aek, sizeof(sta->aek), crypt, crypt_len, 3, 687 aad, aad_len, ampe_buf)) { 688 wpa_printf(MSG_ERROR, "Mesh RSN: frame verification failed!"); 689 ret = -2; 690 goto free; 691 } 692 693 crypt_len -= AES_BLOCK_SIZE; 694 wpa_hexdump_key(MSG_DEBUG, "mesh: Decrypted AMPE element", 695 ampe_buf, crypt_len); 696 697 ampe_eid = *ampe_buf++; 698 ampe_ie_len = *ampe_buf++; 699 700 if (ampe_eid != WLAN_EID_AMPE || 701 (size_t) 2 + ampe_ie_len > crypt_len || 702 ampe_ie_len < sizeof(struct ieee80211_ampe_ie)) { 703 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid ampe ie"); 704 ret = -1; 705 goto free; 706 } 707 708 ampe = (struct ieee80211_ampe_ie *) ampe_buf; 709 pos = (u8 *) (ampe + 1); 710 end = ampe_buf + ampe_ie_len; 711 if (os_memcmp(ampe->peer_nonce, null_nonce, WPA_NONCE_LEN) != 0 && 712 os_memcmp(ampe->peer_nonce, sta->my_nonce, WPA_NONCE_LEN) != 0) { 713 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid peer nonce"); 714 ret = -1; 715 goto free; 716 } 717 os_memcpy(sta->peer_nonce, ampe->local_nonce, 718 sizeof(ampe->local_nonce)); 719 720 /* TODO: Key Replay Counter[8] in Mesh Group Key Inform/Acknowledge 721 * frames */ 722 723 /* 724 * GTKdata shall not be included in Mesh Peering Confirm. While the 725 * standard does not state the same about IGTKdata, that same constraint 726 * needs to apply for it. It makes no sense to include the keys in Mesh 727 * Peering Close frames either, so while the standard does not seem to 728 * have a shall statement for these, they are described without 729 * mentioning GTKdata. 730 * 731 * An earlier implementation used to add GTKdata to both Mesh Peering 732 * Open and Mesh Peering Confirm frames, so ignore the possibly present 733 * GTKdata frame without rejecting the frame as a backwards 734 * compatibility mechanism. 735 */ 736 if (cat[1] != PLINK_OPEN) { 737 if (end > pos) { 738 wpa_hexdump_key(MSG_DEBUG, 739 "mesh: Ignore unexpected GTKdata(etc.) fields in the end of AMPE element in Mesh Peering Confirm/Close", 740 pos, end - pos); 741 } 742 goto free; 743 } 744 745 /* 746 * GTKdata[variable]: 747 * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4] 748 */ 749 sta->mgtk_key_id = 1; /* FIX: Where to get Key ID? */ 750 key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->group_cipher); 751 if ((int) key_len + WPA_KEY_RSC_LEN + 4 > end - pos) { 752 wpa_dbg(wpa_s, MSG_DEBUG, "mesh: Truncated AMPE element"); 753 ret = -1; 754 goto free; 755 } 756 sta->mgtk_len = key_len; 757 os_memcpy(sta->mgtk, pos, sta->mgtk_len); 758 wpa_hexdump_key(MSG_DEBUG, "mesh: GTKdata - MGTK", 759 sta->mgtk, sta->mgtk_len); 760 pos += sta->mgtk_len; 761 wpa_hexdump(MSG_DEBUG, "mesh: GTKdata - MGTK - Key RSC", 762 pos, WPA_KEY_RSC_LEN); 763 os_memcpy(sta->mgtk_rsc, pos, sizeof(sta->mgtk_rsc)); 764 pos += WPA_KEY_RSC_LEN; 765 wpa_printf(MSG_DEBUG, 766 "mesh: GTKdata - MGTK - GTKExpirationTime: %u seconds", 767 WPA_GET_LE32(pos)); 768 pos += 4; 769 770 #ifdef CONFIG_IEEE80211W 771 /* 772 * IGTKdata[variable]: 773 * Key ID[2], IPN[6], IGTK[variable] 774 */ 775 key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->mgmt_group_cipher); 776 if (end - pos >= (int) (2 + 6 + key_len)) { 777 sta->igtk_key_id = WPA_GET_LE16(pos); 778 wpa_printf(MSG_DEBUG, "mesh: IGTKdata - Key ID %u", 779 sta->igtk_key_id); 780 pos += 2; 781 os_memcpy(sta->igtk_rsc, pos, sizeof(sta->igtk_rsc)); 782 wpa_hexdump(MSG_DEBUG, "mesh: IGTKdata - IPN", 783 sta->igtk_rsc, sizeof(sta->igtk_rsc)); 784 pos += 6; 785 os_memcpy(sta->igtk, pos, key_len); 786 sta->igtk_len = key_len; 787 wpa_hexdump_key(MSG_DEBUG, "mesh: IGTKdata - IGTK", 788 sta->igtk, sta->igtk_len); 789 } 790 #endif /* CONFIG_IEEE80211W */ 791 792 free: 793 os_free(crypt); 794 return ret; 795 } 796