1 /* 2 * IEEE 802.1X-2010 Key Agreement Protocol of PAE state machine 3 * Copyright (c) 2013, Qualcomm Atheros, Inc. 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include <time.h> 10 #include "includes.h" 11 #include "common.h" 12 #include "list.h" 13 #include "eloop.h" 14 #include "wpabuf.h" 15 #include "state_machine.h" 16 #include "l2_packet/l2_packet.h" 17 #include "common/eapol_common.h" 18 #include "crypto/aes_wrap.h" 19 #include "ieee802_1x_cp.h" 20 #include "ieee802_1x_key.h" 21 #include "ieee802_1x_kay.h" 22 #include "ieee802_1x_kay_i.h" 23 #include "ieee802_1x_secy_ops.h" 24 25 26 #define DEFAULT_SA_KEY_LEN 16 27 #define DEFAULT_ICV_LEN 16 28 #define MAX_ICV_LEN 32 /* 32 bytes, 256 bits */ 29 30 #define MAX_MISSING_SAK_USE 10 /* Accept up to 10 inbound MKPDUs without 31 * SAK-USE before dropping */ 32 33 #define PENDING_PN_EXHAUSTION 0xC0000000 34 35 #define MKA_ALIGN_LENGTH(len) (((len) + 0x3) & ~0x3) 36 37 /* IEEE Std 802.1X-2010, Table 9-1 - MKA Algorithm Agility */ 38 #define MKA_ALGO_AGILITY_2009 { 0x00, 0x80, 0xC2, 0x01 } 39 static u8 mka_algo_agility[4] = MKA_ALGO_AGILITY_2009; 40 41 /* IEEE802.1AE-2006 Table 14-1 MACsec Cipher Suites */ 42 static struct macsec_ciphersuite cipher_suite_tbl[] = { 43 /* GCM-AES-128 */ 44 { 45 .id = CS_ID_GCM_AES_128, 46 .name = CS_NAME_GCM_AES_128, 47 .capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50, 48 .sak_len = DEFAULT_SA_KEY_LEN, 49 }, 50 /* GCM-AES-256 */ 51 { 52 .id = CS_ID_GCM_AES_256, 53 .name = CS_NAME_GCM_AES_256, 54 .capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50, 55 .sak_len = 32, 56 }, 57 }; 58 #define CS_TABLE_SIZE (ARRAY_SIZE(cipher_suite_tbl)) 59 #define DEFAULT_CS_INDEX 0 60 61 static struct mka_alg mka_alg_tbl[] = { 62 { 63 .parameter = MKA_ALGO_AGILITY_2009, 64 65 .icv_len = DEFAULT_ICV_LEN, 66 67 .cak_trfm = ieee802_1x_cak_aes_cmac, 68 .ckn_trfm = ieee802_1x_ckn_aes_cmac, 69 .kek_trfm = ieee802_1x_kek_aes_cmac, 70 .ick_trfm = ieee802_1x_ick_aes_cmac, 71 .icv_hash = ieee802_1x_icv_aes_cmac, 72 }, 73 }; 74 #define MKA_ALG_TABLE_SIZE (ARRAY_SIZE(mka_alg_tbl)) 75 76 77 static int is_ki_equal(struct ieee802_1x_mka_ki *ki1, 78 struct ieee802_1x_mka_ki *ki2) 79 { 80 return os_memcmp(ki1->mi, ki2->mi, MI_LEN) == 0 && 81 ki1->kn == ki2->kn; 82 } 83 84 85 static void set_mka_param_body_len(void *body, unsigned int len) 86 { 87 struct ieee802_1x_mka_hdr *hdr = body; 88 hdr->length = (len >> 8) & 0x0f; 89 hdr->length1 = len & 0xff; 90 } 91 92 93 static unsigned int get_mka_param_body_len(const void *body) 94 { 95 const struct ieee802_1x_mka_hdr *hdr = body; 96 return (hdr->length << 8) | hdr->length1; 97 } 98 99 100 static u8 get_mka_param_body_type(const void *body) 101 { 102 const struct ieee802_1x_mka_hdr *hdr = body; 103 return hdr->type; 104 } 105 106 107 static const char * mi_txt(const u8 *mi) 108 { 109 static char txt[MI_LEN * 2 + 1]; 110 111 wpa_snprintf_hex(txt, sizeof(txt), mi, MI_LEN); 112 return txt; 113 } 114 115 116 static const char * sci_txt(const struct ieee802_1x_mka_sci *sci) 117 { 118 static char txt[ETH_ALEN * 3 + 1 + 5 + 1]; 119 120 os_snprintf(txt, sizeof(txt), MACSTR "@%u", 121 MAC2STR(sci->addr), be_to_host16(sci->port)); 122 return txt; 123 } 124 125 126 static const char * algo_agility_txt(const u8 *algo_agility) 127 { 128 static char txt[4 * 2 + 1]; 129 130 wpa_snprintf_hex(txt, sizeof(txt), algo_agility, 4); 131 return txt; 132 } 133 134 135 /** 136 * ieee802_1x_mka_dump_basic_body - 137 */ 138 static void 139 ieee802_1x_mka_dump_basic_body(struct ieee802_1x_mka_basic_body *body) 140 { 141 size_t body_len; 142 143 if (!body) 144 return; 145 146 /* IEEE Std 802.1X-2010, Figure 11-8 */ 147 body_len = get_mka_param_body_len(body); 148 wpa_printf(MSG_DEBUG, "MKA Basic Parameter Set"); 149 wpa_printf(MSG_DEBUG, "\tMKA Version Identifier: %d", body->version); 150 wpa_printf(MSG_DEBUG, "\tKey Server Priority: %d", body->priority); 151 wpa_printf(MSG_DEBUG, "\tKey Server: %d", body->key_server); 152 wpa_printf(MSG_DEBUG, "\tMACsec Desired: %d", body->macsec_desired); 153 wpa_printf(MSG_DEBUG, "\tMACsec Capability: %d", 154 body->macsec_capability); 155 wpa_printf(MSG_DEBUG, "\tParameter set body length: %zu", body_len); 156 wpa_printf(MSG_DEBUG, "\tSCI: %s", sci_txt(&body->actor_sci)); 157 wpa_printf(MSG_DEBUG, "\tActor's Member Identifier: %s", 158 mi_txt(body->actor_mi)); 159 wpa_printf(MSG_DEBUG, "\tActor's Message Number: %d", 160 be_to_host32(body->actor_mn)); 161 wpa_printf(MSG_DEBUG, "\tAlgorithm Agility: %s", 162 algo_agility_txt(body->algo_agility)); 163 wpa_hexdump(MSG_DEBUG, "\tCAK Name", body->ckn, 164 body_len + MKA_HDR_LEN - sizeof(*body)); 165 } 166 167 168 /** 169 * ieee802_1x_mka_dump_peer_body - 170 */ 171 static void 172 ieee802_1x_mka_dump_peer_body(struct ieee802_1x_mka_peer_body *body) 173 { 174 size_t body_len; 175 size_t i; 176 u8 *mi; 177 be32 mn; 178 179 if (body == NULL) 180 return; 181 182 /* IEEE Std 802.1X-2010, Figure 11-9 */ 183 body_len = get_mka_param_body_len(body); 184 if (body->type == MKA_LIVE_PEER_LIST) { 185 wpa_printf(MSG_DEBUG, "Live Peer List parameter set"); 186 wpa_printf(MSG_DEBUG, "\tBody Length: %zu", body_len); 187 } else if (body->type == MKA_POTENTIAL_PEER_LIST) { 188 wpa_printf(MSG_DEBUG, "Potential Peer List parameter set"); 189 wpa_printf(MSG_DEBUG, "\tBody Length: %zu", body_len); 190 } 191 192 for (i = 0; i < body_len; i += MI_LEN + sizeof(mn)) { 193 mi = body->peer + i; 194 os_memcpy(&mn, mi + MI_LEN, sizeof(mn)); 195 wpa_printf(MSG_DEBUG, "\tMember Id: %s Message Number: %d", 196 mi_txt(mi), be_to_host32(mn)); 197 } 198 } 199 200 201 /** 202 * ieee802_1x_mka_dump_dist_sak_body - 203 */ 204 static void 205 ieee802_1x_mka_dump_dist_sak_body(struct ieee802_1x_mka_dist_sak_body *body) 206 { 207 size_t body_len; 208 209 if (body == NULL) 210 return; 211 212 /* IEEE Std 802.1X-2010, Figure 11-11 and 11-12 */ 213 body_len = get_mka_param_body_len(body); 214 wpa_printf(MSG_DEBUG, "Distributed SAK parameter set"); 215 wpa_printf(MSG_DEBUG, "\tDistributed AN........: %d", body->dan); 216 wpa_printf(MSG_DEBUG, "\tConfidentiality Offset: %d", 217 body->confid_offset); 218 wpa_printf(MSG_DEBUG, "\tBody Length...........: %zu", body_len); 219 if (!body_len) 220 return; 221 222 wpa_printf(MSG_DEBUG, "\tKey Number............: %d", 223 be_to_host32(body->kn)); 224 if (body_len == 28) { 225 wpa_hexdump(MSG_DEBUG, "\tAES Key Wrap of SAK...:", 226 body->sak, 24); 227 } else if (body_len > CS_ID_LEN - sizeof(body->kn)) { 228 wpa_hexdump(MSG_DEBUG, "\tMACsec Cipher Suite...:", 229 body->sak, CS_ID_LEN); 230 wpa_hexdump(MSG_DEBUG, "\tAES Key Wrap of SAK...:", 231 body->sak + CS_ID_LEN, 232 body_len - CS_ID_LEN - sizeof(body->kn)); 233 } 234 } 235 236 237 static const char * yes_no(int val) 238 { 239 return val ? "Yes" : "No"; 240 } 241 242 243 /** 244 * ieee802_1x_mka_dump_sak_use_body - 245 */ 246 static void 247 ieee802_1x_mka_dump_sak_use_body(struct ieee802_1x_mka_sak_use_body *body) 248 { 249 int body_len; 250 251 if (body == NULL) 252 return; 253 254 /* IEEE Std 802.1X-2010, Figure 11-10 */ 255 body_len = get_mka_param_body_len(body); 256 wpa_printf(MSG_DEBUG, "MACsec SAK Use parameter set"); 257 wpa_printf(MSG_DEBUG, "\tLatest Key AN....: %d", body->lan); 258 wpa_printf(MSG_DEBUG, "\tLatest Key Tx....: %s", yes_no(body->ltx)); 259 wpa_printf(MSG_DEBUG, "\tLatest Key Rx....: %s", yes_no(body->lrx)); 260 wpa_printf(MSG_DEBUG, "\tOld Key AN.......: %d", body->oan); 261 wpa_printf(MSG_DEBUG, "\tOld Key Tx.......: %s", yes_no(body->otx)); 262 wpa_printf(MSG_DEBUG, "\tOld Key Rx.......: %s", yes_no(body->orx)); 263 wpa_printf(MSG_DEBUG, "\tPlain Tx.........: %s", yes_no(body->ptx)); 264 wpa_printf(MSG_DEBUG, "\tPlain Rx.........: %s", yes_no(body->prx)); 265 wpa_printf(MSG_DEBUG, "\tDelay Protect....: %s", 266 yes_no(body->delay_protect)); 267 wpa_printf(MSG_DEBUG, "\tBody Length......: %d", body_len); 268 if (!body_len) 269 return; 270 271 wpa_printf(MSG_DEBUG, "\tKey Server MI....: %s", mi_txt(body->lsrv_mi)); 272 wpa_printf(MSG_DEBUG, "\tKey Number.......: %u", 273 be_to_host32(body->lkn)); 274 wpa_printf(MSG_DEBUG, "\tLowest PN........: %u", 275 be_to_host32(body->llpn)); 276 wpa_printf(MSG_DEBUG, "\tOld Key Server MI: %s", mi_txt(body->osrv_mi)); 277 wpa_printf(MSG_DEBUG, "\tOld Key Number...: %u", 278 be_to_host32(body->okn)); 279 wpa_printf(MSG_DEBUG, "\tOld Lowest PN....: %u", 280 be_to_host32(body->olpn)); 281 } 282 283 284 /** 285 * ieee802_1x_kay_get_participant - 286 */ 287 static struct ieee802_1x_mka_participant * 288 ieee802_1x_kay_get_participant(struct ieee802_1x_kay *kay, const u8 *ckn, 289 size_t len) 290 { 291 struct ieee802_1x_mka_participant *participant; 292 293 dl_list_for_each(participant, &kay->participant_list, 294 struct ieee802_1x_mka_participant, list) { 295 if (participant->ckn.len == len && 296 os_memcmp(participant->ckn.name, ckn, 297 participant->ckn.len) == 0) 298 return participant; 299 } 300 301 wpa_printf(MSG_DEBUG, "KaY: participant is not found"); 302 303 return NULL; 304 } 305 306 307 /** 308 * ieee802_1x_kay_get_principal_participant - 309 */ 310 static struct ieee802_1x_mka_participant * 311 ieee802_1x_kay_get_principal_participant(struct ieee802_1x_kay *kay) 312 { 313 struct ieee802_1x_mka_participant *participant; 314 315 dl_list_for_each(participant, &kay->participant_list, 316 struct ieee802_1x_mka_participant, list) { 317 if (participant->principal) 318 return participant; 319 } 320 321 wpa_printf(MSG_DEBUG, "KaY: principal participant is not found"); 322 return NULL; 323 } 324 325 326 static struct ieee802_1x_kay_peer * get_peer_mi(struct dl_list *peers, 327 const u8 *mi) 328 { 329 struct ieee802_1x_kay_peer *peer; 330 331 dl_list_for_each(peer, peers, struct ieee802_1x_kay_peer, list) { 332 if (os_memcmp(peer->mi, mi, MI_LEN) == 0) 333 return peer; 334 } 335 336 return NULL; 337 } 338 339 340 /** 341 * ieee802_1x_kay_get_potential_peer 342 */ 343 static struct ieee802_1x_kay_peer * 344 ieee802_1x_kay_get_potential_peer( 345 struct ieee802_1x_mka_participant *participant, const u8 *mi) 346 { 347 return get_peer_mi(&participant->potential_peers, mi); 348 } 349 350 351 /** 352 * ieee802_1x_kay_get_live_peer 353 */ 354 static struct ieee802_1x_kay_peer * 355 ieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant *participant, 356 const u8 *mi) 357 { 358 return get_peer_mi(&participant->live_peers, mi); 359 } 360 361 362 /** 363 * ieee802_1x_kay_is_in_potential_peer 364 */ 365 static bool 366 ieee802_1x_kay_is_in_potential_peer( 367 struct ieee802_1x_mka_participant *participant, const u8 *mi) 368 { 369 return ieee802_1x_kay_get_potential_peer(participant, mi) != NULL; 370 } 371 372 373 /** 374 * ieee802_1x_kay_is_in_live_peer 375 */ 376 static bool 377 ieee802_1x_kay_is_in_live_peer( 378 struct ieee802_1x_mka_participant *participant, const u8 *mi) 379 { 380 return ieee802_1x_kay_get_live_peer(participant, mi) != NULL; 381 } 382 383 384 /** 385 * ieee802_1x_kay_get_peer 386 */ 387 static struct ieee802_1x_kay_peer * 388 ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant, 389 const u8 *mi) 390 { 391 struct ieee802_1x_kay_peer *peer; 392 393 peer = ieee802_1x_kay_get_live_peer(participant, mi); 394 if (peer) 395 return peer; 396 397 return ieee802_1x_kay_get_potential_peer(participant, mi); 398 } 399 400 401 /** 402 * ieee802_1x_kay_get_cipher_suite 403 */ 404 static struct macsec_ciphersuite * 405 ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant, 406 const u8 *cs_id, unsigned int *idx) 407 { 408 unsigned int i; 409 u64 cs; 410 be64 _cs; 411 412 os_memcpy(&_cs, cs_id, CS_ID_LEN); 413 cs = be_to_host64(_cs); 414 415 for (i = 0; i < CS_TABLE_SIZE; i++) { 416 if (cipher_suite_tbl[i].id == cs) { 417 *idx = i; 418 return &cipher_suite_tbl[i]; 419 } 420 } 421 422 return NULL; 423 } 424 425 426 u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci) 427 { 428 struct ieee802_1x_mka_sci tmp; 429 430 os_memcpy(tmp.addr, sci->addr, ETH_ALEN); 431 tmp.port = sci->port; 432 433 return *((u64 *) &tmp); 434 } 435 436 437 static bool sci_equal(const struct ieee802_1x_mka_sci *a, 438 const struct ieee802_1x_mka_sci *b) 439 { 440 return os_memcmp(a, b, sizeof(struct ieee802_1x_mka_sci)) == 0; 441 } 442 443 444 /** 445 * ieee802_1x_kay_get_peer_sci 446 */ 447 static struct ieee802_1x_kay_peer * 448 ieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant *participant, 449 const struct ieee802_1x_mka_sci *sci) 450 { 451 struct ieee802_1x_kay_peer *peer; 452 453 dl_list_for_each(peer, &participant->live_peers, 454 struct ieee802_1x_kay_peer, list) { 455 if (sci_equal(&peer->sci, sci)) 456 return peer; 457 } 458 459 dl_list_for_each(peer, &participant->potential_peers, 460 struct ieee802_1x_kay_peer, list) { 461 if (sci_equal(&peer->sci, sci)) 462 return peer; 463 } 464 465 return NULL; 466 } 467 468 469 static void ieee802_1x_kay_use_data_key(struct data_key *pkey); 470 471 /** 472 * ieee802_1x_kay_init_receive_sa - 473 */ 474 static struct receive_sa * 475 ieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn, 476 struct data_key *key) 477 { 478 struct receive_sa *psa; 479 480 if (!psc || !key) 481 return NULL; 482 483 psa = os_zalloc(sizeof(*psa)); 484 if (!psa) { 485 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 486 return NULL; 487 } 488 489 ieee802_1x_kay_use_data_key(key); 490 psa->pkey = key; 491 psa->lowest_pn = lowest_pn; 492 psa->next_pn = lowest_pn; 493 psa->an = an; 494 psa->sc = psc; 495 496 os_get_time(&psa->created_time); 497 psa->in_use = false; 498 499 dl_list_add(&psc->sa_list, &psa->list); 500 wpa_printf(MSG_DEBUG, 501 "KaY: Create receive SA(an: %hhu lowest_pn: %u) of SC", 502 an, lowest_pn); 503 504 return psa; 505 } 506 507 508 static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey); 509 510 /** 511 * ieee802_1x_kay_deinit_receive_sa - 512 */ 513 static void ieee802_1x_kay_deinit_receive_sa(struct receive_sa *psa) 514 { 515 ieee802_1x_kay_deinit_data_key(psa->pkey); 516 psa->pkey = NULL; 517 wpa_printf(MSG_DEBUG, 518 "KaY: Delete receive SA(an: %hhu) of SC", 519 psa->an); 520 dl_list_del(&psa->list); 521 os_free(psa); 522 } 523 524 525 /** 526 * ieee802_1x_kay_init_receive_sc - 527 */ 528 static struct receive_sc * 529 ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci) 530 { 531 struct receive_sc *psc; 532 533 if (!psci) 534 return NULL; 535 536 psc = os_zalloc(sizeof(*psc)); 537 if (!psc) { 538 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 539 return NULL; 540 } 541 542 os_memcpy(&psc->sci, psci, sizeof(psc->sci)); 543 544 os_get_time(&psc->created_time); 545 psc->receiving = false; 546 547 dl_list_init(&psc->sa_list); 548 wpa_printf(MSG_DEBUG, "KaY: Create receive SC: SCI %s", 549 sci_txt(&psc->sci)); 550 551 return psc; 552 } 553 554 555 static void ieee802_1x_delete_receive_sa(struct ieee802_1x_kay *kay, 556 struct receive_sa *sa) 557 { 558 secy_disable_receive_sa(kay, sa); 559 secy_delete_receive_sa(kay, sa); 560 ieee802_1x_kay_deinit_receive_sa(sa); 561 } 562 563 564 /** 565 * ieee802_1x_kay_deinit_receive_sc - 566 **/ 567 static void 568 ieee802_1x_kay_deinit_receive_sc( 569 struct ieee802_1x_mka_participant *participant, struct receive_sc *psc) 570 { 571 struct receive_sa *psa, *pre_sa; 572 573 wpa_printf(MSG_DEBUG, "KaY: Delete receive SC"); 574 dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, 575 list) 576 ieee802_1x_delete_receive_sa(participant->kay, psa); 577 578 dl_list_del(&psc->list); 579 secy_delete_receive_sc(participant->kay, psc); 580 os_free(psc); 581 } 582 583 584 static void ieee802_1x_kay_dump_peer(struct ieee802_1x_kay_peer *peer) 585 { 586 wpa_printf(MSG_DEBUG, "\tMI: %s MN: %d SCI: %s", 587 mi_txt(peer->mi), peer->mn, sci_txt(&peer->sci)); 588 } 589 590 591 static struct ieee802_1x_kay_peer * 592 ieee802_1x_kay_create_peer(const u8 *mi, u32 mn) 593 { 594 struct ieee802_1x_kay_peer *peer; 595 596 peer = os_zalloc(sizeof(*peer)); 597 if (!peer) { 598 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 599 return NULL; 600 } 601 602 os_memcpy(peer->mi, mi, MI_LEN); 603 peer->mn = mn; 604 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 605 peer->sak_used = false; 606 peer->missing_sak_use_count = 0; 607 608 return peer; 609 } 610 611 612 /** 613 * ieee802_1x_kay_create_live_peer 614 */ 615 static struct ieee802_1x_kay_peer * 616 ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant, 617 const u8 *mi, u32 mn) 618 { 619 struct ieee802_1x_kay_peer *peer; 620 struct receive_sc *rxsc; 621 622 peer = ieee802_1x_kay_create_peer(mi, mn); 623 if (!peer) 624 return NULL; 625 626 os_memcpy(&peer->sci, &participant->current_peer_sci, 627 sizeof(peer->sci)); 628 629 rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci); 630 if (!rxsc) { 631 os_free(peer); 632 return NULL; 633 } 634 635 if (secy_create_receive_sc(participant->kay, rxsc)) { 636 os_free(rxsc); 637 os_free(peer); 638 return NULL; 639 } 640 dl_list_add(&participant->live_peers, &peer->list); 641 dl_list_add(&participant->rxsc_list, &rxsc->list); 642 643 wpa_printf(MSG_DEBUG, "KaY: Live peer created"); 644 ieee802_1x_kay_dump_peer(peer); 645 646 return peer; 647 } 648 649 650 /** 651 * ieee802_1x_kay_create_potential_peer 652 */ 653 static struct ieee802_1x_kay_peer * 654 ieee802_1x_kay_create_potential_peer( 655 struct ieee802_1x_mka_participant *participant, const u8 *mi, u32 mn) 656 { 657 struct ieee802_1x_kay_peer *peer; 658 659 peer = ieee802_1x_kay_create_peer(mi, mn); 660 if (!peer) 661 return NULL; 662 663 dl_list_add(&participant->potential_peers, &peer->list); 664 665 wpa_printf(MSG_DEBUG, "KaY: Potential peer created"); 666 ieee802_1x_kay_dump_peer(peer); 667 668 return peer; 669 } 670 671 672 /** 673 * ieee802_1x_kay_move_live_peer 674 */ 675 static struct ieee802_1x_kay_peer * 676 ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant, 677 u8 *mi, u32 mn) 678 { 679 struct ieee802_1x_kay_peer *peer; 680 struct receive_sc *rxsc; 681 682 peer = ieee802_1x_kay_get_potential_peer(participant, mi); 683 if (!peer) 684 return NULL; 685 686 rxsc = ieee802_1x_kay_init_receive_sc(&participant->current_peer_sci); 687 if (!rxsc) 688 return NULL; 689 690 os_memcpy(&peer->sci, &participant->current_peer_sci, 691 sizeof(peer->sci)); 692 peer->mn = mn; 693 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 694 695 wpa_printf(MSG_DEBUG, "KaY: Move potential peer to live peer"); 696 ieee802_1x_kay_dump_peer(peer); 697 698 dl_list_del(&peer->list); 699 if (secy_create_receive_sc(participant->kay, rxsc)) { 700 wpa_printf(MSG_ERROR, "KaY: Can't create SC, discard peer"); 701 os_free(rxsc); 702 os_free(peer); 703 return NULL; 704 } 705 dl_list_add_tail(&participant->live_peers, &peer->list); 706 707 dl_list_add(&participant->rxsc_list, &rxsc->list); 708 709 return peer; 710 } 711 712 713 714 /** 715 * ieee802_1x_mka_basic_body_present - 716 */ 717 static bool 718 ieee802_1x_mka_basic_body_present( 719 struct ieee802_1x_mka_participant *participant) 720 { 721 return true; 722 } 723 724 725 /** 726 * ieee802_1x_mka_basic_body_length - 727 */ 728 static int 729 ieee802_1x_mka_basic_body_length(struct ieee802_1x_mka_participant *participant) 730 { 731 int length; 732 733 length = sizeof(struct ieee802_1x_mka_basic_body); 734 length += participant->ckn.len; 735 return MKA_ALIGN_LENGTH(length); 736 } 737 738 739 /** 740 * ieee802_1x_mka_encode_basic_body 741 */ 742 static int 743 ieee802_1x_mka_encode_basic_body( 744 struct ieee802_1x_mka_participant *participant, 745 struct wpabuf *buf) 746 { 747 struct ieee802_1x_mka_basic_body *body; 748 struct ieee802_1x_kay *kay = participant->kay; 749 unsigned int length = sizeof(struct ieee802_1x_mka_basic_body); 750 751 length += participant->ckn.len; 752 body = wpabuf_put(buf, MKA_ALIGN_LENGTH(length)); 753 754 body->version = kay->mka_version; 755 body->priority = kay->actor_priority; 756 /* The Key Server flag is set if and only if the participant has not 757 * decided that another participant is or will be the Key Server. */ 758 if (participant->is_elected) 759 body->key_server = participant->is_key_server; 760 else 761 body->key_server = participant->can_be_key_server; 762 763 body->macsec_desired = kay->macsec_desired; 764 body->macsec_capability = kay->macsec_capable; 765 set_mka_param_body_len(body, length - MKA_HDR_LEN); 766 767 os_memcpy(body->actor_sci.addr, kay->actor_sci.addr, 768 sizeof(kay->actor_sci.addr)); 769 body->actor_sci.port = kay->actor_sci.port; 770 771 os_memcpy(body->actor_mi, participant->mi, sizeof(body->actor_mi)); 772 participant->mn = participant->mn + 1; 773 body->actor_mn = host_to_be32(participant->mn); 774 os_memcpy(body->algo_agility, kay->algo_agility, 775 sizeof(body->algo_agility)); 776 777 os_memcpy(body->ckn, participant->ckn.name, participant->ckn.len); 778 779 ieee802_1x_mka_dump_basic_body(body); 780 781 return 0; 782 } 783 784 785 static bool 786 reset_participant_mi(struct ieee802_1x_mka_participant *participant) 787 { 788 if (os_get_random(participant->mi, sizeof(participant->mi)) < 0) 789 return false; 790 participant->mn = 0; 791 792 return true; 793 } 794 795 796 /** 797 * ieee802_1x_mka_decode_basic_body - 798 */ 799 static struct ieee802_1x_mka_participant * 800 ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg, 801 size_t msg_len) 802 { 803 struct ieee802_1x_mka_participant *participant; 804 const struct ieee802_1x_mka_basic_body *body; 805 struct ieee802_1x_kay_peer *peer; 806 size_t ckn_len; 807 size_t body_len; 808 809 body = (const struct ieee802_1x_mka_basic_body *) mka_msg; 810 811 if (body->version > MKA_VERSION_ID) { 812 wpa_printf(MSG_DEBUG, 813 "KaY: Peer's version(%d) greater than MKA current version(%d)", 814 body->version, MKA_VERSION_ID); 815 } 816 if (kay->is_obliged_key_server && body->key_server) { 817 wpa_printf(MSG_DEBUG, "KaY: I must be key server - ignore MKPDU claiming to be from a key server"); 818 return NULL; 819 } 820 821 body_len = get_mka_param_body_len(body); 822 if (body_len < sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN) { 823 wpa_printf(MSG_DEBUG, "KaY: Too small body length %zu", 824 body_len); 825 return NULL; 826 } 827 ckn_len = body_len - 828 (sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN); 829 participant = ieee802_1x_kay_get_participant(kay, body->ckn, ckn_len); 830 if (!participant) { 831 wpa_printf(MSG_DEBUG, 832 "KaY: Peer is not included in my CA - ignore MKPDU"); 833 return NULL; 834 } 835 836 /* If the peer's MI is my MI, I will choose new MI */ 837 if (os_memcmp(body->actor_mi, participant->mi, MI_LEN) == 0) { 838 if (!reset_participant_mi(participant)) 839 return NULL; 840 wpa_printf(MSG_DEBUG, 841 "KaY: Peer using my MI - selected a new random MI: %s", 842 mi_txt(participant->mi)); 843 } 844 845 os_memcpy(participant->current_peer_id.mi, body->actor_mi, MI_LEN); 846 participant->current_peer_id.mn = body->actor_mn; 847 os_memcpy(participant->current_peer_sci.addr, body->actor_sci.addr, 848 sizeof(participant->current_peer_sci.addr)); 849 participant->current_peer_sci.port = body->actor_sci.port; 850 851 /* handler peer */ 852 peer = ieee802_1x_kay_get_peer(participant, body->actor_mi); 853 if (!peer) { 854 /* Check duplicated SCI 855 * 856 * A duplicated SCI indicates either an active attacker or 857 * a valid peer whose MI is being changed. The latter scenario 858 * is more likely because to have gotten this far the received 859 * MKPDU must have had a valid ICV, indicating the peer holds 860 * the same CAK as our participant. 861 * 862 * Before creating a new peer object for the new MI we must 863 * clean up the resources (SCs and SAs) associated with the 864 * old peer. An easy way to do this is to ignore MKPDUs with 865 * the new MI's for now and just wait for the old peer to 866 * time out and clean itself up (within MKA_LIFE_TIME). 867 * 868 * This method is preferable to deleting the old peer here 869 * and now and continuing on with processing because if this 870 * MKPDU is from an attacker it's better to ignore the MKPDU 871 * than to process it (and delete a valid peer as well). 872 */ 873 peer = ieee802_1x_kay_get_peer_sci(participant, 874 &body->actor_sci); 875 if (peer) { 876 time_t new_expire; 877 878 wpa_printf(MSG_WARNING, 879 "KaY: duplicated SCI detected - maybe active attacker or peer selected new MI - ignore MKPDU"); 880 /* Reduce timeout to speed up this process but left the 881 * chance for old one to prove aliveness. */ 882 new_expire = time(NULL) + MKA_HELLO_TIME * 1.5 / 1000; 883 if (peer->expire > new_expire) 884 peer->expire = new_expire; 885 return NULL; 886 } 887 888 peer = ieee802_1x_kay_create_potential_peer( 889 participant, body->actor_mi, 890 be_to_host32(body->actor_mn)); 891 if (!peer) { 892 wpa_printf(MSG_DEBUG, 893 "KaY: No potential peer entry found - ignore MKPDU"); 894 return NULL; 895 } 896 897 peer->macsec_desired = body->macsec_desired; 898 peer->macsec_capability = body->macsec_capability; 899 peer->is_key_server = body->key_server; 900 peer->key_server_priority = body->priority; 901 } else if (peer->mn < be_to_host32(body->actor_mn)) { 902 peer->mn = be_to_host32(body->actor_mn); 903 peer->macsec_desired = body->macsec_desired; 904 peer->macsec_capability = body->macsec_capability; 905 peer->is_key_server = body->key_server; 906 peer->key_server_priority = body->priority; 907 } else { 908 wpa_printf(MSG_WARNING, 909 "KaY: The peer MN did not increase - ignore MKPDU"); 910 return NULL; 911 } 912 913 return participant; 914 } 915 916 917 /** 918 * ieee802_1x_mka_live_peer_body_present 919 */ 920 static bool 921 ieee802_1x_mka_live_peer_body_present( 922 struct ieee802_1x_mka_participant *participant) 923 { 924 return !dl_list_empty(&participant->live_peers); 925 } 926 927 928 /** 929 * ieee802_1x_kay_get_live_peer_length 930 */ 931 static int 932 ieee802_1x_mka_get_live_peer_length( 933 struct ieee802_1x_mka_participant *participant) 934 { 935 int len = MKA_HDR_LEN; 936 struct ieee802_1x_kay_peer *peer; 937 938 dl_list_for_each(peer, &participant->live_peers, 939 struct ieee802_1x_kay_peer, list) 940 len += sizeof(struct ieee802_1x_mka_peer_id); 941 942 return MKA_ALIGN_LENGTH(len); 943 } 944 945 946 /** 947 * ieee802_1x_mka_encode_live_peer_body - 948 */ 949 static int 950 ieee802_1x_mka_encode_live_peer_body( 951 struct ieee802_1x_mka_participant *participant, 952 struct wpabuf *buf) 953 { 954 struct ieee802_1x_mka_peer_body *body; 955 struct ieee802_1x_kay_peer *peer; 956 unsigned int length; 957 struct ieee802_1x_mka_peer_id *body_peer; 958 959 length = ieee802_1x_mka_get_live_peer_length(participant); 960 body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body)); 961 962 body->type = MKA_LIVE_PEER_LIST; 963 set_mka_param_body_len(body, length - MKA_HDR_LEN); 964 965 dl_list_for_each(peer, &participant->live_peers, 966 struct ieee802_1x_kay_peer, list) { 967 body_peer = wpabuf_put(buf, 968 sizeof(struct ieee802_1x_mka_peer_id)); 969 os_memcpy(body_peer->mi, peer->mi, MI_LEN); 970 body_peer->mn = host_to_be32(peer->mn); 971 } 972 973 ieee802_1x_mka_dump_peer_body(body); 974 return 0; 975 } 976 977 /** 978 * ieee802_1x_mka_potential_peer_body_present 979 */ 980 static bool 981 ieee802_1x_mka_potential_peer_body_present( 982 struct ieee802_1x_mka_participant *participant) 983 { 984 return !dl_list_empty(&participant->potential_peers); 985 } 986 987 988 /** 989 * ieee802_1x_kay_get_potential_peer_length 990 */ 991 static int 992 ieee802_1x_mka_get_potential_peer_length( 993 struct ieee802_1x_mka_participant *participant) 994 { 995 int len = MKA_HDR_LEN; 996 struct ieee802_1x_kay_peer *peer; 997 998 dl_list_for_each(peer, &participant->potential_peers, 999 struct ieee802_1x_kay_peer, list) 1000 len += sizeof(struct ieee802_1x_mka_peer_id); 1001 1002 return MKA_ALIGN_LENGTH(len); 1003 } 1004 1005 1006 /** 1007 * ieee802_1x_mka_encode_potential_peer_body - 1008 */ 1009 static int 1010 ieee802_1x_mka_encode_potential_peer_body( 1011 struct ieee802_1x_mka_participant *participant, 1012 struct wpabuf *buf) 1013 { 1014 struct ieee802_1x_mka_peer_body *body; 1015 struct ieee802_1x_kay_peer *peer; 1016 unsigned int length; 1017 struct ieee802_1x_mka_peer_id *body_peer; 1018 1019 length = ieee802_1x_mka_get_potential_peer_length(participant); 1020 body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body)); 1021 1022 body->type = MKA_POTENTIAL_PEER_LIST; 1023 set_mka_param_body_len(body, length - MKA_HDR_LEN); 1024 1025 dl_list_for_each(peer, &participant->potential_peers, 1026 struct ieee802_1x_kay_peer, list) { 1027 body_peer = wpabuf_put(buf, 1028 sizeof(struct ieee802_1x_mka_peer_id)); 1029 os_memcpy(body_peer->mi, peer->mi, MI_LEN); 1030 body_peer->mn = host_to_be32(peer->mn); 1031 } 1032 1033 ieee802_1x_mka_dump_peer_body(body); 1034 return 0; 1035 } 1036 1037 1038 /** 1039 * ieee802_1x_mka_i_in_peerlist - 1040 */ 1041 static bool 1042 ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant, 1043 const u8 *mka_msg, size_t msg_len) 1044 { 1045 struct ieee802_1x_mka_hdr *hdr; 1046 size_t body_len; 1047 size_t left_len; 1048 u8 body_type; 1049 const u8 *pos; 1050 size_t i; 1051 1052 for (pos = mka_msg, left_len = msg_len; 1053 left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN; 1054 left_len -= MKA_ALIGN_LENGTH(body_len) + MKA_HDR_LEN, 1055 pos += MKA_ALIGN_LENGTH(body_len) + MKA_HDR_LEN) { 1056 hdr = (struct ieee802_1x_mka_hdr *) pos; 1057 body_len = get_mka_param_body_len(hdr); 1058 body_type = get_mka_param_body_type(hdr); 1059 1060 if (left_len < (MKA_HDR_LEN + MKA_ALIGN_LENGTH(body_len) + DEFAULT_ICV_LEN)) { 1061 wpa_printf(MSG_ERROR, 1062 "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV", 1063 left_len, MKA_HDR_LEN, 1064 MKA_ALIGN_LENGTH(body_len), 1065 DEFAULT_ICV_LEN); 1066 return false; 1067 } 1068 1069 if (body_type != MKA_LIVE_PEER_LIST && 1070 body_type != MKA_POTENTIAL_PEER_LIST) 1071 continue; 1072 1073 if ((body_len % 16) != 0) { 1074 wpa_printf(MSG_ERROR, 1075 "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets", 1076 body_len); 1077 continue; 1078 } 1079 1080 ieee802_1x_mka_dump_peer_body( 1081 (struct ieee802_1x_mka_peer_body *)pos); 1082 1083 for (i = 0; i < body_len; 1084 i += sizeof(struct ieee802_1x_mka_peer_id)) { 1085 const struct ieee802_1x_mka_peer_id *peer_mi; 1086 1087 peer_mi = (const struct ieee802_1x_mka_peer_id *) 1088 (pos + MKA_HDR_LEN + i); 1089 if (os_memcmp(peer_mi->mi, participant->mi, 1090 MI_LEN) == 0) { 1091 u32 mn = be_to_host32(peer_mi->mn); 1092 1093 wpa_printf(MSG_DEBUG, 1094 "KaY: My MI - received MN %u, most recently transmitted MN %u", 1095 mn, participant->mn); 1096 /* IEEE Std 802.1X-2010 is not exactly clear 1097 * which values of MN should be accepted here. 1098 * It uses "acceptably recent MN" language 1099 * without defining what would be acceptable 1100 * recent. For now, allow the last two used MN 1101 * values (i.e., peer having copied my MI,MN 1102 * from either of the last two MKPDUs that I 1103 * have sent). */ 1104 if (mn == participant->mn || 1105 (participant->mn > 1 && 1106 mn == participant->mn - 1)) 1107 return true; 1108 } 1109 } 1110 } 1111 1112 return false; 1113 } 1114 1115 1116 /** 1117 * ieee802_1x_mka_decode_live_peer_body - 1118 */ 1119 static int ieee802_1x_mka_decode_live_peer_body( 1120 struct ieee802_1x_mka_participant *participant, 1121 const u8 *peer_msg, size_t msg_len) 1122 { 1123 const struct ieee802_1x_mka_hdr *hdr; 1124 struct ieee802_1x_kay_peer *peer; 1125 size_t body_len; 1126 size_t i; 1127 bool is_included; 1128 1129 is_included = ieee802_1x_kay_is_in_live_peer( 1130 participant, participant->current_peer_id.mi); 1131 1132 hdr = (const struct ieee802_1x_mka_hdr *) peer_msg; 1133 body_len = get_mka_param_body_len(hdr); 1134 if (body_len % 16 != 0) { 1135 wpa_printf(MSG_ERROR, 1136 "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets", 1137 body_len); 1138 return -1; 1139 } 1140 1141 for (i = 0; i < body_len; i += sizeof(struct ieee802_1x_mka_peer_id)) { 1142 const struct ieee802_1x_mka_peer_id *peer_mi; 1143 u32 peer_mn; 1144 1145 peer_mi = (const struct ieee802_1x_mka_peer_id *) 1146 (peer_msg + MKA_HDR_LEN + i); 1147 peer_mn = be_to_host32(peer_mi->mn); 1148 1149 /* it is myself */ 1150 if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) { 1151 /* My message id is used by other participant */ 1152 if (peer_mn > participant->mn && 1153 !reset_participant_mi(participant)) 1154 wpa_printf(MSG_DEBUG, "KaY: Could not update mi"); 1155 continue; 1156 } 1157 1158 if (!is_included) 1159 continue; 1160 1161 peer = ieee802_1x_kay_get_peer(participant, peer_mi->mi); 1162 if (peer) { 1163 peer->mn = peer_mn; 1164 } else if (!ieee802_1x_kay_create_potential_peer( 1165 participant, peer_mi->mi, peer_mn)) { 1166 return -1; 1167 } 1168 } 1169 1170 return 0; 1171 } 1172 1173 1174 /** 1175 * ieee802_1x_mka_decode_potential_peer_body - 1176 */ 1177 static int 1178 ieee802_1x_mka_decode_potential_peer_body( 1179 struct ieee802_1x_mka_participant *participant, 1180 const u8 *peer_msg, size_t msg_len) 1181 { 1182 const struct ieee802_1x_mka_hdr *hdr; 1183 size_t body_len; 1184 size_t i; 1185 1186 hdr = (const struct ieee802_1x_mka_hdr *) peer_msg; 1187 body_len = get_mka_param_body_len(hdr); 1188 if (body_len % 16 != 0) { 1189 wpa_printf(MSG_ERROR, 1190 "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets", 1191 body_len); 1192 return -1; 1193 } 1194 1195 for (i = 0; i < body_len; i += sizeof(struct ieee802_1x_mka_peer_id)) { 1196 const struct ieee802_1x_mka_peer_id *peer_mi; 1197 u32 peer_mn; 1198 1199 peer_mi = (struct ieee802_1x_mka_peer_id *) 1200 (peer_msg + MKA_HDR_LEN + i); 1201 peer_mn = be_to_host32(peer_mi->mn); 1202 1203 /* it is myself */ 1204 if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) { 1205 /* My message id is used by other participant */ 1206 if (peer_mn > participant->mn && 1207 !reset_participant_mi(participant)) 1208 wpa_printf(MSG_DEBUG, "KaY: Could not update MI"); 1209 continue; 1210 } 1211 } 1212 1213 return 0; 1214 } 1215 1216 1217 /** 1218 * ieee802_1x_mka_sak_use_body_present 1219 */ 1220 static bool 1221 ieee802_1x_mka_sak_use_body_present( 1222 struct ieee802_1x_mka_participant *participant) 1223 { 1224 return participant->to_use_sak; 1225 } 1226 1227 1228 /** 1229 * ieee802_1x_mka_get_sak_use_length 1230 */ 1231 static int 1232 ieee802_1x_mka_get_sak_use_length( 1233 struct ieee802_1x_mka_participant *participant) 1234 { 1235 int length = MKA_HDR_LEN; 1236 1237 if (participant->kay->macsec_desired && participant->advised_desired) 1238 length = sizeof(struct ieee802_1x_mka_sak_use_body); 1239 1240 return MKA_ALIGN_LENGTH(length); 1241 } 1242 1243 1244 /** 1245 * ieee802_1x_mka_get_lpn 1246 */ 1247 static u32 1248 ieee802_1x_mka_get_lpn(struct ieee802_1x_mka_participant *principal, 1249 struct ieee802_1x_mka_ki *ki) 1250 { 1251 struct transmit_sa *txsa; 1252 u32 lpn = 0; 1253 1254 dl_list_for_each(txsa, &principal->txsc->sa_list, 1255 struct transmit_sa, list) { 1256 if (is_ki_equal(&txsa->pkey->key_identifier, ki)) { 1257 /* Per IEEE Std 802.1X-2010, Clause 9, "Each SecY uses 1258 * MKA to communicate the lowest PN used for 1259 * transmission with the SAK within the last two 1260 * seconds". Achieve this 2 second delay by setting the 1261 * lpn using the transmit next PN (i.e., txsa->next_pn) 1262 * that was read last time here (i.e., mka_hello_time 1263 * 2 seconds ago). 1264 * 1265 * The lowest acceptable PN is the same as the last 1266 * transmitted PN, which is one less than the next 1267 * transmit PN. 1268 * 1269 * NOTE: This method only works if mka_hello_time is 2s. 1270 */ 1271 lpn = (txsa->next_pn > 0) ? (txsa->next_pn - 1) : 0; 1272 1273 /* Now read the current transmit next PN for use next 1274 * time through. */ 1275 secy_get_transmit_next_pn(principal->kay, txsa); 1276 break; 1277 } 1278 } 1279 1280 if (lpn == 0) 1281 lpn = 1; 1282 1283 return lpn; 1284 } 1285 1286 1287 /** 1288 * ieee802_1x_mka_encode_sak_use_body - 1289 */ 1290 static int 1291 ieee802_1x_mka_encode_sak_use_body( 1292 struct ieee802_1x_mka_participant *participant, 1293 struct wpabuf *buf) 1294 { 1295 struct ieee802_1x_mka_sak_use_body *body; 1296 struct ieee802_1x_kay *kay = participant->kay; 1297 unsigned int length; 1298 u32 olpn, llpn; 1299 1300 length = ieee802_1x_mka_get_sak_use_length(participant); 1301 body = wpabuf_put(buf, length); 1302 1303 body->type = MKA_SAK_USE; 1304 set_mka_param_body_len(body, length - MKA_HDR_LEN); 1305 1306 if (length == MKA_HDR_LEN) { 1307 body->ptx = true; 1308 body->prx = true; 1309 body->lan = 0; 1310 body->lrx = false; 1311 body->ltx = false; 1312 body->delay_protect = false; 1313 return 0; 1314 } 1315 1316 /* data delay protect */ 1317 body->delay_protect = kay->mka_hello_time <= MKA_BOUNDED_HELLO_TIME; 1318 /* lowest accept packet numbers */ 1319 olpn = ieee802_1x_mka_get_lpn(participant, &participant->oki); 1320 body->olpn = host_to_be32(olpn); 1321 llpn = ieee802_1x_mka_get_lpn(participant, &participant->lki); 1322 body->llpn = host_to_be32(llpn); 1323 if (participant->is_key_server) { 1324 /* The CP will spend most of it's time in RETIRE where only 1325 * the old key is populated. Therefore we should be checking 1326 * the OLPN most of the time. 1327 */ 1328 if (participant->lrx) { 1329 if (llpn > kay->pn_exhaustion) { 1330 wpa_printf(MSG_WARNING, 1331 "KaY: My LLPN exhaustion"); 1332 participant->new_sak = true; 1333 } 1334 } else { 1335 if (olpn > kay->pn_exhaustion) { 1336 wpa_printf(MSG_WARNING, 1337 "KaY: My OLPN exhaustion"); 1338 participant->new_sak = true; 1339 } 1340 } 1341 } 1342 1343 /* plain tx, plain rx */ 1344 body->ptx = !kay->macsec_protect; 1345 body->prx = kay->macsec_validate != Strict; 1346 1347 /* latest key: rx, tx, key server member identifier key number */ 1348 body->lan = participant->lan; 1349 os_memcpy(body->lsrv_mi, participant->lki.mi, sizeof(body->lsrv_mi)); 1350 body->lkn = host_to_be32(participant->lki.kn); 1351 body->lrx = participant->lrx; 1352 body->ltx = participant->ltx; 1353 1354 /* old key: rx, tx, key server member identifier key number */ 1355 body->oan = participant->oan; 1356 if (participant->oki.kn != participant->lki.kn && 1357 participant->oki.kn != 0) { 1358 body->otx = true; 1359 body->orx = true; 1360 os_memcpy(body->osrv_mi, participant->oki.mi, 1361 sizeof(body->osrv_mi)); 1362 body->okn = host_to_be32(participant->oki.kn); 1363 } else { 1364 body->otx = false; 1365 body->orx = false; 1366 } 1367 1368 /* set CP's variable */ 1369 if (body->ltx) { 1370 kay->tx_enable = true; 1371 kay->port_enable = true; 1372 } 1373 if (body->lrx) 1374 kay->rx_enable = true; 1375 1376 ieee802_1x_mka_dump_sak_use_body(body); 1377 return 0; 1378 } 1379 1380 1381 /** 1382 * ieee802_1x_mka_decode_sak_use_body - 1383 */ 1384 static int 1385 ieee802_1x_mka_decode_sak_use_body( 1386 struct ieee802_1x_mka_participant *participant, 1387 const u8 *mka_msg, size_t msg_len) 1388 { 1389 struct ieee802_1x_mka_hdr *hdr; 1390 struct ieee802_1x_mka_sak_use_body *body; 1391 struct ieee802_1x_kay_peer *peer; 1392 struct data_key *sa_key = NULL; 1393 size_t body_len; 1394 struct ieee802_1x_mka_ki ki; 1395 u32 lpn; 1396 struct ieee802_1x_kay *kay = participant->kay; 1397 u32 olpn, llpn; 1398 1399 if (!participant->principal) { 1400 wpa_printf(MSG_WARNING, "KaY: Participant is not principal"); 1401 return -1; 1402 } 1403 peer = ieee802_1x_kay_get_live_peer(participant, 1404 participant->current_peer_id.mi); 1405 if (!peer) { 1406 wpa_printf(MSG_WARNING, 1407 "KaY: The peer (%s) is not my live peer - ignore MACsec SAK Use parameter set", 1408 mi_txt(participant->current_peer_id.mi)); 1409 return -1; 1410 } 1411 1412 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1413 body_len = get_mka_param_body_len(hdr); 1414 body = (struct ieee802_1x_mka_sak_use_body *) mka_msg; 1415 ieee802_1x_mka_dump_sak_use_body(body); 1416 1417 if ((body_len != 0) && (body_len < 40)) { 1418 wpa_printf(MSG_ERROR, 1419 "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 0, 40, or more octets", 1420 body_len); 1421 return -1; 1422 } 1423 1424 /* TODO: what action should I take when peer does not support MACsec */ 1425 if (body_len == 0) { 1426 wpa_printf(MSG_WARNING, "KaY: Peer does not support MACsec"); 1427 return 0; 1428 } 1429 1430 /* TODO: when the plain tx or rx of peer is true, should I change 1431 * the attribute of controlled port 1432 */ 1433 if (body->prx) 1434 wpa_printf(MSG_WARNING, "KaY: peer's plain rx are TRUE"); 1435 1436 if (body->ptx) 1437 wpa_printf(MSG_WARNING, "KaY: peer's plain tx are TRUE"); 1438 /* TODO: how to set the MACsec hardware when delay_protect is true */ 1439 if (body->delay_protect && 1440 (!be_to_host32(body->llpn) || !be_to_host32(body->olpn))) { 1441 wpa_printf(MSG_WARNING, 1442 "KaY: Lowest packet number should be greater than 0 when delay_protect is TRUE"); 1443 return -1; 1444 } 1445 1446 olpn = be_to_host32(body->olpn); 1447 llpn = be_to_host32(body->llpn); 1448 1449 /* Our most recent distributed key should be the first in the list. 1450 * If it doesn't exist then we can't really do anything. 1451 * Be lenient and don't return error here as there are legitimate cases 1452 * where this can happen such as when a new participant joins the CA and 1453 * the first frame it receives can have a SAKuse but not distSAK. 1454 */ 1455 sa_key = dl_list_first(&participant->sak_list, struct data_key, list); 1456 if (!sa_key) { 1457 wpa_printf(MSG_INFO, 1458 "KaY: We don't have a latest distributed key - ignore SAK use"); 1459 return 0; 1460 } 1461 1462 /* The peer's most recent key will be the "latest key" if it is present 1463 * otherwise it will be the "old key" if in the RETIRE state. 1464 */ 1465 if (body->lrx) { 1466 os_memcpy(ki.mi, body->lsrv_mi, sizeof(ki.mi)); 1467 ki.kn = be_to_host32(body->lkn); 1468 lpn = llpn; 1469 } else { 1470 os_memcpy(ki.mi, body->osrv_mi, sizeof(ki.mi)); 1471 ki.kn = be_to_host32(body->okn); 1472 lpn = olpn; 1473 } 1474 1475 /* If the most recent distributed keys don't agree then someone is out 1476 * of sync. Perhaps non key server hasn't processed the most recent 1477 * distSAK yet and the key server is processing an old packet after it 1478 * has done distSAK. Be lenient and don't return error in this 1479 * particular case; otherwise, the key server will reset its MI and 1480 * cause a traffic disruption which is really undesired for a simple 1481 * timing issue. 1482 */ 1483 if (!is_ki_equal(&sa_key->key_identifier, &ki)) { 1484 wpa_printf(MSG_INFO, 1485 "KaY: Distributed keys don't match - ignore SAK use"); 1486 return 0; 1487 } 1488 sa_key->next_pn = lpn; 1489 1490 /* The key server must check that all peers are using the most recent 1491 * distributed key. Non key servers must check if the key server is 1492 * transmitting. 1493 */ 1494 if (participant->is_key_server) { 1495 struct ieee802_1x_kay_peer *peer_iter; 1496 bool all_receiving = true; 1497 1498 /* Distributed keys are equal from above comparison. */ 1499 peer->sak_used = true; 1500 1501 dl_list_for_each(peer_iter, &participant->live_peers, 1502 struct ieee802_1x_kay_peer, list) { 1503 if (!peer_iter->sak_used) { 1504 all_receiving = false; 1505 break; 1506 } 1507 } 1508 if (all_receiving) { 1509 participant->to_dist_sak = false; 1510 ieee802_1x_cp_set_allreceiving(kay->cp, true); 1511 ieee802_1x_cp_sm_step(kay->cp); 1512 } 1513 } else if (peer->is_key_server) { 1514 if (body->ltx) { 1515 ieee802_1x_cp_set_servertransmitting(kay->cp, true); 1516 ieee802_1x_cp_sm_step(kay->cp); 1517 } 1518 } 1519 1520 /* If I'm key server, and detects peer member PN exhaustion, rekey. 1521 * We only need to check the PN of the most recent distributed key. This 1522 * could be the peer's "latest" or "old" key depending on its current 1523 * state. If both "old" and "latest" keys are present then the "old" key 1524 * has already been exhausted. 1525 */ 1526 if (participant->is_key_server && lpn > kay->pn_exhaustion) { 1527 participant->new_sak = true; 1528 wpa_printf(MSG_WARNING, "KaY: Peer LPN exhaustion"); 1529 } 1530 1531 /* Get the associated RX SAs of the keys for delay protection since both 1532 * can be in use. Delay protect window (communicated via MKA) is tighter 1533 * than SecY's current replay protect window, so tell SecY the new (and 1534 * higher) lpn. 1535 */ 1536 if (body->delay_protect) { 1537 struct receive_sc *rxsc; 1538 struct receive_sa *rxsa; 1539 bool found = false; 1540 1541 dl_list_for_each(rxsc, &participant->rxsc_list, 1542 struct receive_sc, list) { 1543 dl_list_for_each(rxsa, &rxsc->sa_list, 1544 struct receive_sa, list) { 1545 if (sa_key && rxsa->pkey == sa_key) { 1546 found = true; 1547 break; 1548 } 1549 } 1550 if (found) 1551 break; 1552 } 1553 if (found) { 1554 secy_get_receive_lowest_pn(participant->kay, rxsa); 1555 if (lpn > rxsa->lowest_pn) { 1556 rxsa->lowest_pn = lpn; 1557 secy_set_receive_lowest_pn(participant->kay, 1558 rxsa); 1559 wpa_printf(MSG_DEBUG, 1560 "KaY: update dist LPN=0x%x", lpn); 1561 } 1562 } 1563 1564 /* FIX: Delay protection for the SA being replaced is not 1565 * implemented. Note that this key will be active for at least 1566 * MKA_SAK_RETIRE_TIME (3 seconds) but could be longer depending 1567 * on how long it takes to get from RECEIVE to TRANSMITTING or 1568 * if going via ABANDON. Delay protection does allow PNs within 1569 * a 2 second window, so getting PN would be a lot of work for 1570 * just 1 second's worth of protection. 1571 */ 1572 } 1573 1574 return 0; 1575 } 1576 1577 1578 /** 1579 * ieee802_1x_mka_dist_sak_body_present 1580 */ 1581 static bool 1582 ieee802_1x_mka_dist_sak_body_present( 1583 struct ieee802_1x_mka_participant *participant) 1584 { 1585 return participant->is_key_server && participant->to_dist_sak && 1586 participant->new_key; 1587 } 1588 1589 1590 /** 1591 * ieee802_1x_kay_get_dist_sak_length 1592 */ 1593 static int 1594 ieee802_1x_mka_get_dist_sak_length( 1595 struct ieee802_1x_mka_participant *participant) 1596 { 1597 int length = MKA_HDR_LEN; 1598 unsigned int cs_index = participant->kay->macsec_csindex; 1599 1600 if (participant->advised_desired && cs_index < CS_TABLE_SIZE) { 1601 length = sizeof(struct ieee802_1x_mka_dist_sak_body); 1602 if (cs_index != DEFAULT_CS_INDEX) 1603 length += CS_ID_LEN; 1604 1605 length += cipher_suite_tbl[cs_index].sak_len + 8; 1606 } 1607 1608 return MKA_ALIGN_LENGTH(length); 1609 } 1610 1611 1612 /** 1613 * ieee802_1x_mka_encode_dist_sak_body - 1614 */ 1615 static int 1616 ieee802_1x_mka_encode_dist_sak_body( 1617 struct ieee802_1x_mka_participant *participant, 1618 struct wpabuf *buf) 1619 { 1620 struct ieee802_1x_mka_dist_sak_body *body; 1621 struct data_key *sak; 1622 unsigned int length; 1623 unsigned int cs_index; 1624 int sak_pos; 1625 1626 length = ieee802_1x_mka_get_dist_sak_length(participant); 1627 body = wpabuf_put(buf, length); 1628 body->type = MKA_DISTRIBUTED_SAK; 1629 set_mka_param_body_len(body, length - MKA_HDR_LEN); 1630 if (length == MKA_HDR_LEN) { 1631 body->confid_offset = 0; 1632 body->dan = 0; 1633 return 0; 1634 } 1635 1636 sak = participant->new_key; 1637 if (!sak) { 1638 wpa_printf(MSG_DEBUG, 1639 "KaY: No SAK available to build Distributed SAK parameter set"); 1640 return -1; 1641 } 1642 body->confid_offset = sak->confidentiality_offset; 1643 body->dan = sak->an; 1644 body->kn = host_to_be32(sak->key_identifier.kn); 1645 cs_index = participant->kay->macsec_csindex; 1646 sak_pos = 0; 1647 if (cs_index >= CS_TABLE_SIZE) 1648 return -1; 1649 if (cs_index != DEFAULT_CS_INDEX) { 1650 be64 cs; 1651 1652 cs = host_to_be64(cipher_suite_tbl[cs_index].id); 1653 os_memcpy(body->sak, &cs, CS_ID_LEN); 1654 sak_pos = CS_ID_LEN; 1655 } 1656 if (aes_wrap(participant->kek.key, participant->kek.len, 1657 cipher_suite_tbl[cs_index].sak_len / 8, 1658 sak->key, body->sak + sak_pos)) { 1659 wpa_printf(MSG_ERROR, "KaY: AES wrap failed"); 1660 return -1; 1661 } 1662 1663 ieee802_1x_mka_dump_dist_sak_body(body); 1664 1665 return 0; 1666 } 1667 1668 1669 /** 1670 * ieee802_1x_kay_init_data_key - 1671 */ 1672 static void ieee802_1x_kay_init_data_key(struct data_key *pkey) 1673 { 1674 pkey->transmits = true; 1675 pkey->receives = true; 1676 os_get_time(&pkey->created_time); 1677 1678 pkey->next_pn = 1; 1679 pkey->user = 1; 1680 } 1681 1682 1683 /** 1684 * ieee802_1x_kay_decode_dist_sak_body - 1685 */ 1686 static int 1687 ieee802_1x_mka_decode_dist_sak_body( 1688 struct ieee802_1x_mka_participant *participant, 1689 const u8 *mka_msg, size_t msg_len) 1690 { 1691 struct ieee802_1x_mka_hdr *hdr; 1692 struct ieee802_1x_mka_dist_sak_body *body; 1693 struct ieee802_1x_kay_peer *peer; 1694 struct macsec_ciphersuite *cs; 1695 size_t body_len; 1696 struct data_key *sa_key = NULL; 1697 int sak_len; 1698 u8 *wrap_sak; 1699 u8 *unwrap_sak; 1700 struct ieee802_1x_kay *kay = participant->kay; 1701 1702 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1703 body_len = get_mka_param_body_len(hdr); 1704 if ((body_len != 0) && (body_len != 28) && (body_len < 36)) { 1705 wpa_printf(MSG_ERROR, 1706 "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 0, 28, 36, or more octets", 1707 body_len); 1708 return -1; 1709 } 1710 1711 if (!participant->principal) { 1712 wpa_printf(MSG_ERROR, 1713 "KaY: I can't accept the distributed SAK as I am not principal"); 1714 return -1; 1715 } 1716 if (participant->is_key_server) { 1717 wpa_printf(MSG_ERROR, 1718 "KaY: Reject distributed SAK since I'm a key server"); 1719 return -1; 1720 } 1721 if (!kay->macsec_desired || 1722 kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { 1723 wpa_printf(MSG_ERROR, 1724 "KaY: I am not MACsec-desired or without MACsec capable"); 1725 return -1; 1726 } 1727 1728 peer = ieee802_1x_kay_get_live_peer(participant, 1729 participant->current_peer_id.mi); 1730 if (!peer) { 1731 wpa_printf(MSG_ERROR, 1732 "KaY: The key server is not in my live peers list"); 1733 return -1; 1734 } 1735 if (!sci_equal(&kay->key_server_sci, &peer->sci)) { 1736 wpa_printf(MSG_ERROR, "KaY: The key server is not elected"); 1737 return -1; 1738 } 1739 1740 if (body_len == 0) { 1741 kay->authenticated = true; 1742 kay->secured = false; 1743 kay->failed = false; 1744 participant->advised_desired = false; 1745 ieee802_1x_cp_connect_authenticated(kay->cp); 1746 ieee802_1x_cp_sm_step(kay->cp); 1747 wpa_printf(MSG_WARNING, "KaY: The Key server advise no MACsec"); 1748 participant->to_use_sak = false; 1749 return 0; 1750 } 1751 1752 participant->advised_desired = true; 1753 kay->authenticated = false; 1754 kay->secured = true; 1755 kay->failed = false; 1756 ieee802_1x_cp_connect_secure(kay->cp); 1757 ieee802_1x_cp_sm_step(kay->cp); 1758 1759 body = (struct ieee802_1x_mka_dist_sak_body *)mka_msg; 1760 ieee802_1x_mka_dump_dist_sak_body(body); 1761 dl_list_for_each(sa_key, &participant->sak_list, struct data_key, list) 1762 { 1763 if (os_memcmp(sa_key->key_identifier.mi, 1764 participant->current_peer_id.mi, MI_LEN) == 0 && 1765 sa_key->key_identifier.kn == be_to_host32(body->kn)) { 1766 wpa_printf(MSG_DEBUG, 1767 "KaY: SAK has already been installed - do not set it again"); 1768 return 0; 1769 } 1770 } 1771 1772 if (body_len == 28) { 1773 sak_len = DEFAULT_SA_KEY_LEN; 1774 wrap_sak = body->sak; 1775 kay->macsec_csindex = DEFAULT_CS_INDEX; 1776 cs = &cipher_suite_tbl[kay->macsec_csindex]; 1777 } else { 1778 unsigned int idx; 1779 1780 cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak, 1781 &idx); 1782 if (!cs) { 1783 wpa_printf(MSG_ERROR, 1784 "KaY: I can't support the Cipher Suite advised by key server"); 1785 return -1; 1786 } 1787 sak_len = cs->sak_len; 1788 wrap_sak = body->sak + CS_ID_LEN; 1789 kay->macsec_csindex = idx; 1790 } 1791 1792 unwrap_sak = os_zalloc(sak_len); 1793 if (!unwrap_sak) { 1794 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 1795 return -1; 1796 } 1797 if (aes_unwrap(participant->kek.key, participant->kek.len, 1798 sak_len >> 3, wrap_sak, unwrap_sak)) { 1799 wpa_printf(MSG_ERROR, "KaY: AES unwrap failed"); 1800 os_free(unwrap_sak); 1801 return -1; 1802 } 1803 wpa_hexdump_key(MSG_DEBUG, "\tAES Key Unwrap of SAK.:", 1804 unwrap_sak, sak_len); 1805 1806 sa_key = os_zalloc(sizeof(*sa_key)); 1807 if (!sa_key) { 1808 os_free(unwrap_sak); 1809 return -1; 1810 } 1811 1812 os_memcpy(&sa_key->key_identifier.mi, &participant->current_peer_id.mi, 1813 MI_LEN); 1814 sa_key->key_identifier.kn = be_to_host32(body->kn); 1815 1816 sa_key->key = unwrap_sak; 1817 sa_key->key_len = sak_len; 1818 1819 sa_key->confidentiality_offset = body->confid_offset; 1820 sa_key->an = body->dan; 1821 ieee802_1x_kay_init_data_key(sa_key); 1822 1823 ieee802_1x_kay_use_data_key(sa_key); 1824 dl_list_add(&participant->sak_list, &sa_key->list); 1825 1826 ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id); 1827 ieee802_1x_cp_sm_step(kay->cp); 1828 ieee802_1x_cp_set_offset(kay->cp, body->confid_offset); 1829 ieee802_1x_cp_sm_step(kay->cp); 1830 ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier); 1831 ieee802_1x_cp_set_distributedan(kay->cp, body->dan); 1832 ieee802_1x_cp_signal_newsak(kay->cp); 1833 ieee802_1x_cp_sm_step(kay->cp); 1834 1835 kay->rcvd_keys++; 1836 participant->to_use_sak = true; 1837 1838 /* 1839 * The key server may not include dist sak and use sak in one packet. 1840 * Meanwhile, after dist sak, the current participant (non-key server) 1841 * will install SC or SA(s) after decoding the dist sak which may take 1842 * few seconds in real physical platforms. Meanwhile, the peer expire 1843 * time is always initialized at adding the key server to peer list. 1844 * The gap between adding the key server to peer list and processing 1845 * next use sak packet may exceed the threshold of MKA_LIFE_TIME (6 s). 1846 * It will cause an unexpected cleanup (delete SC and SA(s)), so, 1847 * update the expire timeout at dist sak also. */ 1848 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 1849 1850 return 0; 1851 } 1852 1853 1854 /** 1855 * ieee802_1x_mka_icv_body_present 1856 */ 1857 static bool 1858 ieee802_1x_mka_icv_body_present(struct ieee802_1x_mka_participant *participant) 1859 { 1860 return true; 1861 } 1862 1863 1864 /** 1865 * ieee802_1x_kay_get_icv_length 1866 */ 1867 static int 1868 ieee802_1x_mka_get_icv_length(struct ieee802_1x_mka_participant *participant) 1869 { 1870 int length; 1871 1872 /* Determine if we need space for the ICV Indicator */ 1873 if (mka_alg_tbl[participant->kay->mka_algindex].icv_len != 1874 DEFAULT_ICV_LEN) 1875 length = sizeof(struct ieee802_1x_mka_icv_body); 1876 else 1877 length = 0; 1878 length += mka_alg_tbl[participant->kay->mka_algindex].icv_len; 1879 1880 return MKA_ALIGN_LENGTH(length); 1881 } 1882 1883 1884 /** 1885 * ieee802_1x_mka_encode_icv_body - 1886 */ 1887 static int 1888 ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant, 1889 struct wpabuf *buf) 1890 { 1891 struct ieee802_1x_mka_icv_body *body; 1892 unsigned int length; 1893 u8 cmac[MAX_ICV_LEN]; 1894 1895 length = ieee802_1x_mka_get_icv_length(participant); 1896 if (mka_alg_tbl[participant->kay->mka_algindex].icv_len != 1897 DEFAULT_ICV_LEN) { 1898 wpa_printf(MSG_DEBUG, "KaY: ICV Indicator"); 1899 body = wpabuf_put(buf, MKA_HDR_LEN); 1900 body->type = MKA_ICV_INDICATOR; 1901 length -= MKA_HDR_LEN; 1902 set_mka_param_body_len(body, length); 1903 } 1904 1905 if (mka_alg_tbl[participant->kay->mka_algindex].icv_hash( 1906 participant->ick.key, participant->ick.len, 1907 wpabuf_head(buf), wpabuf_len(buf), cmac)) { 1908 wpa_printf(MSG_ERROR, "KaY: failed to calculate ICV"); 1909 return -1; 1910 } 1911 wpa_hexdump(MSG_DEBUG, "KaY: ICV", cmac, length); 1912 1913 os_memcpy(wpabuf_put(buf, length), cmac, length); 1914 1915 return 0; 1916 } 1917 1918 /** 1919 * ieee802_1x_mka_decode_icv_body - 1920 */ 1921 static const u8 * 1922 ieee802_1x_mka_decode_icv_body(struct ieee802_1x_mka_participant *participant, 1923 const u8 *mka_msg, size_t msg_len) 1924 { 1925 const struct ieee802_1x_mka_hdr *hdr; 1926 const struct ieee802_1x_mka_icv_body *body; 1927 size_t body_len; 1928 size_t left_len; 1929 u8 body_type; 1930 const u8 *pos; 1931 1932 pos = mka_msg; 1933 left_len = msg_len; 1934 while (left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN) { 1935 hdr = (const struct ieee802_1x_mka_hdr *) pos; 1936 body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr)); 1937 body_type = get_mka_param_body_type(hdr); 1938 1939 if (left_len < body_len + MKA_HDR_LEN) 1940 break; 1941 1942 if (body_type != MKA_ICV_INDICATOR) { 1943 left_len -= MKA_HDR_LEN + body_len; 1944 pos += MKA_HDR_LEN + body_len; 1945 continue; 1946 } 1947 1948 body = (const struct ieee802_1x_mka_icv_body *) pos; 1949 if (body_len 1950 < mka_alg_tbl[participant->kay->mka_algindex].icv_len) 1951 return NULL; 1952 1953 return body->icv; 1954 } 1955 1956 return mka_msg + msg_len - DEFAULT_ICV_LEN; 1957 } 1958 1959 1960 /** 1961 * ieee802_1x_mka_decode_dist_cak_body- 1962 */ 1963 static int 1964 ieee802_1x_mka_decode_dist_cak_body( 1965 struct ieee802_1x_mka_participant *participant, 1966 const u8 *mka_msg, size_t msg_len) 1967 { 1968 struct ieee802_1x_mka_hdr *hdr; 1969 size_t body_len; 1970 1971 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1972 body_len = get_mka_param_body_len(hdr); 1973 if (body_len < 28) { 1974 wpa_printf(MSG_ERROR, 1975 "KaY: MKA Use CAK Packet Body Length (%zu bytes) should be 28 or more octets", 1976 body_len); 1977 return -1; 1978 } 1979 1980 return 0; 1981 } 1982 1983 1984 /** 1985 * ieee802_1x_mka_decode_kmd_body - 1986 */ 1987 static int 1988 ieee802_1x_mka_decode_kmd_body( 1989 struct ieee802_1x_mka_participant *participant, 1990 const u8 *mka_msg, size_t msg_len) 1991 { 1992 struct ieee802_1x_mka_hdr *hdr; 1993 size_t body_len; 1994 1995 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1996 body_len = get_mka_param_body_len(hdr); 1997 if (body_len < 5) { 1998 wpa_printf(MSG_ERROR, 1999 "KaY: MKA Use KMD Packet Body Length (%zu bytes) should be 5 or more octets", 2000 body_len); 2001 return -1; 2002 } 2003 2004 return 0; 2005 } 2006 2007 2008 /** 2009 * ieee802_1x_mka_decode_announce_body - 2010 */ 2011 static int ieee802_1x_mka_decode_announce_body( 2012 struct ieee802_1x_mka_participant *participant, 2013 const u8 *mka_msg, size_t msg_len) 2014 { 2015 return 0; 2016 } 2017 2018 2019 struct mka_param_body_handler { 2020 int (*body_tx)(struct ieee802_1x_mka_participant *participant, 2021 struct wpabuf *buf); 2022 int (*body_rx)(struct ieee802_1x_mka_participant *participant, 2023 const u8 *mka_msg, size_t msg_len); 2024 int (*body_length)(struct ieee802_1x_mka_participant *participant); 2025 bool (*body_present)(struct ieee802_1x_mka_participant *participant); 2026 }; 2027 2028 2029 static struct mka_param_body_handler mka_body_handler[] = { 2030 /* Basic parameter set */ 2031 { 2032 .body_tx = ieee802_1x_mka_encode_basic_body, 2033 .body_rx = NULL, 2034 .body_length = ieee802_1x_mka_basic_body_length, 2035 .body_present = ieee802_1x_mka_basic_body_present 2036 }, 2037 2038 /* Live Peer List parameter set */ 2039 { 2040 .body_tx = ieee802_1x_mka_encode_live_peer_body, 2041 .body_rx = ieee802_1x_mka_decode_live_peer_body, 2042 .body_length = ieee802_1x_mka_get_live_peer_length, 2043 .body_present = ieee802_1x_mka_live_peer_body_present 2044 }, 2045 2046 /* Potential Peer List parameter set */ 2047 { 2048 .body_tx = ieee802_1x_mka_encode_potential_peer_body, 2049 .body_rx = ieee802_1x_mka_decode_potential_peer_body, 2050 .body_length = ieee802_1x_mka_get_potential_peer_length, 2051 .body_present = ieee802_1x_mka_potential_peer_body_present 2052 }, 2053 2054 /* MACsec SAK Use parameter set */ 2055 { 2056 .body_tx = ieee802_1x_mka_encode_sak_use_body, 2057 .body_rx = ieee802_1x_mka_decode_sak_use_body, 2058 .body_length = ieee802_1x_mka_get_sak_use_length, 2059 .body_present = ieee802_1x_mka_sak_use_body_present 2060 }, 2061 2062 /* Distributed SAK parameter set */ 2063 { 2064 .body_tx = ieee802_1x_mka_encode_dist_sak_body, 2065 .body_rx = ieee802_1x_mka_decode_dist_sak_body, 2066 .body_length = ieee802_1x_mka_get_dist_sak_length, 2067 .body_present = ieee802_1x_mka_dist_sak_body_present 2068 }, 2069 2070 /* Distribute CAK parameter set */ 2071 { 2072 .body_tx = NULL, 2073 .body_rx = ieee802_1x_mka_decode_dist_cak_body, 2074 .body_length = NULL, 2075 .body_present = NULL 2076 }, 2077 2078 /* KMD parameter set */ 2079 { 2080 .body_tx = NULL, 2081 .body_rx = ieee802_1x_mka_decode_kmd_body, 2082 .body_length = NULL, 2083 .body_present = NULL 2084 }, 2085 2086 /* Announcement parameter set */ 2087 { 2088 .body_tx = NULL, 2089 .body_rx = ieee802_1x_mka_decode_announce_body, 2090 .body_length = NULL, 2091 .body_present = NULL 2092 }, 2093 2094 /* ICV Indicator parameter set */ 2095 { 2096 .body_tx = ieee802_1x_mka_encode_icv_body, 2097 .body_rx = NULL, 2098 .body_length = ieee802_1x_mka_get_icv_length, 2099 .body_present = ieee802_1x_mka_icv_body_present 2100 }, 2101 }; 2102 2103 2104 /** 2105 * ieee802_1x_kay_use_data_key - Take reference on a key 2106 */ 2107 static void ieee802_1x_kay_use_data_key(struct data_key *pkey) 2108 { 2109 pkey->user++; 2110 } 2111 2112 2113 /** 2114 * ieee802_1x_kay_deinit_data_key - Release reference on a key and 2115 * free if there are no remaining users 2116 */ 2117 static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey) 2118 { 2119 if (!pkey) 2120 return; 2121 2122 pkey->user--; 2123 if (pkey->user > 1) 2124 return; 2125 2126 os_free(pkey->key); 2127 os_free(pkey); 2128 } 2129 2130 2131 /** 2132 * ieee802_1x_kay_generate_new_sak - 2133 */ 2134 static int 2135 ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant) 2136 { 2137 struct data_key *sa_key = NULL; 2138 struct ieee802_1x_kay_peer *peer; 2139 struct ieee802_1x_kay *kay = participant->kay; 2140 int ctx_len, ctx_offset; 2141 u8 *context; 2142 unsigned int key_len; 2143 u8 *key; 2144 struct macsec_ciphersuite *cs; 2145 2146 /* check condition for generating a fresh SAK: 2147 * must have one live peer 2148 * and MKA life time elapse since last distribution 2149 * or potential peer is empty 2150 */ 2151 if (dl_list_empty(&participant->live_peers)) { 2152 wpa_printf(MSG_ERROR, 2153 "KaY: Live peers list must not be empty when generating fresh SAK"); 2154 return -1; 2155 } 2156 2157 /* FIXME: A fresh SAK not generated until 2158 * the live peer list contains at least one peer and 2159 * MKA life time has elapsed since the prior SAK was first distributed, 2160 * or the Key server's potential peer is empty 2161 * but I can't understand the second item, so 2162 * here only check first item and ingore 2163 * && (!dl_list_empty(&participant->potential_peers))) { 2164 */ 2165 if ((time(NULL) - kay->dist_time) < MKA_LIFE_TIME / 1000) { 2166 wpa_printf(MSG_ERROR, 2167 "KaY: Life time has not elapsed since prior SAK distributed"); 2168 return -1; 2169 } 2170 2171 cs = &cipher_suite_tbl[kay->macsec_csindex]; 2172 key_len = cs->sak_len; 2173 key = os_zalloc(key_len); 2174 if (!key) { 2175 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 2176 return -1; 2177 } 2178 2179 ctx_len = key_len + sizeof(kay->dist_kn); 2180 dl_list_for_each(peer, &participant->live_peers, 2181 struct ieee802_1x_kay_peer, list) 2182 ctx_len += sizeof(peer->mi); 2183 ctx_len += sizeof(participant->mi); 2184 2185 context = os_zalloc(ctx_len); 2186 if (!context) 2187 goto fail; 2188 2189 ctx_offset = 0; 2190 if (os_get_random(context + ctx_offset, key_len) < 0) 2191 goto fail; 2192 2193 ctx_offset += key_len; 2194 dl_list_for_each(peer, &participant->live_peers, 2195 struct ieee802_1x_kay_peer, list) { 2196 os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi)); 2197 ctx_offset += sizeof(peer->mi); 2198 } 2199 os_memcpy(context + ctx_offset, participant->mi, 2200 sizeof(participant->mi)); 2201 ctx_offset += sizeof(participant->mi); 2202 os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn)); 2203 2204 if (key_len == 16 || key_len == 32) { 2205 if (ieee802_1x_sak_aes_cmac(participant->cak.key, 2206 participant->cak.len, 2207 context, ctx_len, 2208 key, key_len)) { 2209 wpa_printf(MSG_ERROR, "KaY: Failed to generate SAK"); 2210 goto fail; 2211 } 2212 } else { 2213 wpa_printf(MSG_ERROR, "KaY: SAK Length(%u) not supported", 2214 key_len); 2215 goto fail; 2216 } 2217 wpa_hexdump_key(MSG_DEBUG, "KaY: generated new SAK", key, key_len); 2218 os_free(context); 2219 context = NULL; 2220 2221 sa_key = os_zalloc(sizeof(*sa_key)); 2222 if (!sa_key) { 2223 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 2224 goto fail; 2225 } 2226 2227 sa_key->key = key; 2228 sa_key->key_len = key_len; 2229 os_memcpy(sa_key->key_identifier.mi, participant->mi, MI_LEN); 2230 sa_key->key_identifier.kn = kay->dist_kn; 2231 2232 sa_key->confidentiality_offset = kay->macsec_confidentiality; 2233 sa_key->an = kay->dist_an; 2234 ieee802_1x_kay_init_data_key(sa_key); 2235 2236 participant->new_key = sa_key; 2237 2238 ieee802_1x_kay_use_data_key(sa_key); 2239 dl_list_add(&participant->sak_list, &sa_key->list); 2240 2241 ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id); 2242 ieee802_1x_cp_sm_step(kay->cp); 2243 ieee802_1x_cp_set_offset(kay->cp, kay->macsec_confidentiality); 2244 ieee802_1x_cp_sm_step(kay->cp); 2245 ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier); 2246 ieee802_1x_cp_set_distributedan(kay->cp, sa_key->an); 2247 ieee802_1x_cp_signal_newsak(kay->cp); 2248 ieee802_1x_cp_sm_step(kay->cp); 2249 2250 dl_list_for_each(peer, &participant->live_peers, 2251 struct ieee802_1x_kay_peer, list) 2252 peer->sak_used = false; 2253 2254 kay->dist_kn++; 2255 kay->dist_an++; 2256 if (kay->dist_an > 3) 2257 kay->dist_an = 0; 2258 2259 kay->dist_time = time(NULL); 2260 2261 return 0; 2262 2263 fail: 2264 os_free(key); 2265 os_free(context); 2266 return -1; 2267 } 2268 2269 2270 static int compare_priorities(const struct ieee802_1x_kay_peer *peer, 2271 const struct ieee802_1x_kay_peer *other) 2272 { 2273 if (peer->key_server_priority < other->key_server_priority) 2274 return -1; 2275 if (other->key_server_priority < peer->key_server_priority) 2276 return 1; 2277 2278 return os_memcmp(peer->sci.addr, other->sci.addr, ETH_ALEN); 2279 } 2280 2281 2282 /** 2283 * ieee802_1x_kay_elect_key_server - elect the key server 2284 * when to elect: whenever the live peers list changes 2285 */ 2286 static int 2287 ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant) 2288 { 2289 struct ieee802_1x_kay_peer *peer; 2290 struct ieee802_1x_kay_peer *key_server = NULL; 2291 struct ieee802_1x_kay *kay = participant->kay; 2292 bool i_is_key_server; 2293 int priority_comparison; 2294 2295 if (participant->is_obliged_key_server) { 2296 participant->new_sak = true; 2297 participant->to_dist_sak = false; 2298 ieee802_1x_cp_set_electedself(kay->cp, true); 2299 return 0; 2300 } 2301 2302 /* elect the key server among the peers */ 2303 dl_list_for_each(peer, &participant->live_peers, 2304 struct ieee802_1x_kay_peer, list) { 2305 if (!peer->is_key_server) 2306 continue; 2307 2308 if (!key_server) { 2309 key_server = peer; 2310 continue; 2311 } 2312 2313 if (compare_priorities(peer, key_server) < 0) 2314 key_server = peer; 2315 } 2316 2317 /* elect the key server between me and the above elected peer */ 2318 i_is_key_server = false; 2319 if (key_server && participant->can_be_key_server) { 2320 struct ieee802_1x_kay_peer tmp; 2321 2322 tmp.key_server_priority = kay->actor_priority; 2323 os_memcpy(&tmp.sci, &kay->actor_sci, sizeof(tmp.sci)); 2324 priority_comparison = compare_priorities(&tmp, key_server); 2325 if (priority_comparison < 0) { 2326 i_is_key_server = true; 2327 } else if (priority_comparison == 0) { 2328 wpa_printf(MSG_WARNING, 2329 "KaY: Cannot elect key server between me and peer, duplicate MAC detected"); 2330 key_server = NULL; 2331 } 2332 } else if (participant->can_be_key_server) { 2333 i_is_key_server = true; 2334 } 2335 2336 if (i_is_key_server) { 2337 ieee802_1x_cp_set_electedself(kay->cp, true); 2338 if (!sci_equal(&kay->key_server_sci, &kay->actor_sci)) { 2339 ieee802_1x_cp_signal_chgdserver(kay->cp); 2340 ieee802_1x_cp_sm_step(kay->cp); 2341 } 2342 2343 participant->is_key_server = true; 2344 participant->principal = true; 2345 participant->new_sak = true; 2346 wpa_printf(MSG_DEBUG, "KaY: I am elected as key server"); 2347 participant->to_dist_sak = false; 2348 participant->is_elected = true; 2349 2350 os_memcpy(&kay->key_server_sci, &kay->actor_sci, 2351 sizeof(kay->key_server_sci)); 2352 kay->key_server_priority = kay->actor_priority; 2353 } else if (key_server) { 2354 wpa_printf(MSG_DEBUG, 2355 "KaY: Peer %s was elected as the key server", 2356 mi_txt(key_server->mi)); 2357 ieee802_1x_cp_set_electedself(kay->cp, false); 2358 if (!sci_equal(&kay->key_server_sci, &key_server->sci)) { 2359 ieee802_1x_cp_signal_chgdserver(kay->cp); 2360 ieee802_1x_cp_sm_step(kay->cp); 2361 } 2362 2363 participant->is_key_server = false; 2364 participant->principal = true; 2365 participant->is_elected = true; 2366 2367 os_memcpy(&kay->key_server_sci, &key_server->sci, 2368 sizeof(kay->key_server_sci)); 2369 kay->key_server_priority = key_server->key_server_priority; 2370 } else { 2371 participant->principal = false; 2372 participant->is_key_server = false; 2373 participant->is_elected = false; 2374 } 2375 2376 return 0; 2377 } 2378 2379 2380 /** 2381 * ieee802_1x_kay_decide_macsec_use - the key server determinate 2382 * how to use MACsec: whether use MACsec and its capability 2383 * protectFrames will be advised if the key server and one of its live peers are 2384 * MACsec capable and one of those request MACsec protection 2385 */ 2386 static int 2387 ieee802_1x_kay_decide_macsec_use( 2388 struct ieee802_1x_mka_participant *participant) 2389 { 2390 struct ieee802_1x_kay *kay = participant->kay; 2391 struct ieee802_1x_kay_peer *peer; 2392 enum macsec_cap less_capability; 2393 bool has_peer; 2394 2395 if (!participant->is_key_server) 2396 return -1; 2397 2398 /* key server self is MACsec-desired and requesting MACsec */ 2399 if (!kay->macsec_desired) { 2400 participant->advised_desired = false; 2401 return -1; 2402 } 2403 if (kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { 2404 participant->advised_desired = false; 2405 return -1; 2406 } 2407 less_capability = kay->macsec_capable; 2408 2409 /* at least one of peers is MACsec-desired and requesting MACsec */ 2410 has_peer = false; 2411 dl_list_for_each(peer, &participant->live_peers, 2412 struct ieee802_1x_kay_peer, list) { 2413 if (!peer->macsec_desired) 2414 continue; 2415 2416 if (peer->macsec_capability == MACSEC_CAP_NOT_IMPLEMENTED) 2417 continue; 2418 2419 less_capability = (less_capability < peer->macsec_capability) ? 2420 less_capability : peer->macsec_capability; 2421 has_peer = true; 2422 } 2423 2424 if (has_peer) { 2425 participant->advised_desired = true; 2426 participant->advised_capability = less_capability; 2427 kay->authenticated = false; 2428 kay->secured = true; 2429 kay->failed = false; 2430 ieee802_1x_cp_connect_secure(kay->cp); 2431 ieee802_1x_cp_sm_step(kay->cp); 2432 } else { 2433 participant->advised_desired = false; 2434 participant->advised_capability = MACSEC_CAP_NOT_IMPLEMENTED; 2435 participant->to_use_sak = false; 2436 kay->authenticated = true; 2437 kay->secured = false; 2438 kay->failed = false; 2439 kay->ltx_kn = 0; 2440 kay->ltx_an = 0; 2441 kay->lrx_kn = 0; 2442 kay->lrx_an = 0; 2443 kay->otx_kn = 0; 2444 kay->otx_an = 0; 2445 kay->orx_kn = 0; 2446 kay->orx_an = 0; 2447 ieee802_1x_cp_connect_authenticated(kay->cp); 2448 ieee802_1x_cp_sm_step(kay->cp); 2449 } 2450 2451 return 0; 2452 } 2453 2454 static const u8 pae_group_addr[ETH_ALEN] = { 2455 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 2456 }; 2457 2458 2459 /** 2460 * ieee802_1x_kay_encode_mkpdu - 2461 */ 2462 static int 2463 ieee802_1x_kay_encode_mkpdu(struct ieee802_1x_mka_participant *participant, 2464 struct wpabuf *pbuf) 2465 { 2466 unsigned int i; 2467 struct ieee8023_hdr *ether_hdr; 2468 struct ieee802_1x_hdr *eapol_hdr; 2469 2470 ether_hdr = wpabuf_put(pbuf, sizeof(*ether_hdr)); 2471 os_memcpy(ether_hdr->dest, pae_group_addr, sizeof(ether_hdr->dest)); 2472 os_memcpy(ether_hdr->src, participant->kay->actor_sci.addr, 2473 sizeof(ether_hdr->dest)); 2474 ether_hdr->ethertype = host_to_be16(ETH_P_EAPOL); 2475 wpa_printf(MSG_DEBUG, "KaY: Ethernet header: DA=" MACSTR " SA=" MACSTR 2476 " Ethertype=0x%x", 2477 MAC2STR(ether_hdr->dest), MAC2STR(ether_hdr->src), 2478 be_to_host16(ether_hdr->ethertype)); 2479 2480 eapol_hdr = wpabuf_put(pbuf, sizeof(*eapol_hdr)); 2481 eapol_hdr->version = EAPOL_VERSION; 2482 eapol_hdr->type = IEEE802_1X_TYPE_EAPOL_MKA; 2483 eapol_hdr->length = host_to_be16(wpabuf_tailroom(pbuf)); 2484 wpa_printf(MSG_DEBUG, 2485 "KaY: Common EAPOL PDU structure: Protocol Version=%u Packet Type=%u Packet Body Length=%u", 2486 eapol_hdr->version, eapol_hdr->type, 2487 be_to_host16(eapol_hdr->length)); 2488 2489 for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) { 2490 if (mka_body_handler[i].body_present && 2491 mka_body_handler[i].body_present(participant)) { 2492 if (mka_body_handler[i].body_tx(participant, pbuf)) 2493 return -1; 2494 } 2495 } 2496 2497 return 0; 2498 } 2499 2500 2501 /** 2502 * ieee802_1x_participant_send_mkpdu - 2503 */ 2504 static int 2505 ieee802_1x_participant_send_mkpdu( 2506 struct ieee802_1x_mka_participant *participant) 2507 { 2508 struct wpabuf *buf; 2509 struct ieee802_1x_kay *kay = participant->kay; 2510 size_t length = 0; 2511 unsigned int i; 2512 2513 wpa_printf(MSG_DEBUG, "KaY: Encode and send an MKPDU (ifname=%s)", 2514 kay->if_name); 2515 length += sizeof(struct ieee802_1x_hdr) + sizeof(struct ieee8023_hdr); 2516 for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) { 2517 if (mka_body_handler[i].body_present && 2518 mka_body_handler[i].body_present(participant)) 2519 length += mka_body_handler[i].body_length(participant); 2520 } 2521 2522 buf = wpabuf_alloc(length); 2523 if (!buf) { 2524 wpa_printf(MSG_ERROR, "KaY: out of memory"); 2525 return -1; 2526 } 2527 2528 if (ieee802_1x_kay_encode_mkpdu(participant, buf)) { 2529 wpa_printf(MSG_ERROR, "KaY: encode MKPDU fail"); 2530 return -1; 2531 } 2532 2533 wpa_hexdump_buf(MSG_MSGDUMP, "KaY: Outgoing MKPDU", buf); 2534 l2_packet_send(kay->l2_mka, NULL, 0, wpabuf_head(buf), wpabuf_len(buf)); 2535 wpabuf_free(buf); 2536 2537 kay->active = true; 2538 participant->active = true; 2539 2540 return 0; 2541 } 2542 2543 2544 static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa); 2545 2546 static void ieee802_1x_delete_transmit_sa(struct ieee802_1x_kay *kay, 2547 struct transmit_sa *sa) 2548 { 2549 secy_disable_transmit_sa(kay, sa); 2550 secy_delete_transmit_sa(kay, sa); 2551 ieee802_1x_kay_deinit_transmit_sa(sa); 2552 } 2553 2554 2555 /** 2556 * ieee802_1x_participant_timer - 2557 */ 2558 static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) 2559 { 2560 struct ieee802_1x_mka_participant *participant; 2561 struct ieee802_1x_kay *kay; 2562 struct ieee802_1x_kay_peer *peer, *pre_peer; 2563 time_t now = time(NULL); 2564 bool lp_changed; 2565 bool key_server_removed; 2566 struct receive_sc *rxsc, *pre_rxsc; 2567 struct transmit_sa *txsa, *pre_txsa; 2568 2569 participant = (struct ieee802_1x_mka_participant *)eloop_ctx; 2570 kay = participant->kay; 2571 wpa_printf(MSG_DEBUG, "KaY: Participant timer (ifname=%s)", 2572 kay->if_name); 2573 if (participant->cak_life) { 2574 if (now > participant->cak_life) 2575 goto delete_mka; 2576 } 2577 2578 /* should delete MKA instance if there are not live peers 2579 * when the MKA life elapsed since its creating */ 2580 if (participant->mka_life) { 2581 if (dl_list_empty(&participant->live_peers)) { 2582 if (now > participant->mka_life) 2583 goto delete_mka; 2584 } else { 2585 participant->mka_life = 0; 2586 } 2587 } 2588 2589 lp_changed = false; 2590 key_server_removed = false; 2591 dl_list_for_each_safe(peer, pre_peer, &participant->live_peers, 2592 struct ieee802_1x_kay_peer, list) { 2593 if (now > peer->expire) { 2594 wpa_printf(MSG_DEBUG, "KaY: Live peer removed"); 2595 ieee802_1x_kay_dump_peer(peer); 2596 dl_list_for_each_safe(rxsc, pre_rxsc, 2597 &participant->rxsc_list, 2598 struct receive_sc, list) { 2599 if (sci_equal(&rxsc->sci, &peer->sci)) { 2600 ieee802_1x_kay_deinit_receive_sc( 2601 participant, rxsc); 2602 } 2603 } 2604 key_server_removed |= peer->is_key_server; 2605 dl_list_del(&peer->list); 2606 os_free(peer); 2607 lp_changed = true; 2608 } 2609 } 2610 2611 /* The key server may be removed due to the ingress packets delay. 2612 * In this situation, the endpoint of the key server may not be aware 2613 * of this participant who has removed the key server from the peer 2614 * list. Because the egress traffic is normal, the key server will not 2615 * remove this participant from the peer list of the key server. So in 2616 * the next MKA message, the key server will not dispatch a new SAK to 2617 * this participant. And this participant cannot be aware that that is 2618 * a new round of communication so it will not update its MI at 2619 * re-adding the key server to its peer list. So we need to update MI 2620 * to avoid the failure of the re-establishment MKA session. */ 2621 if (key_server_removed) { 2622 if (!reset_participant_mi(participant)) 2623 wpa_printf(MSG_WARNING, 2624 "KaY: Could not update MI on key server removal"); 2625 else 2626 wpa_printf(MSG_DEBUG, 2627 "KaY: Update MI on key server removal"); 2628 } 2629 2630 if (lp_changed) { 2631 if (dl_list_empty(&participant->live_peers)) { 2632 participant->advised_desired = false; 2633 participant->advised_capability = 2634 MACSEC_CAP_NOT_IMPLEMENTED; 2635 participant->to_use_sak = false; 2636 participant->ltx = false; 2637 participant->lrx = false; 2638 participant->otx = false; 2639 participant->orx = false; 2640 participant->is_key_server = false; 2641 participant->is_elected = false; 2642 kay->authenticated = false; 2643 kay->secured = false; 2644 kay->failed = false; 2645 kay->ltx_kn = 0; 2646 kay->ltx_an = 0; 2647 kay->lrx_kn = 0; 2648 kay->lrx_an = 0; 2649 kay->otx_kn = 0; 2650 kay->otx_an = 0; 2651 kay->orx_kn = 0; 2652 kay->orx_an = 0; 2653 dl_list_for_each_safe(txsa, pre_txsa, 2654 &participant->txsc->sa_list, 2655 struct transmit_sa, list) { 2656 ieee802_1x_delete_transmit_sa(kay, txsa); 2657 } 2658 2659 ieee802_1x_cp_connect_pending(kay->cp); 2660 ieee802_1x_cp_sm_step(kay->cp); 2661 } else { 2662 ieee802_1x_kay_elect_key_server(participant); 2663 ieee802_1x_kay_decide_macsec_use(participant); 2664 } 2665 } 2666 2667 dl_list_for_each_safe(peer, pre_peer, &participant->potential_peers, 2668 struct ieee802_1x_kay_peer, list) { 2669 if (now > peer->expire) { 2670 wpa_printf(MSG_DEBUG, "KaY: Potential peer removed"); 2671 ieee802_1x_kay_dump_peer(peer); 2672 dl_list_del(&peer->list); 2673 os_free(peer); 2674 } 2675 } 2676 2677 if (participant->new_sak && participant->is_key_server) { 2678 if (!ieee802_1x_kay_generate_new_sak(participant)) 2679 participant->to_dist_sak = true; 2680 2681 participant->new_sak = false; 2682 } 2683 2684 if (participant->retry_count < MAX_RETRY_CNT || 2685 participant->mode == PSK) { 2686 ieee802_1x_participant_send_mkpdu(participant); 2687 participant->retry_count++; 2688 } 2689 2690 eloop_register_timeout(kay->mka_hello_time / 1000, 0, 2691 ieee802_1x_participant_timer, 2692 participant, NULL); 2693 2694 return; 2695 2696 delete_mka: 2697 kay->authenticated = false; 2698 kay->secured = false; 2699 kay->failed = true; 2700 ieee802_1x_kay_delete_mka(kay, &participant->ckn); 2701 } 2702 2703 2704 /** 2705 * ieee802_1x_kay_init_transmit_sa - 2706 */ 2707 static struct transmit_sa * 2708 ieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN, 2709 struct data_key *key) 2710 { 2711 struct transmit_sa *psa; 2712 2713 key->tx_latest = true; 2714 key->rx_latest = true; 2715 2716 psa = os_zalloc(sizeof(*psa)); 2717 if (!psa) { 2718 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 2719 return NULL; 2720 } 2721 2722 if (key->confidentiality_offset >= CONFIDENTIALITY_OFFSET_0 && 2723 key->confidentiality_offset <= CONFIDENTIALITY_OFFSET_50) 2724 psa->confidentiality = true; 2725 else 2726 psa->confidentiality = false; 2727 2728 psa->an = an; 2729 ieee802_1x_kay_use_data_key(key); 2730 psa->pkey = key; 2731 psa->next_pn = next_PN; 2732 psa->sc = psc; 2733 2734 os_get_time(&psa->created_time); 2735 psa->in_use = false; 2736 2737 dl_list_add(&psc->sa_list, &psa->list); 2738 wpa_printf(MSG_DEBUG, 2739 "KaY: Create transmit SA(an: %hhu, next_pn: %u) of SC", 2740 an, next_PN); 2741 2742 return psa; 2743 } 2744 2745 2746 /** 2747 * ieee802_1x_kay_deinit_transmit_sa - 2748 */ 2749 static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa) 2750 { 2751 ieee802_1x_kay_deinit_data_key(psa->pkey); 2752 psa->pkey = NULL; 2753 wpa_printf(MSG_DEBUG, 2754 "KaY: Delete transmit SA(an: %hhu) of SC", 2755 psa->an); 2756 dl_list_del(&psa->list); 2757 os_free(psa); 2758 } 2759 2760 2761 /** 2762 * init_transmit_sc - 2763 */ 2764 static struct transmit_sc * 2765 ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci) 2766 { 2767 struct transmit_sc *psc; 2768 2769 psc = os_zalloc(sizeof(*psc)); 2770 if (!psc) { 2771 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 2772 return NULL; 2773 } 2774 os_memcpy(&psc->sci, sci, sizeof(psc->sci)); 2775 2776 os_get_time(&psc->created_time); 2777 psc->transmitting = false; 2778 psc->encoding_sa = false; 2779 psc->enciphering_sa = false; 2780 2781 dl_list_init(&psc->sa_list); 2782 wpa_printf(MSG_DEBUG, "KaY: Create transmit SC - SCI: %s", 2783 sci_txt(&psc->sci)); 2784 2785 return psc; 2786 } 2787 2788 2789 /** 2790 * ieee802_1x_kay_deinit_transmit_sc - 2791 */ 2792 static void 2793 ieee802_1x_kay_deinit_transmit_sc( 2794 struct ieee802_1x_mka_participant *participant, struct transmit_sc *psc) 2795 { 2796 struct transmit_sa *psa, *tmp; 2797 2798 wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC"); 2799 dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, list) 2800 ieee802_1x_delete_transmit_sa(participant->kay, psa); 2801 2802 secy_delete_transmit_sc(participant->kay, psc); 2803 os_free(psc); 2804 } 2805 2806 2807 /****************** Interface between CP and KAY *********************/ 2808 /** 2809 * ieee802_1x_kay_set_latest_sa_attr - 2810 */ 2811 int ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay, 2812 struct ieee802_1x_mka_ki *lki, u8 lan, 2813 bool ltx, bool lrx) 2814 { 2815 struct ieee802_1x_mka_participant *principal; 2816 2817 principal = ieee802_1x_kay_get_principal_participant(kay); 2818 if (!principal) 2819 return -1; 2820 2821 if (!lki) 2822 os_memset(&principal->lki, 0, sizeof(principal->lki)); 2823 else 2824 os_memcpy(&principal->lki, lki, sizeof(principal->lki)); 2825 2826 principal->lan = lan; 2827 principal->ltx = ltx; 2828 principal->lrx = lrx; 2829 if (!lki) { 2830 kay->ltx_kn = 0; 2831 kay->lrx_kn = 0; 2832 } else { 2833 kay->ltx_kn = lki->kn; 2834 kay->lrx_kn = lki->kn; 2835 } 2836 kay->ltx_an = lan; 2837 kay->lrx_an = lan; 2838 2839 return 0; 2840 } 2841 2842 2843 /** 2844 * ieee802_1x_kay_set_old_sa_attr - 2845 */ 2846 int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay, 2847 struct ieee802_1x_mka_ki *oki, 2848 u8 oan, bool otx, bool orx) 2849 { 2850 struct ieee802_1x_mka_participant *principal; 2851 2852 principal = ieee802_1x_kay_get_principal_participant(kay); 2853 if (!principal) 2854 return -1; 2855 2856 if (!oki) 2857 os_memset(&principal->oki, 0, sizeof(principal->oki)); 2858 else 2859 os_memcpy(&principal->oki, oki, sizeof(principal->oki)); 2860 2861 principal->oan = oan; 2862 principal->otx = otx; 2863 principal->orx = orx; 2864 2865 if (!oki) { 2866 kay->otx_kn = 0; 2867 kay->orx_kn = 0; 2868 } else { 2869 kay->otx_kn = oki->kn; 2870 kay->orx_kn = oki->kn; 2871 } 2872 kay->otx_an = oan; 2873 kay->orx_an = oan; 2874 2875 return 0; 2876 } 2877 2878 2879 static struct transmit_sa * lookup_txsa_by_an(struct transmit_sc *txsc, u8 an) 2880 { 2881 struct transmit_sa *txsa; 2882 2883 dl_list_for_each(txsa, &txsc->sa_list, struct transmit_sa, list) { 2884 if (txsa->an == an) 2885 return txsa; 2886 } 2887 2888 return NULL; 2889 } 2890 2891 2892 static struct receive_sa * lookup_rxsa_by_an(struct receive_sc *rxsc, u8 an) 2893 { 2894 struct receive_sa *rxsa; 2895 2896 dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) { 2897 if (rxsa->an == an) 2898 return rxsa; 2899 } 2900 2901 return NULL; 2902 } 2903 2904 2905 /** 2906 * ieee802_1x_kay_create_sas - 2907 */ 2908 int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, 2909 struct ieee802_1x_mka_ki *lki) 2910 { 2911 struct data_key *sa_key, *latest_sak; 2912 struct ieee802_1x_mka_participant *principal; 2913 struct receive_sc *rxsc; 2914 struct receive_sa *rxsa; 2915 struct transmit_sa *txsa; 2916 2917 principal = ieee802_1x_kay_get_principal_participant(kay); 2918 if (!principal) 2919 return -1; 2920 2921 latest_sak = NULL; 2922 dl_list_for_each(sa_key, &principal->sak_list, struct data_key, list) { 2923 if (is_ki_equal(&sa_key->key_identifier, lki)) { 2924 sa_key->rx_latest = true; 2925 sa_key->tx_latest = true; 2926 latest_sak = sa_key; 2927 principal->to_use_sak = true; 2928 } else { 2929 sa_key->rx_latest = false; 2930 sa_key->tx_latest = false; 2931 } 2932 } 2933 if (!latest_sak) { 2934 wpa_printf(MSG_ERROR, "KaY: lki related sak not found"); 2935 return -1; 2936 } 2937 2938 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 2939 while ((rxsa = lookup_rxsa_by_an(rxsc, latest_sak->an)) != NULL) 2940 ieee802_1x_delete_receive_sa(kay, rxsa); 2941 2942 rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1, 2943 latest_sak); 2944 if (!rxsa) 2945 return -1; 2946 2947 secy_create_receive_sa(kay, rxsa); 2948 } 2949 2950 while ((txsa = lookup_txsa_by_an(principal->txsc, latest_sak->an)) != 2951 NULL) 2952 ieee802_1x_delete_transmit_sa(kay, txsa); 2953 2954 txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an, 2955 latest_sak->next_pn ? 2956 latest_sak->next_pn : 1, 2957 latest_sak); 2958 if (!txsa) 2959 return -1; 2960 2961 secy_create_transmit_sa(kay, txsa); 2962 2963 2964 2965 return 0; 2966 } 2967 2968 2969 /** 2970 * ieee802_1x_kay_delete_sas - 2971 */ 2972 int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay, 2973 struct ieee802_1x_mka_ki *ki) 2974 { 2975 struct data_key *sa_key, *pre_key; 2976 struct transmit_sa *txsa, *pre_txsa; 2977 struct receive_sa *rxsa, *pre_rxsa; 2978 struct receive_sc *rxsc; 2979 struct ieee802_1x_mka_participant *principal; 2980 2981 wpa_printf(MSG_DEBUG, "KaY: Entry into %s", __func__); 2982 principal = ieee802_1x_kay_get_principal_participant(kay); 2983 if (!principal) 2984 return -1; 2985 2986 /* remove the transmit sa */ 2987 dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list, 2988 struct transmit_sa, list) { 2989 if (is_ki_equal(&txsa->pkey->key_identifier, ki)) 2990 ieee802_1x_delete_transmit_sa(kay, txsa); 2991 } 2992 2993 /* remove the receive sa */ 2994 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 2995 dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list, 2996 struct receive_sa, list) { 2997 if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) 2998 ieee802_1x_delete_receive_sa(kay, rxsa); 2999 } 3000 } 3001 3002 /* remove the sak */ 3003 dl_list_for_each_safe(sa_key, pre_key, &principal->sak_list, 3004 struct data_key, list) { 3005 if (is_ki_equal(&sa_key->key_identifier, ki)) { 3006 if (principal->new_key == sa_key) 3007 principal->new_key = NULL; 3008 dl_list_del(&sa_key->list); 3009 ieee802_1x_kay_deinit_data_key(sa_key); 3010 break; 3011 } 3012 } 3013 3014 return 0; 3015 } 3016 3017 3018 /** 3019 * ieee802_1x_kay_enable_tx_sas - 3020 */ 3021 int ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay, 3022 struct ieee802_1x_mka_ki *lki) 3023 { 3024 struct ieee802_1x_mka_participant *principal; 3025 struct transmit_sa *txsa; 3026 3027 principal = ieee802_1x_kay_get_principal_participant(kay); 3028 if (!principal) 3029 return -1; 3030 3031 dl_list_for_each(txsa, &principal->txsc->sa_list, struct transmit_sa, 3032 list) { 3033 if (is_ki_equal(&txsa->pkey->key_identifier, lki)) { 3034 txsa->in_use = true; 3035 secy_enable_transmit_sa(kay, txsa); 3036 ieee802_1x_cp_set_usingtransmitas( 3037 principal->kay->cp, true); 3038 ieee802_1x_cp_sm_step(principal->kay->cp); 3039 } 3040 } 3041 3042 return 0; 3043 } 3044 3045 3046 /** 3047 * ieee802_1x_kay_enable_rx_sas - 3048 */ 3049 int ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay, 3050 struct ieee802_1x_mka_ki *lki) 3051 { 3052 struct ieee802_1x_mka_participant *principal; 3053 struct receive_sa *rxsa; 3054 struct receive_sc *rxsc; 3055 3056 principal = ieee802_1x_kay_get_principal_participant(kay); 3057 if (!principal) 3058 return -1; 3059 3060 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 3061 dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) 3062 { 3063 if (is_ki_equal(&rxsa->pkey->key_identifier, lki)) { 3064 rxsa->in_use = true; 3065 secy_enable_receive_sa(kay, rxsa); 3066 ieee802_1x_cp_set_usingreceivesas( 3067 principal->kay->cp, true); 3068 ieee802_1x_cp_sm_step(principal->kay->cp); 3069 } 3070 } 3071 } 3072 3073 return 0; 3074 } 3075 3076 3077 /** 3078 * ieee802_1x_kay_enable_new_info - 3079 */ 3080 int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay) 3081 { 3082 struct ieee802_1x_mka_participant *principal; 3083 3084 principal = ieee802_1x_kay_get_principal_participant(kay); 3085 if (!principal) 3086 return -1; 3087 3088 if (principal->retry_count < MAX_RETRY_CNT || principal->mode == PSK) { 3089 ieee802_1x_participant_send_mkpdu(principal); 3090 principal->retry_count++; 3091 } 3092 3093 return 0; 3094 } 3095 3096 3097 /** 3098 * ieee802_1x_kay_mkpdu_validity_check - 3099 * Validity checks specified in IEEE Std 802.1X-2010, 11.11.2 (Validation of 3100 * MKPDUs) 3101 */ 3102 static int ieee802_1x_kay_mkpdu_validity_check(struct ieee802_1x_kay *kay, 3103 const u8 *buf, size_t len) 3104 { 3105 struct ieee8023_hdr *eth_hdr; 3106 struct ieee802_1x_hdr *eapol_hdr; 3107 struct ieee802_1x_mka_hdr *mka_hdr; 3108 struct ieee802_1x_mka_basic_body *body; 3109 size_t mka_msg_len; 3110 struct ieee802_1x_mka_participant *participant; 3111 size_t body_len; 3112 size_t ckn_len; 3113 u8 icv[MAX_ICV_LEN]; 3114 const u8 *msg_icv; 3115 3116 /* len > eth+eapol header already verified in kay_l2_receive(); 3117 * likewise, eapol_hdr->length validated there */ 3118 eth_hdr = (struct ieee8023_hdr *) buf; 3119 eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1); 3120 mka_hdr = (struct ieee802_1x_mka_hdr *) (eapol_hdr + 1); 3121 3122 wpa_printf(MSG_DEBUG, "KaY: Ethernet header: DA=" MACSTR " SA=" MACSTR 3123 " Ethertype=0x%x", 3124 MAC2STR(eth_hdr->dest), MAC2STR(eth_hdr->src), 3125 be_to_host16(eth_hdr->ethertype)); 3126 3127 /* the destination address shall not be an individual address */ 3128 if (!ether_addr_equal(eth_hdr->dest, pae_group_addr)) { 3129 wpa_printf(MSG_DEBUG, 3130 "KaY: ethernet destination address is not PAE group address"); 3131 return -1; 3132 } 3133 3134 wpa_printf(MSG_DEBUG, 3135 "KaY: Common EAPOL PDU structure: Protocol Version=%u Packet Type=%u Packet Body Length=%u", 3136 eapol_hdr->version, eapol_hdr->type, 3137 be_to_host16(eapol_hdr->length)); 3138 3139 /* MKPDU shall not be less than 32 octets */ 3140 mka_msg_len = be_to_host16(eapol_hdr->length); 3141 if (mka_msg_len < 32) { 3142 wpa_printf(MSG_DEBUG, "KaY: MKPDU is less than 32 octets"); 3143 return -1; 3144 } 3145 /* MKPDU shall be a multiple of 4 octets */ 3146 if ((mka_msg_len % 4) != 0) { 3147 wpa_printf(MSG_DEBUG, 3148 "KaY: MKPDU is not multiple of 4 octets"); 3149 return -1; 3150 } 3151 3152 wpa_hexdump(MSG_MSGDUMP, "KaY: EAPOL-MKA Packet Body (MKPDU)", 3153 mka_hdr, mka_msg_len); 3154 3155 /* Room for body_len already verified in kay_l2_receive() */ 3156 body = (struct ieee802_1x_mka_basic_body *) mka_hdr; 3157 body_len = get_mka_param_body_len(body); 3158 /* EAPOL-MKA body should comprise basic parameter set and ICV */ 3159 if (mka_msg_len < MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN) { 3160 wpa_printf(MSG_ERROR, 3161 "KaY: Received EAPOL-MKA Packet Body Length (%zu bytes) is less than the Basic Parameter Set Header Length (%zu bytes) + the Basic Parameter Set Body Length (%zu bytes) + %d bytes of ICV", 3162 mka_msg_len, MKA_HDR_LEN, 3163 body_len, DEFAULT_ICV_LEN); 3164 return -1; 3165 } 3166 3167 if (body_len < sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN) { 3168 wpa_printf(MSG_DEBUG, "KaY: Too small body length %zu", 3169 body_len); 3170 return -1; 3171 } 3172 ckn_len = body_len - 3173 (sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN); 3174 if (ckn_len < 1 || ckn_len > MAX_CKN_LEN) { 3175 wpa_printf(MSG_WARNING, 3176 "KaY: Received EAPOL-MKA CKN Length (%zu bytes) is out of range (<= %u bytes)", 3177 ckn_len, MAX_CKN_LEN); 3178 return -1; 3179 } 3180 3181 ieee802_1x_mka_dump_basic_body(body); 3182 3183 /* CKN should be owned by I */ 3184 participant = ieee802_1x_kay_get_participant(kay, body->ckn, ckn_len); 3185 if (!participant) { 3186 wpa_printf(MSG_DEBUG, "KaY: CKN is not included in my CA"); 3187 return -1; 3188 } 3189 3190 /* algorithm agility check */ 3191 if (os_memcmp(body->algo_agility, mka_algo_agility, 3192 sizeof(body->algo_agility)) != 0) { 3193 wpa_printf(MSG_INFO, 3194 "KaY: Peer's algorithm agility (%s) not supported", 3195 algo_agility_txt(body->algo_agility)); 3196 return -1; 3197 } 3198 3199 /* ICV check */ 3200 /* 3201 * The ICV will comprise the final octets of the packet body, whatever 3202 * its size, not the fixed length 16 octets, indicated by the EAPOL 3203 * packet body length. 3204 */ 3205 if (len < mka_alg_tbl[kay->mka_algindex].icv_len || 3206 mka_alg_tbl[kay->mka_algindex].icv_hash( 3207 participant->ick.key, participant->ick.len, 3208 buf, len - mka_alg_tbl[kay->mka_algindex].icv_len, icv)) { 3209 wpa_printf(MSG_ERROR, "KaY: Failed to calculate ICV"); 3210 return -1; 3211 } 3212 3213 msg_icv = ieee802_1x_mka_decode_icv_body(participant, 3214 (const u8 *) mka_hdr, 3215 mka_msg_len); 3216 if (!msg_icv) { 3217 wpa_printf(MSG_WARNING, "KaY: No ICV in MKPDU - ignore it"); 3218 return -1; 3219 } 3220 wpa_hexdump(MSG_DEBUG, "KaY: Received ICV", 3221 msg_icv, mka_alg_tbl[kay->mka_algindex].icv_len); 3222 if (os_memcmp_const(msg_icv, icv, 3223 mka_alg_tbl[kay->mka_algindex].icv_len) != 0) { 3224 wpa_printf(MSG_WARNING, 3225 "KaY: Computed ICV is not equal to Received ICV"); 3226 wpa_hexdump(MSG_DEBUG, "KaY: Calculated ICV", 3227 icv, mka_alg_tbl[kay->mka_algindex].icv_len); 3228 return -1; 3229 } 3230 3231 return 0; 3232 } 3233 3234 3235 /** 3236 * ieee802_1x_kay_decode_mkpdu - 3237 */ 3238 static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay, 3239 const u8 *buf, size_t len) 3240 { 3241 struct ieee802_1x_mka_participant *participant; 3242 struct ieee802_1x_mka_hdr *hdr; 3243 struct ieee802_1x_kay_peer *peer; 3244 size_t body_len; 3245 size_t left_len; 3246 u8 body_type; 3247 int i; 3248 const u8 *pos; 3249 bool handled[256]; 3250 bool bad_sak_use = false; /* Error detected while processing SAK Use 3251 * parameter set */ 3252 bool i_in_peerlist, is_in_live_peer, is_in_potential_peer; 3253 3254 wpa_printf(MSG_DEBUG, "KaY: Decode received MKPDU (ifname=%s)", 3255 kay->if_name); 3256 if (ieee802_1x_kay_mkpdu_validity_check(kay, buf, len)) 3257 return -1; 3258 3259 /* handle basic parameter set */ 3260 pos = buf + sizeof(struct ieee8023_hdr) + sizeof(struct ieee802_1x_hdr); 3261 left_len = len - sizeof(struct ieee8023_hdr) - 3262 sizeof(struct ieee802_1x_hdr); 3263 participant = ieee802_1x_mka_decode_basic_body(kay, pos, left_len); 3264 if (!participant) 3265 return -1; 3266 3267 /* to skip basic parameter set */ 3268 hdr = (struct ieee802_1x_mka_hdr *) pos; 3269 body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr)); 3270 if (left_len < body_len + MKA_HDR_LEN) 3271 return -1; 3272 pos += body_len + MKA_HDR_LEN; 3273 left_len -= body_len + MKA_HDR_LEN; 3274 3275 /* check i am in the peer's peer list */ 3276 i_in_peerlist = ieee802_1x_mka_i_in_peerlist(participant, pos, 3277 left_len); 3278 is_in_live_peer = ieee802_1x_kay_is_in_live_peer( 3279 participant, participant->current_peer_id.mi); 3280 wpa_printf(MSG_DEBUG, "KaY: i_in_peerlist=%s is_in_live_peer=%s", 3281 yes_no(i_in_peerlist), yes_no(is_in_live_peer)); 3282 if (i_in_peerlist && !is_in_live_peer) { 3283 /* accept the peer as live peer */ 3284 is_in_potential_peer = ieee802_1x_kay_is_in_potential_peer( 3285 participant, participant->current_peer_id.mi); 3286 if (is_in_potential_peer) { 3287 if (!ieee802_1x_kay_move_live_peer( 3288 participant, 3289 participant->current_peer_id.mi, 3290 be_to_host32(participant-> 3291 current_peer_id.mn))) 3292 return -1; 3293 } else if (!ieee802_1x_kay_create_live_peer( 3294 participant, participant->current_peer_id.mi, 3295 be_to_host32(participant-> 3296 current_peer_id.mn))) { 3297 return -1; 3298 } 3299 3300 ieee802_1x_kay_elect_key_server(participant); 3301 ieee802_1x_kay_decide_macsec_use(participant); 3302 } 3303 3304 /* 3305 * Handle other parameter set than basic parameter set. 3306 * Each parameter set should be present only once. 3307 */ 3308 for (i = 0; i < 256; i++) 3309 handled[i] = false; 3310 3311 handled[0] = true; 3312 for (; left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN; 3313 pos += body_len + MKA_HDR_LEN, 3314 left_len -= body_len + MKA_HDR_LEN) { 3315 hdr = (struct ieee802_1x_mka_hdr *) pos; 3316 body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr)); 3317 body_type = get_mka_param_body_type(hdr); 3318 3319 if (body_type == MKA_ICV_INDICATOR) 3320 return 0; 3321 3322 if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) { 3323 wpa_printf(MSG_ERROR, 3324 "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV", 3325 left_len, MKA_HDR_LEN, 3326 body_len, DEFAULT_ICV_LEN); 3327 return -1; 3328 } 3329 3330 if (handled[body_type]) { 3331 wpa_printf(MSG_DEBUG, 3332 "KaY: Ignore duplicated body type %u", 3333 body_type); 3334 continue; 3335 } 3336 3337 handled[body_type] = true; 3338 if (body_type < ARRAY_SIZE(mka_body_handler) && 3339 mka_body_handler[body_type].body_rx) { 3340 if (mka_body_handler[body_type].body_rx 3341 (participant, pos, left_len) != 0) { 3342 /* Handle parameter set failure */ 3343 if (body_type != MKA_SAK_USE) { 3344 wpa_printf(MSG_INFO, 3345 "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed", 3346 body_type); 3347 return -1; 3348 } 3349 3350 /* Ideally DIST-SAK should be processed before 3351 * SAK-USE. Unfortunately IEEE Std 802.1X-2010, 3352 * 11.11.3 (Encoding MKPDUs) states SAK-USE(3) 3353 * must always be encoded before DIST-SAK(4). 3354 * Rather than redesigning mka_body_handler so 3355 * that it somehow processes DIST-SAK before 3356 * SAK-USE, just ignore SAK-USE failures if 3357 * DIST-SAK is also present in this MKPDU. */ 3358 bad_sak_use = true; 3359 } 3360 } else { 3361 wpa_printf(MSG_ERROR, 3362 "KaY: The body type %d is not supported in this MKA version %d", 3363 body_type, MKA_VERSION_ID); 3364 } 3365 } 3366 3367 if (bad_sak_use && !handled[MKA_DISTRIBUTED_SAK]) { 3368 wpa_printf(MSG_INFO, 3369 "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed", 3370 MKA_SAK_USE); 3371 if (!reset_participant_mi(participant)) 3372 wpa_printf(MSG_DEBUG, "KaY: Could not update MI"); 3373 else 3374 wpa_printf(MSG_DEBUG, 3375 "KaY: Selected a new random MI: %s", 3376 mi_txt(participant->mi)); 3377 return -1; 3378 } 3379 3380 /* Detect missing parameter sets */ 3381 peer = ieee802_1x_kay_get_live_peer(participant, 3382 participant->current_peer_id.mi); 3383 if (peer) { 3384 /* MKPDU is from live peer */ 3385 if (!handled[MKA_SAK_USE]) { 3386 /* Once a live peer starts sending SAK-USE, it should be 3387 * sent every time. */ 3388 if (peer->sak_used) { 3389 wpa_printf(MSG_INFO, 3390 "KaY: Discarding Rx MKPDU: Live Peer stopped sending SAK-USE"); 3391 return -1; 3392 } 3393 3394 /* Live peer is probably hung if it hasn't sent SAK-USE 3395 * after a reasonable number of MKPDUs. Drop the MKPDU, 3396 * which will eventually force an timeout. */ 3397 if (++peer->missing_sak_use_count > 3398 MAX_MISSING_SAK_USE) { 3399 wpa_printf(MSG_INFO, 3400 "KaY: Discarding Rx MKPDU: Live Peer not sending SAK-USE"); 3401 return -1; 3402 } 3403 } else { 3404 peer->missing_sak_use_count = 0; 3405 3406 /* Only update live peer watchdog after successful 3407 * decode of all parameter sets */ 3408 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 3409 } 3410 } else { 3411 /* MKPDU is from new or potential peer */ 3412 peer = ieee802_1x_kay_get_peer(participant, 3413 participant->current_peer_id.mi); 3414 if (!peer) { 3415 wpa_printf(MSG_DEBUG, "KaY: No peer entry found"); 3416 return -1; 3417 } 3418 3419 /* Do not update potential peer watchdog. Per IEEE Std 3420 * 802.1X-2010, 9.4.3, potential peers need to show liveness by 3421 * including our MI/MN in their transmitted MKPDU (within 3422 * potential or live parameter sets). Whena potential peer does 3423 * include our MI/MN in an MKPDU, we respond by moving the peer 3424 * from 'potential_peers' to 'live_peers'. */ 3425 } 3426 3427 kay->active = true; 3428 participant->retry_count = 0; 3429 participant->active = true; 3430 3431 return 0; 3432 } 3433 3434 3435 3436 static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf, 3437 size_t len) 3438 { 3439 struct ieee802_1x_kay *kay = ctx; 3440 struct ieee8023_hdr *eth_hdr; 3441 struct ieee802_1x_hdr *eapol_hdr; 3442 size_t calc_len; 3443 3444 /* IEEE Std 802.1X-2010, 11.4 (Validation of received EAPOL PDUs) */ 3445 3446 /* must contain at least ieee8023_hdr + ieee802_1x_hdr */ 3447 if (len < sizeof(*eth_hdr) + sizeof(*eapol_hdr)) { 3448 wpa_printf(MSG_MSGDUMP, "KaY: EAPOL frame too short (%lu)", 3449 (unsigned long) len); 3450 return; 3451 } 3452 3453 eth_hdr = (struct ieee8023_hdr *) buf; 3454 eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1); 3455 calc_len = sizeof(*eth_hdr) + sizeof(*eapol_hdr) + 3456 be_to_host16(eapol_hdr->length); 3457 if (len < calc_len) { 3458 wpa_printf(MSG_MSGDUMP, "KaY: EAPOL MPDU is invalid: (received len %lu, calculated len %lu, EAPOL length %u)", 3459 (unsigned long) len, 3460 (unsigned long) calc_len, 3461 be_to_host16(eapol_hdr->length)); 3462 return; 3463 } 3464 if (len > calc_len) { 3465 wpa_hexdump(MSG_DEBUG, 3466 "KaY: Ignore extra octets following the Packey Body field", 3467 &buf[calc_len], len - calc_len); 3468 len = calc_len; 3469 } 3470 3471 if (eapol_hdr->version < EAPOL_VERSION) { 3472 wpa_printf(MSG_MSGDUMP, "KaY: version %d does not support MKA", 3473 eapol_hdr->version); 3474 return; 3475 } 3476 if (be_to_host16(eth_hdr->ethertype) != ETH_P_PAE || 3477 eapol_hdr->type != IEEE802_1X_TYPE_EAPOL_MKA) 3478 return; /* ignore other EAPOL types silently here */ 3479 3480 wpa_hexdump(MSG_DEBUG, "KaY: RX EAPOL-MKA", buf, len); 3481 if (dl_list_empty(&kay->participant_list)) { 3482 wpa_printf(MSG_ERROR, 3483 "KaY: No MKA participant instance - ignore EAPOL-MKA"); 3484 return; 3485 } 3486 3487 ieee802_1x_kay_decode_mkpdu(kay, buf, len); 3488 } 3489 3490 3491 /** 3492 * ieee802_1x_kay_init - 3493 */ 3494 struct ieee802_1x_kay * 3495 ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, 3496 bool macsec_replay_protect, u32 macsec_replay_window, 3497 u8 macsec_offload, u16 port, u8 priority, 3498 u32 macsec_csindex, const char *ifname, const u8 *addr) 3499 { 3500 struct ieee802_1x_kay *kay; 3501 3502 wpa_printf(MSG_DEBUG, "KaY: Initialize - ifname=%s addr=" MACSTR 3503 " port=%u priority=%u", 3504 ifname, MAC2STR(addr), port, priority); 3505 kay = os_zalloc(sizeof(*kay)); 3506 if (!kay) { 3507 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 3508 os_free(ctx); 3509 return NULL; 3510 } 3511 3512 kay->ctx = ctx; 3513 3514 kay->enable = true; 3515 kay->active = false; 3516 3517 kay->authenticated = false; 3518 kay->secured = false; 3519 kay->failed = false; 3520 kay->policy = policy; 3521 3522 os_strlcpy(kay->if_name, ifname, IFNAMSIZ); 3523 os_memcpy(kay->actor_sci.addr, addr, ETH_ALEN); 3524 kay->actor_sci.port = host_to_be16(port ? port : 0x0001); 3525 wpa_printf(MSG_DEBUG, "KaY: Generated SCI: %s", 3526 sci_txt(&kay->actor_sci)); 3527 kay->actor_priority = priority; 3528 3529 /* While actor acts as a key server, shall distribute sakey */ 3530 kay->dist_kn = 1; 3531 kay->dist_an = 0; 3532 kay->dist_time = 0; 3533 3534 kay->pn_exhaustion = PENDING_PN_EXHAUSTION; 3535 kay->macsec_csindex = macsec_csindex; 3536 kay->mka_algindex = DEFAULT_MKA_ALG_INDEX; 3537 kay->mka_version = MKA_VERSION_ID; 3538 3539 os_memcpy(kay->algo_agility, mka_algo_agility, 3540 sizeof(kay->algo_agility)); 3541 3542 dl_list_init(&kay->participant_list); 3543 3544 if (policy != DO_NOT_SECURE && 3545 secy_get_capability(kay, &kay->macsec_capable) < 0) 3546 goto error; 3547 3548 if (policy == DO_NOT_SECURE || 3549 kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { 3550 kay->macsec_capable = MACSEC_CAP_NOT_IMPLEMENTED; 3551 kay->macsec_desired = false; 3552 kay->macsec_protect = false; 3553 kay->macsec_encrypt = false; 3554 kay->macsec_validate = Disabled; 3555 kay->macsec_replay_protect = false; 3556 kay->macsec_replay_window = 0; 3557 kay->macsec_offload = 0; 3558 kay->macsec_confidentiality = CONFIDENTIALITY_NONE; 3559 kay->mka_hello_time = MKA_HELLO_TIME; 3560 } else { 3561 kay->macsec_desired = true; 3562 kay->macsec_protect = true; 3563 if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF && 3564 policy == SHOULD_ENCRYPT) { 3565 kay->macsec_encrypt = true; 3566 kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0; 3567 } else { /* SHOULD_SECURE */ 3568 kay->macsec_encrypt = false; 3569 kay->macsec_confidentiality = CONFIDENTIALITY_NONE; 3570 } 3571 kay->macsec_validate = Strict; 3572 kay->macsec_replay_protect = macsec_replay_protect; 3573 kay->macsec_replay_window = macsec_replay_window; 3574 kay->macsec_offload = macsec_offload; 3575 kay->mka_hello_time = MKA_HELLO_TIME; 3576 } 3577 3578 wpa_printf(MSG_DEBUG, "KaY: state machine created"); 3579 3580 /* Initialize the SecY must be prio to CP, as CP will control SecY */ 3581 if (secy_init_macsec(kay) < 0) { 3582 wpa_printf(MSG_DEBUG, "KaY: Could not initialize MACsec"); 3583 goto error; 3584 } 3585 3586 wpa_printf(MSG_DEBUG, "KaY: SecY init MACsec done"); 3587 3588 /* init CP */ 3589 kay->cp = ieee802_1x_cp_sm_init(kay); 3590 if (kay->cp == NULL) 3591 goto error; 3592 3593 if (policy == DO_NOT_SECURE) { 3594 ieee802_1x_cp_connect_authenticated(kay->cp); 3595 ieee802_1x_cp_sm_step(kay->cp); 3596 } else { 3597 kay->l2_mka = l2_packet_init(kay->if_name, NULL, ETH_P_PAE, 3598 kay_l2_receive, kay, 1); 3599 if (kay->l2_mka == NULL) { 3600 wpa_printf(MSG_WARNING, 3601 "KaY: Failed to initialize L2 packet processing for MKA packet"); 3602 goto error; 3603 } 3604 } 3605 3606 return kay; 3607 3608 error: 3609 ieee802_1x_kay_deinit(kay); 3610 return NULL; 3611 } 3612 3613 3614 /** 3615 * ieee802_1x_kay_deinit - 3616 */ 3617 void 3618 ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay) 3619 { 3620 struct ieee802_1x_mka_participant *participant; 3621 3622 if (!kay) 3623 return; 3624 3625 wpa_printf(MSG_DEBUG, "KaY: state machine removed"); 3626 3627 while (!dl_list_empty(&kay->participant_list)) { 3628 participant = dl_list_entry(kay->participant_list.next, 3629 struct ieee802_1x_mka_participant, 3630 list); 3631 ieee802_1x_kay_delete_mka(kay, &participant->ckn); 3632 } 3633 3634 ieee802_1x_cp_sm_deinit(kay->cp); 3635 secy_deinit_macsec(kay); 3636 3637 if (kay->l2_mka) { 3638 l2_packet_deinit(kay->l2_mka); 3639 kay->l2_mka = NULL; 3640 } 3641 3642 os_free(kay->ctx); 3643 os_free(kay); 3644 } 3645 3646 3647 static const char * mode_txt(enum mka_created_mode mode) 3648 { 3649 switch (mode) { 3650 case PSK: 3651 return "PSK"; 3652 case EAP_EXCHANGE: 3653 return "EAP"; 3654 } 3655 3656 return "?"; 3657 } 3658 3659 3660 /** 3661 * ieee802_1x_kay_create_mka - 3662 */ 3663 struct ieee802_1x_mka_participant * 3664 ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, 3665 const struct mka_key_name *ckn, 3666 const struct mka_key *cak, u32 life, 3667 enum mka_created_mode mode, bool is_authenticator) 3668 { 3669 struct ieee802_1x_mka_participant *participant; 3670 unsigned int usecs; 3671 3672 wpa_printf(MSG_DEBUG, 3673 "KaY: Create MKA (ifname=%s mode=%s authenticator=%s)", 3674 kay->if_name, mode_txt(mode), yes_no(is_authenticator)); 3675 3676 if (!kay || !ckn || !cak) { 3677 wpa_printf(MSG_ERROR, "KaY: CKN or CAK is null"); 3678 return NULL; 3679 } 3680 3681 if (cak->len != 16 && cak->len != 32) { 3682 wpa_printf(MSG_ERROR, "KaY: Unexpected CAK length %u", 3683 (unsigned int) cak->len); 3684 return NULL; 3685 } 3686 if (ckn->len > MAX_CKN_LEN) { 3687 wpa_printf(MSG_ERROR, "KaY: CKN is out of range (>32 bytes)"); 3688 return NULL; 3689 } 3690 if (!kay->enable) { 3691 wpa_printf(MSG_ERROR, "KaY: Now is at disable state"); 3692 return NULL; 3693 } 3694 3695 participant = os_zalloc(sizeof(*participant)); 3696 if (!participant) { 3697 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 3698 return NULL; 3699 } 3700 3701 participant->ckn.len = ckn->len; 3702 os_memcpy(participant->ckn.name, ckn->name, ckn->len); 3703 wpa_hexdump(MSG_DEBUG, "KaY: CKN", participant->ckn.name, 3704 participant->ckn.len); 3705 participant->cak.len = cak->len; 3706 os_memcpy(participant->cak.key, cak->key, cak->len); 3707 wpa_hexdump_key(MSG_DEBUG, "KaY: CAK", participant->cak.key, 3708 participant->cak.len); 3709 if (life) 3710 participant->cak_life = life + time(NULL); 3711 3712 switch (mode) { 3713 case EAP_EXCHANGE: 3714 if (is_authenticator) { 3715 participant->is_obliged_key_server = true; 3716 participant->can_be_key_server = true; 3717 participant->is_key_server = true; 3718 participant->principal = true; 3719 3720 os_memcpy(&kay->key_server_sci, &kay->actor_sci, 3721 sizeof(kay->key_server_sci)); 3722 kay->key_server_priority = kay->actor_priority; 3723 participant->is_elected = true; 3724 } else { 3725 participant->is_obliged_key_server = false; 3726 participant->can_be_key_server = false; 3727 participant->is_key_server = false; 3728 participant->is_elected = true; 3729 } 3730 break; 3731 3732 default: 3733 participant->is_obliged_key_server = false; 3734 participant->can_be_key_server = true; 3735 participant->is_key_server = true; 3736 participant->is_elected = false; 3737 break; 3738 } 3739 3740 participant->cached = false; 3741 3742 participant->active = false; 3743 participant->participant = false; 3744 participant->retain = false; 3745 participant->activate = DEFAULT; 3746 3747 if (participant->is_key_server) 3748 participant->principal = true; 3749 3750 dl_list_init(&participant->live_peers); 3751 dl_list_init(&participant->potential_peers); 3752 3753 participant->retry_count = 0; 3754 participant->kay = kay; 3755 3756 if (!reset_participant_mi(participant)) 3757 goto fail; 3758 wpa_printf(MSG_DEBUG, "KaY: Selected random MI: %s", 3759 mi_txt(participant->mi)); 3760 3761 participant->lrx = false; 3762 participant->ltx = false; 3763 participant->orx = false; 3764 participant->otx = false; 3765 participant->to_dist_sak = false; 3766 participant->to_use_sak = false; 3767 participant->new_sak = false; 3768 dl_list_init(&participant->sak_list); 3769 participant->new_key = NULL; 3770 dl_list_init(&participant->rxsc_list); 3771 participant->txsc = ieee802_1x_kay_init_transmit_sc(&kay->actor_sci); 3772 secy_cp_control_protect_frames(kay, kay->macsec_protect); 3773 secy_cp_control_replay(kay, kay->macsec_replay_protect, 3774 kay->macsec_replay_window); 3775 secy_cp_control_offload(kay, kay->macsec_offload); 3776 if (secy_create_transmit_sc(kay, participant->txsc)) 3777 goto fail; 3778 3779 /* to derive KEK from CAK and CKN */ 3780 participant->kek.len = participant->cak.len; 3781 if (mka_alg_tbl[kay->mka_algindex].kek_trfm(participant->cak.key, 3782 participant->cak.len, 3783 participant->ckn.name, 3784 participant->ckn.len, 3785 participant->kek.key, 3786 participant->kek.len)) { 3787 wpa_printf(MSG_ERROR, "KaY: KEK derivation failed"); 3788 goto fail; 3789 } 3790 wpa_hexdump_key(MSG_DEBUG, "KaY: Derived KEK", 3791 participant->kek.key, participant->kek.len); 3792 3793 /* to derive ICK from CAK and CKN */ 3794 participant->ick.len = participant->cak.len; 3795 if (mka_alg_tbl[kay->mka_algindex].ick_trfm(participant->cak.key, 3796 participant->cak.len, 3797 participant->ckn.name, 3798 participant->ckn.len, 3799 participant->ick.key, 3800 participant->ick.len)) { 3801 wpa_printf(MSG_ERROR, "KaY: ICK derivation failed"); 3802 goto fail; 3803 } 3804 wpa_hexdump_key(MSG_DEBUG, "KaY: Derived ICK", 3805 participant->ick.key, participant->ick.len); 3806 3807 dl_list_add(&kay->participant_list, &participant->list); 3808 3809 usecs = os_random() % (kay->mka_hello_time * 1000); 3810 eloop_register_timeout(0, usecs, ieee802_1x_participant_timer, 3811 participant, NULL); 3812 3813 /* Disable MKA lifetime for PSK mode. 3814 * The peer(s) can take a long time to come up, because we 3815 * create a "standby" MKA, and we need it to remain live until 3816 * some peer appears. 3817 */ 3818 if (mode != PSK) { 3819 participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) + 3820 usecs / 1000000; 3821 } 3822 participant->mode = mode; 3823 3824 return participant; 3825 3826 fail: 3827 os_free(participant->txsc); 3828 os_free(participant); 3829 return NULL; 3830 } 3831 3832 3833 /** 3834 * ieee802_1x_kay_delete_mka - 3835 */ 3836 void 3837 ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn) 3838 { 3839 struct ieee802_1x_mka_participant *participant; 3840 struct ieee802_1x_kay_peer *peer; 3841 struct data_key *sak; 3842 struct receive_sc *rxsc; 3843 3844 if (!kay || !ckn) 3845 return; 3846 3847 wpa_printf(MSG_DEBUG, "KaY: participant removed"); 3848 3849 /* get the participant */ 3850 participant = ieee802_1x_kay_get_participant(kay, ckn->name, ckn->len); 3851 if (!participant) { 3852 wpa_hexdump(MSG_DEBUG, "KaY: participant is not found", 3853 ckn->name, ckn->len); 3854 return; 3855 } 3856 3857 eloop_cancel_timeout(ieee802_1x_participant_timer, participant, NULL); 3858 dl_list_del(&participant->list); 3859 3860 /* remove live peer */ 3861 while (!dl_list_empty(&participant->live_peers)) { 3862 peer = dl_list_entry(participant->live_peers.next, 3863 struct ieee802_1x_kay_peer, list); 3864 dl_list_del(&peer->list); 3865 os_free(peer); 3866 } 3867 3868 /* remove potential peer */ 3869 while (!dl_list_empty(&participant->potential_peers)) { 3870 peer = dl_list_entry(participant->potential_peers.next, 3871 struct ieee802_1x_kay_peer, list); 3872 dl_list_del(&peer->list); 3873 os_free(peer); 3874 } 3875 3876 /* remove sak */ 3877 while (!dl_list_empty(&participant->sak_list)) { 3878 sak = dl_list_entry(participant->sak_list.next, 3879 struct data_key, list); 3880 dl_list_del(&sak->list); 3881 ieee802_1x_kay_deinit_data_key(sak); 3882 } 3883 while (!dl_list_empty(&participant->rxsc_list)) { 3884 rxsc = dl_list_entry(participant->rxsc_list.next, 3885 struct receive_sc, list); 3886 ieee802_1x_kay_deinit_receive_sc(participant, rxsc); 3887 } 3888 ieee802_1x_kay_deinit_transmit_sc(participant, participant->txsc); 3889 3890 os_memset(&participant->cak, 0, sizeof(participant->cak)); 3891 os_memset(&participant->kek, 0, sizeof(participant->kek)); 3892 os_memset(&participant->ick, 0, sizeof(participant->ick)); 3893 os_free(participant); 3894 } 3895 3896 3897 /** 3898 * ieee802_1x_kay_mka_participate - 3899 */ 3900 void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay, 3901 struct mka_key_name *ckn, bool status) 3902 { 3903 struct ieee802_1x_mka_participant *participant; 3904 3905 if (!kay || !ckn) 3906 return; 3907 3908 participant = ieee802_1x_kay_get_participant(kay, ckn->name, ckn->len); 3909 if (!participant) 3910 return; 3911 3912 participant->active = status; 3913 } 3914 3915 3916 /** 3917 * ieee802_1x_kay_new_sak - 3918 */ 3919 int 3920 ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay) 3921 { 3922 struct ieee802_1x_mka_participant *participant; 3923 3924 if (!kay) 3925 return -1; 3926 3927 participant = ieee802_1x_kay_get_principal_participant(kay); 3928 if (!participant) 3929 return -1; 3930 3931 participant->new_sak = true; 3932 wpa_printf(MSG_DEBUG, "KaY: new SAK signal"); 3933 3934 return 0; 3935 } 3936 3937 3938 /** 3939 * ieee802_1x_kay_change_cipher_suite - 3940 */ 3941 int 3942 ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, 3943 unsigned int cs_index) 3944 { 3945 struct ieee802_1x_mka_participant *participant; 3946 enum macsec_cap secy_cap; 3947 3948 if (!kay) 3949 return -1; 3950 3951 if (cs_index >= CS_TABLE_SIZE) { 3952 wpa_printf(MSG_ERROR, 3953 "KaY: Configured cipher suite index is out of range"); 3954 return -1; 3955 } 3956 if (kay->macsec_csindex == cs_index) 3957 return -2; 3958 3959 if (cs_index == 0) 3960 kay->macsec_desired = false; 3961 3962 kay->macsec_csindex = cs_index; 3963 kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable; 3964 3965 if (secy_get_capability(kay, &secy_cap) < 0) 3966 return -3; 3967 3968 if (kay->macsec_capable > secy_cap) 3969 kay->macsec_capable = secy_cap; 3970 3971 participant = ieee802_1x_kay_get_principal_participant(kay); 3972 if (participant) { 3973 wpa_printf(MSG_INFO, "KaY: Cipher Suite changed"); 3974 participant->new_sak = true; 3975 } 3976 3977 return 0; 3978 } 3979 3980 3981 #ifdef CONFIG_CTRL_IFACE 3982 3983 /** 3984 * ieee802_1x_kay_get_status - Get IEEE 802.1X KaY status details 3985 * @sm: Pointer to KaY allocated with ieee802_1x_kay_init() 3986 * @buf: Buffer for status information 3987 * @buflen: Maximum buffer length 3988 * @verbose: Whether to include verbose status information 3989 * Returns: Number of bytes written to buf. 3990 * 3991 * Query KaY status information. This function fills in a text area with current 3992 * status information. If the buffer (buf) is not large enough, status 3993 * information will be truncated to fit the buffer. 3994 */ 3995 int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf, 3996 size_t buflen) 3997 { 3998 char *pos, *end; 3999 int res, count; 4000 struct ieee802_1x_mka_participant *p; 4001 4002 if (!kay) 4003 return 0; 4004 4005 pos = buf; 4006 end = buf + buflen; 4007 4008 res = os_snprintf(pos, end - pos, 4009 "PAE KaY status=%s\n" 4010 "Authenticated=%s\n" 4011 "Secured=%s\n" 4012 "Failed=%s\n" 4013 "Actor Priority=%u\n" 4014 "Key Server Priority=%u\n" 4015 "Is Key Server=%s\n" 4016 "Number of Keys Distributed=%u\n" 4017 "Number of Keys Received=%u\n" 4018 "MKA Hello Time=%u\n", 4019 kay->active ? "Active" : "Not-Active", 4020 kay->authenticated ? "Yes" : "No", 4021 kay->secured ? "Yes" : "No", 4022 kay->failed ? "Yes" : "No", 4023 kay->actor_priority, 4024 kay->key_server_priority, 4025 kay->is_key_server ? "Yes" : "No", 4026 kay->dist_kn - 1, 4027 kay->rcvd_keys, 4028 kay->mka_hello_time); 4029 if (os_snprintf_error(buflen, res)) 4030 return 0; 4031 pos += res; 4032 4033 res = os_snprintf(pos, end - pos, 4034 "actor_sci=%s\n", sci_txt(&kay->actor_sci)); 4035 if (os_snprintf_error(buflen, res)) 4036 return end - pos; 4037 pos += res; 4038 4039 res = os_snprintf(pos, end - pos, 4040 "key_server_sci=%s\n", sci_txt(&kay->key_server_sci)); 4041 if (os_snprintf_error(buflen, res)) 4042 return end - pos; 4043 pos += res; 4044 4045 count = 0; 4046 dl_list_for_each(p, &kay->participant_list, 4047 struct ieee802_1x_mka_participant, list) { 4048 char *pos2 = pos; 4049 4050 res = os_snprintf(pos2, end - pos2, "participant_idx=%d\nckn=", 4051 count); 4052 if (os_snprintf_error(buflen, res)) 4053 return end - pos; 4054 pos2 += res; 4055 count++; 4056 4057 pos2 += wpa_snprintf_hex(pos2, end - pos2, p->ckn.name, 4058 p->ckn.len); 4059 4060 res = os_snprintf(pos2, end - pos2, 4061 "\nmi=%s\n" 4062 "mn=%u\n" 4063 "active=%s\n" 4064 "participant=%s\n" 4065 "retain=%s\n" 4066 "live_peers=%u\n" 4067 "potential_peers=%u\n" 4068 "is_key_server=%s\n" 4069 "is_elected=%s\n", 4070 mi_txt(p->mi), p->mn, 4071 yes_no(p->active), 4072 yes_no(p->participant), 4073 yes_no(p->retain), 4074 dl_list_len(&p->live_peers), 4075 dl_list_len(&p->potential_peers), 4076 yes_no(p->is_key_server), 4077 yes_no(p->is_elected)); 4078 if (os_snprintf_error(buflen, res)) 4079 return end - pos; 4080 pos2 += res; 4081 pos = pos2; 4082 } 4083 4084 return pos - buf; 4085 } 4086 4087 4088 static const char * true_false(bool val) 4089 { 4090 return val ? "true" : "false"; 4091 } 4092 4093 4094 static const char * activate_control_txt(enum activate_ctrl activate) 4095 { 4096 switch (activate) { 4097 case DEFAULT: 4098 return "default"; 4099 case DISABLED: 4100 return "disabled"; 4101 case ON_OPER_UP: 4102 return "onOperUp"; 4103 case ALWAYS: 4104 return "always"; 4105 } 4106 4107 return "?"; 4108 } 4109 4110 4111 static char * mka_mib_peer(struct dl_list *peers, bool live, char *buf, 4112 char *end) 4113 { 4114 char *pos = buf; 4115 struct ieee802_1x_kay_peer *p; 4116 int res; 4117 4118 dl_list_for_each(p, peers, struct ieee802_1x_kay_peer, list) { 4119 res = os_snprintf(pos, end - pos, 4120 "ieee8021XKayMkaPeerListMI=%s\n" 4121 "ieee8021XKayMkaPeerListMN=%u\n" 4122 "ieee8021XKayMkaPeerListType=%u\n" 4123 "ieee8021XKayMkaPeerListSCI=%s\n", 4124 mi_txt(p->mi), 4125 p->mn, 4126 live ? 1 : 2, 4127 sci_txt(&p->sci)); 4128 if (os_snprintf_error(end - pos, res)) 4129 return pos; 4130 pos += res; 4131 } 4132 4133 return pos; 4134 } 4135 4136 4137 int ieee802_1x_kay_get_mib(struct ieee802_1x_kay *kay, char *buf, 4138 size_t buflen) 4139 { 4140 char *pos, *end; 4141 int res; 4142 struct ieee802_1x_mka_participant *p; 4143 4144 if (!kay) 4145 return 0; 4146 4147 pos = buf; 4148 end = buf + buflen; 4149 4150 dl_list_for_each(p, &kay->participant_list, 4151 struct ieee802_1x_mka_participant, list) { 4152 char *pos2 = pos; 4153 4154 res = os_snprintf(pos2, end - pos2, "ieee8021XKayMkaPartCKN="); 4155 if (os_snprintf_error(buflen, res)) 4156 return end - pos; 4157 pos2 += res; 4158 4159 pos2 += wpa_snprintf_hex(pos2, end - pos2, p->ckn.name, 4160 p->ckn.len); 4161 4162 res = os_snprintf(pos2, end - pos2, 4163 "\nieee8021XKayMkaPartCached=%s\n" 4164 "ieee8021XKayMkaPartActive=%s\n" 4165 "ieee8021XKayMkaPartRetain=%s\n" 4166 "ieee8021XKayMkaPartActivateControl=%s\n" 4167 "ieee8021XKayMkaPartPrincipal=%s\n", 4168 true_false(p->cached), 4169 true_false(p->active), 4170 true_false(p->retain), 4171 activate_control_txt(p->activate), 4172 true_false(p->principal)); 4173 if (os_snprintf_error(buflen, res)) 4174 return end - pos; 4175 pos2 += res; 4176 pos = pos2; 4177 4178 pos = mka_mib_peer(&p->live_peers, true, pos, end); 4179 pos = mka_mib_peer(&p->potential_peers, false, pos, end); 4180 } 4181 4182 return pos - buf; 4183 } 4184 4185 #endif /* CONFIG_CTRL_IFACE */ 4186