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 #define MESH_AUTH_BLOCK_DURATION 3600 31 32 void mesh_auth_timer(void *eloop_ctx, void *user_data) 33 { 34 struct wpa_supplicant *wpa_s = eloop_ctx; 35 struct sta_info *sta = user_data; 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 if (sta->sae_auth_retry > MESH_AUTH_RETRY) { 47 ap_free_sta(wpa_s->ifmsh->bss[0], sta); 48 return; 49 } 50 51 /* block the STA if exceeded the number of attempts */ 52 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_BLOCKED); 53 sta->sae->state = SAE_NOTHING; 54 if (wpa_s->mesh_auth_block_duration < 55 MESH_AUTH_BLOCK_DURATION) 56 wpa_s->mesh_auth_block_duration += 60; 57 eloop_register_timeout(wpa_s->mesh_auth_block_duration, 58 0, mesh_auth_timer, wpa_s, sta); 59 wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_BLOCKED "addr=" 60 MACSTR " duration=%d", 61 MAC2STR(sta->addr), 62 wpa_s->mesh_auth_block_duration); 63 } 64 sta->sae_auth_retry++; 65 } 66 } 67 68 69 static void auth_logger(void *ctx, const u8 *addr, logger_level level, 70 const char *txt) 71 { 72 if (addr) 73 wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s", 74 MAC2STR(addr), txt); 75 else 76 wpa_printf(MSG_DEBUG, "AUTH: %s", txt); 77 } 78 79 80 static const u8 *auth_get_psk(void *ctx, const u8 *addr, 81 const u8 *p2p_dev_addr, const u8 *prev_psk) 82 { 83 struct mesh_rsn *mesh_rsn = ctx; 84 struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0]; 85 struct sta_info *sta = ap_get_sta(hapd, addr); 86 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 { 144 struct wpa_auth_config conf; 145 struct wpa_auth_callbacks cb; 146 u8 seq[6] = {}; 147 148 wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine"); 149 150 os_memset(&conf, 0, sizeof(conf)); 151 conf.wpa = 2; 152 conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE; 153 conf.wpa_pairwise = WPA_CIPHER_CCMP; 154 conf.rsn_pairwise = WPA_CIPHER_CCMP; 155 conf.wpa_group = WPA_CIPHER_CCMP; 156 conf.eapol_version = 0; 157 conf.wpa_group_rekey = -1; 158 159 os_memset(&cb, 0, sizeof(cb)); 160 cb.ctx = rsn; 161 cb.logger = auth_logger; 162 cb.get_psk = auth_get_psk; 163 cb.set_key = auth_set_key; 164 cb.start_ampe = auth_start_ampe; 165 166 rsn->auth = wpa_init(addr, &conf, &cb); 167 if (rsn->auth == NULL) { 168 wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed"); 169 return -1; 170 } 171 172 /* TODO: support rekeying */ 173 if (random_get_bytes(rsn->mgtk, 16) < 0) { 174 wpa_deinit(rsn->auth); 175 return -1; 176 } 177 178 /* group mgmt */ 179 wpa_drv_set_key(rsn->wpa_s, WPA_ALG_IGTK, NULL, 4, 1, 180 seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk)); 181 182 /* group privacy / data frames */ 183 wpa_drv_set_key(rsn->wpa_s, WPA_ALG_CCMP, NULL, 1, 1, 184 seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk)); 185 186 return 0; 187 } 188 189 190 static void mesh_rsn_deinit(struct mesh_rsn *rsn) 191 { 192 os_memset(rsn->mgtk, 0, sizeof(rsn->mgtk)); 193 if (rsn->auth) 194 wpa_deinit(rsn->auth); 195 } 196 197 198 struct mesh_rsn *mesh_rsn_auth_init(struct wpa_supplicant *wpa_s, 199 struct mesh_conf *conf) 200 { 201 struct mesh_rsn *mesh_rsn; 202 struct hostapd_data *bss = wpa_s->ifmsh->bss[0]; 203 const u8 *ie; 204 size_t ie_len; 205 206 mesh_rsn = os_zalloc(sizeof(*mesh_rsn)); 207 if (mesh_rsn == NULL) 208 return NULL; 209 mesh_rsn->wpa_s = wpa_s; 210 211 if (__mesh_rsn_auth_init(mesh_rsn, wpa_s->own_addr) < 0) { 212 mesh_rsn_deinit(mesh_rsn); 213 os_free(mesh_rsn); 214 return NULL; 215 } 216 217 bss->wpa_auth = mesh_rsn->auth; 218 219 ie = wpa_auth_get_wpa_ie(mesh_rsn->auth, &ie_len); 220 conf->rsn_ie = (u8 *) ie; 221 conf->rsn_ie_len = ie_len; 222 223 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); 224 225 return mesh_rsn; 226 } 227 228 229 static int index_within_array(const int *array, int idx) 230 { 231 int i; 232 233 for (i = 0; i < idx; i++) { 234 if (array[i] == -1) 235 return 0; 236 } 237 238 return 1; 239 } 240 241 242 static int mesh_rsn_sae_group(struct wpa_supplicant *wpa_s, 243 struct sae_data *sae) 244 { 245 int *groups = wpa_s->ifmsh->bss[0]->conf->sae_groups; 246 247 /* Configuration may have changed, so validate current index */ 248 if (!index_within_array(groups, wpa_s->mesh_rsn->sae_group_index)) 249 return -1; 250 251 for (;;) { 252 int group = groups[wpa_s->mesh_rsn->sae_group_index]; 253 254 if (group <= 0) 255 break; 256 if (sae_set_group(sae, group) == 0) { 257 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d", 258 sae->group); 259 return 0; 260 } 261 wpa_s->mesh_rsn->sae_group_index++; 262 } 263 264 return -1; 265 } 266 267 268 static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s, 269 struct wpa_ssid *ssid, 270 struct sta_info *sta) 271 { 272 if (ssid->passphrase == NULL) { 273 wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available"); 274 return -1; 275 } 276 277 if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) { 278 wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group"); 279 return -1; 280 } 281 282 return sae_prepare_commit(wpa_s->own_addr, sta->addr, 283 (u8 *) ssid->passphrase, 284 os_strlen(ssid->passphrase), sta->sae); 285 } 286 287 288 /* initiate new SAE authentication with sta */ 289 int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s, 290 struct sta_info *sta) 291 { 292 struct hostapd_data *hapd = wpa_s->ifmsh->bss[0]; 293 struct wpa_ssid *ssid = wpa_s->current_ssid; 294 unsigned int rnd; 295 int ret; 296 297 if (!ssid) { 298 wpa_msg(wpa_s, MSG_DEBUG, 299 "AUTH: No current_ssid known to initiate new SAE"); 300 return -1; 301 } 302 303 if (!sta->sae) { 304 sta->sae = os_zalloc(sizeof(*sta->sae)); 305 if (sta->sae == NULL) 306 return -1; 307 } 308 309 if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta)) 310 return -1; 311 312 wpa_msg(wpa_s, MSG_DEBUG, 313 "AUTH: started authentication with SAE peer: " MACSTR, 314 MAC2STR(sta->addr)); 315 316 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 317 ret = auth_sae_init_committed(hapd, sta); 318 if (ret) 319 return ret; 320 321 eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta); 322 rnd = rand() % MESH_AUTH_TIMEOUT; 323 eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer, 324 wpa_s, sta); 325 return 0; 326 } 327 328 329 void mesh_rsn_get_pmkid(struct mesh_rsn *rsn, struct sta_info *sta, u8 *pmkid) 330 { 331 /* don't expect wpa auth to cache the pmkid for now */ 332 rsn_pmkid(sta->sae->pmk, PMK_LEN, rsn->wpa_s->own_addr, 333 sta->addr, pmkid, 334 wpa_key_mgmt_sha256(wpa_auth_sta_key_mgmt(sta->wpa_sm))); 335 } 336 337 338 static void 339 mesh_rsn_derive_aek(struct mesh_rsn *rsn, struct sta_info *sta) 340 { 341 u8 *myaddr = rsn->wpa_s->own_addr; 342 u8 *peer = sta->addr; 343 u8 *addr1 = peer, *addr2 = myaddr; 344 u8 context[AES_BLOCK_SIZE]; 345 346 /* SAE */ 347 RSN_SELECTOR_PUT(context, wpa_cipher_to_suite(0, WPA_CIPHER_GCMP)); 348 349 if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) { 350 addr1 = myaddr; 351 addr2 = peer; 352 } 353 os_memcpy(context + 4, addr1, ETH_ALEN); 354 os_memcpy(context + 10, addr2, ETH_ALEN); 355 356 sha256_prf(sta->sae->pmk, sizeof(sta->sae->pmk), "AEK Derivation", 357 context, sizeof(context), sta->aek, sizeof(sta->aek)); 358 } 359 360 361 /* derive mesh temporal key from pmk */ 362 int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta) 363 { 364 u8 *ptr; 365 u8 *min, *max; 366 u16 min_lid, max_lid; 367 size_t nonce_len = sizeof(sta->my_nonce); 368 size_t lid_len = sizeof(sta->my_lid); 369 u8 *myaddr = wpa_s->own_addr; 370 u8 *peer = sta->addr; 371 /* 2 nonces, 2 linkids, akm suite, 2 mac addrs */ 372 u8 context[64 + 4 + 4 + 12]; 373 374 ptr = context; 375 if (os_memcmp(sta->my_nonce, sta->peer_nonce, nonce_len) < 0) { 376 min = sta->my_nonce; 377 max = sta->peer_nonce; 378 } else { 379 min = sta->peer_nonce; 380 max = sta->my_nonce; 381 } 382 os_memcpy(ptr, min, nonce_len); 383 os_memcpy(ptr + nonce_len, max, nonce_len); 384 ptr += 2 * nonce_len; 385 386 if (sta->my_lid < sta->peer_lid) { 387 min_lid = host_to_le16(sta->my_lid); 388 max_lid = host_to_le16(sta->peer_lid); 389 } else { 390 min_lid = host_to_le16(sta->peer_lid); 391 max_lid = host_to_le16(sta->my_lid); 392 } 393 os_memcpy(ptr, &min_lid, lid_len); 394 os_memcpy(ptr + lid_len, &max_lid, lid_len); 395 ptr += 2 * lid_len; 396 397 /* SAE */ 398 RSN_SELECTOR_PUT(ptr, wpa_cipher_to_suite(0, WPA_CIPHER_GCMP)); 399 ptr += 4; 400 401 if (os_memcmp(myaddr, peer, ETH_ALEN) < 0) { 402 min = myaddr; 403 max = peer; 404 } else { 405 min = peer; 406 max = myaddr; 407 } 408 os_memcpy(ptr, min, ETH_ALEN); 409 os_memcpy(ptr + ETH_ALEN, max, ETH_ALEN); 410 411 sha256_prf(sta->sae->pmk, sizeof(sta->sae->pmk), 412 "Temporal Key Derivation", context, sizeof(context), 413 sta->mtk, sizeof(sta->mtk)); 414 return 0; 415 } 416 417 418 void mesh_rsn_init_ampe_sta(struct wpa_supplicant *wpa_s, struct sta_info *sta) 419 { 420 if (random_get_bytes(sta->my_nonce, 32) < 0) { 421 wpa_printf(MSG_INFO, "mesh: Failed to derive random nonce"); 422 /* TODO: How to handle this more cleanly? */ 423 } 424 os_memset(sta->peer_nonce, 0, 32); 425 mesh_rsn_derive_aek(wpa_s->mesh_rsn, sta); 426 } 427 428 429 /* insert AMPE and encrypted MIC at @ie. 430 * @mesh_rsn: mesh RSN context 431 * @sta: STA we're sending to 432 * @cat: pointer to category code in frame header. 433 * @buf: wpabuf to add encrypted AMPE and MIC to. 434 * */ 435 int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta, 436 const u8 *cat, struct wpabuf *buf) 437 { 438 struct ieee80211_ampe_ie *ampe; 439 u8 const *ie = wpabuf_head_u8(buf) + wpabuf_len(buf); 440 u8 *ampe_ie = NULL, *mic_ie = NULL, *mic_payload; 441 const u8 *aad[] = { rsn->wpa_s->own_addr, sta->addr, cat }; 442 const size_t aad_len[] = { ETH_ALEN, ETH_ALEN, ie - cat }; 443 int ret = 0; 444 445 if (AES_BLOCK_SIZE + 2 + sizeof(*ampe) + 2 > wpabuf_tailroom(buf)) { 446 wpa_printf(MSG_ERROR, "protect frame: buffer too small"); 447 return -EINVAL; 448 } 449 450 ampe_ie = os_zalloc(2 + sizeof(*ampe)); 451 if (!ampe_ie) { 452 wpa_printf(MSG_ERROR, "protect frame: out of memory"); 453 return -ENOMEM; 454 } 455 456 mic_ie = os_zalloc(2 + AES_BLOCK_SIZE); 457 if (!mic_ie) { 458 wpa_printf(MSG_ERROR, "protect frame: out of memory"); 459 ret = -ENOMEM; 460 goto free; 461 } 462 463 /* IE: AMPE */ 464 ampe_ie[0] = WLAN_EID_AMPE; 465 ampe_ie[1] = sizeof(*ampe); 466 ampe = (struct ieee80211_ampe_ie *) (ampe_ie + 2); 467 468 RSN_SELECTOR_PUT(ampe->selected_pairwise_suite, 469 wpa_cipher_to_suite(WPA_PROTO_RSN, WPA_CIPHER_CCMP)); 470 os_memcpy(ampe->local_nonce, sta->my_nonce, 32); 471 os_memcpy(ampe->peer_nonce, sta->peer_nonce, 32); 472 /* incomplete: see 13.5.4 */ 473 /* TODO: static mgtk for now since we don't support rekeying! */ 474 os_memcpy(ampe->mgtk, rsn->mgtk, 16); 475 /* TODO: Populate Key RSC */ 476 /* expire in 13 decades or so */ 477 os_memset(ampe->key_expiration, 0xff, 4); 478 479 /* IE: MIC */ 480 mic_ie[0] = WLAN_EID_MIC; 481 mic_ie[1] = AES_BLOCK_SIZE; 482 wpabuf_put_data(buf, mic_ie, 2); 483 /* MIC field is output ciphertext */ 484 485 /* encrypt after MIC */ 486 mic_payload = (u8 *) wpabuf_put(buf, 2 + sizeof(*ampe) + 487 AES_BLOCK_SIZE); 488 489 if (aes_siv_encrypt(sta->aek, ampe_ie, 2 + sizeof(*ampe), 3, 490 aad, aad_len, mic_payload)) { 491 wpa_printf(MSG_ERROR, "protect frame: failed to encrypt"); 492 ret = -ENOMEM; 493 goto free; 494 } 495 496 free: 497 os_free(ampe_ie); 498 os_free(mic_ie); 499 500 return ret; 501 } 502 503 504 int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta, 505 struct ieee802_11_elems *elems, const u8 *cat, 506 const u8 *start, size_t elems_len) 507 { 508 int ret = 0; 509 struct ieee80211_ampe_ie *ampe; 510 u8 null_nonce[32] = {}; 511 u8 ampe_eid; 512 u8 ampe_ie_len; 513 u8 *ampe_buf, *crypt = NULL; 514 size_t crypt_len; 515 const u8 *aad[] = { sta->addr, wpa_s->own_addr, cat }; 516 const size_t aad_len[] = { ETH_ALEN, ETH_ALEN, 517 (elems->mic - 2) - cat }; 518 519 if (!elems->mic || elems->mic_len < AES_BLOCK_SIZE) { 520 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing mic ie"); 521 return -1; 522 } 523 524 ampe_buf = (u8 *) elems->mic + elems->mic_len; 525 if ((int) elems_len < ampe_buf - start) 526 return -1; 527 528 crypt_len = elems_len - (elems->mic - start); 529 if (crypt_len < 2) { 530 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: missing ampe ie"); 531 return -1; 532 } 533 534 /* crypt is modified by siv_decrypt */ 535 crypt = os_zalloc(crypt_len); 536 if (!crypt) { 537 wpa_printf(MSG_ERROR, "Mesh RSN: out of memory"); 538 ret = -ENOMEM; 539 goto free; 540 } 541 542 os_memcpy(crypt, elems->mic, crypt_len); 543 544 if (aes_siv_decrypt(sta->aek, crypt, crypt_len, 3, 545 aad, aad_len, ampe_buf)) { 546 wpa_printf(MSG_ERROR, "Mesh RSN: frame verification failed!"); 547 ret = -1; 548 goto free; 549 } 550 551 ampe_eid = *ampe_buf++; 552 ampe_ie_len = *ampe_buf++; 553 554 if (ampe_eid != WLAN_EID_AMPE || 555 ampe_ie_len < sizeof(struct ieee80211_ampe_ie)) { 556 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid ampe ie"); 557 ret = -1; 558 goto free; 559 } 560 561 ampe = (struct ieee80211_ampe_ie *) ampe_buf; 562 if (os_memcmp(ampe->peer_nonce, null_nonce, 32) != 0 && 563 os_memcmp(ampe->peer_nonce, sta->my_nonce, 32) != 0) { 564 wpa_msg(wpa_s, MSG_DEBUG, "Mesh RSN: invalid peer nonce"); 565 ret = -1; 566 goto free; 567 } 568 os_memcpy(sta->peer_nonce, ampe->local_nonce, 569 sizeof(ampe->local_nonce)); 570 os_memcpy(sta->mgtk, ampe->mgtk, sizeof(ampe->mgtk)); 571 572 /* todo parse mgtk expiration */ 573 free: 574 os_free(crypt); 575 return ret; 576 } 577