1/* 2 * IEEE 802.1X-2010 Key Agree 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 PENDING_PN_EXHAUSTION 0xC0000000 31 32/* IEEE Std 802.1X-2010, Table 9-1 - MKA Algorithm Agility */ 33#define MKA_ALGO_AGILITY_2009 { 0x00, 0x80, 0xC2, 0x01 } 34static u8 mka_algo_agility[4] = MKA_ALGO_AGILITY_2009; 35 36/* IEEE802.1AE-2006 Table 14-1 MACsec Cipher Suites */ 37static struct macsec_ciphersuite cipher_suite_tbl[] = { 38 /* GCM-AES-128 */ 39 { 40 CS_ID_GCM_AES_128, 41 CS_NAME_GCM_AES_128, 42 MACSEC_CAP_INTEG_AND_CONF_0_30_50, 43 16, 44 45 0 /* index */ 46 }, 47}; 48#define CS_TABLE_SIZE (ARRAY_SIZE(cipher_suite_tbl)) 49#define DEFAULT_CS_INDEX 0 50 51static struct mka_alg mka_alg_tbl[] = { 52 { 53 MKA_ALGO_AGILITY_2009, 54 /* 128-bit CAK, KEK, ICK, ICV */ 55 16, 16, 16, 16, 56 ieee802_1x_cak_128bits_aes_cmac, 57 ieee802_1x_ckn_128bits_aes_cmac, 58 ieee802_1x_kek_128bits_aes_cmac, 59 ieee802_1x_ick_128bits_aes_cmac, 60 ieee802_1x_icv_128bits_aes_cmac, 61 62 1, /* index */ 63 }, 64}; 65#define MKA_ALG_TABLE_SIZE (ARRAY_SIZE(mka_alg_tbl)) 66 67 68static int is_ki_equal(struct ieee802_1x_mka_ki *ki1, 69 struct ieee802_1x_mka_ki *ki2) 70{ 71 return os_memcmp(ki1->mi, ki2->mi, MI_LEN) == 0 && 72 ki1->kn == ki2->kn; 73} 74 75 76struct mka_param_body_handler { 77 int (*body_tx)(struct ieee802_1x_mka_participant *participant, 78 struct wpabuf *buf); 79 int (*body_rx)(struct ieee802_1x_mka_participant *participant, 80 const u8 *mka_msg, size_t msg_len); 81 int (*body_length)(struct ieee802_1x_mka_participant *participant); 82 Boolean (*body_present)(struct ieee802_1x_mka_participant *participant); 83}; 84 85 86static void set_mka_param_body_len(void *body, unsigned int len) 87{ 88 struct ieee802_1x_mka_hdr *hdr = body; 89 hdr->length = (len >> 8) & 0x0f; 90 hdr->length1 = len & 0xff; 91} 92 93 94static unsigned int get_mka_param_body_len(const void *body) 95{ 96 const struct ieee802_1x_mka_hdr *hdr = body; 97 return (hdr->length << 8) | hdr->length1; 98} 99 100 101static int get_mka_param_body_type(const void *body) 102{ 103 const struct ieee802_1x_mka_hdr *hdr = body; 104 return hdr->type; 105} 106 107 108/** 109 * ieee802_1x_mka_dump_basic_body - 110 */ 111static void 112ieee802_1x_mka_dump_basic_body(struct ieee802_1x_mka_basic_body *body) 113{ 114 size_t body_len; 115 116 if (!body) 117 return; 118 119 body_len = get_mka_param_body_len(body); 120 wpa_printf(MSG_DEBUG, "*** MKA Basic Parameter set ***"); 121 wpa_printf(MSG_DEBUG, "\tVersion.......: %d", body->version); 122 wpa_printf(MSG_DEBUG, "\tPriority......: %d", body->priority); 123 wpa_printf(MSG_DEBUG, "\tKeySvr........: %d", body->key_server); 124 wpa_printf(MSG_DEBUG, "\tMACSecDesired.: %d", body->macsec_desired); 125 wpa_printf(MSG_DEBUG, "\tMACSecCapable.: %d", body->macsec_capbility); 126 wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len); 127 wpa_printf(MSG_DEBUG, "\tSCI MAC.......: " MACSTR, 128 MAC2STR(body->actor_sci.addr)); 129 wpa_printf(MSG_DEBUG, "\tSCI Port .....: %d", 130 be_to_host16(body->actor_sci.port)); 131 wpa_hexdump(MSG_DEBUG, "\tMember Id.....:", 132 body->actor_mi, sizeof(body->actor_mi)); 133 wpa_printf(MSG_DEBUG, "\tMessage Number: %d", 134 be_to_host32(body->actor_mn)); 135 wpa_hexdump(MSG_DEBUG, "\tAlgo Agility..:", 136 body->algo_agility, sizeof(body->algo_agility)); 137 wpa_hexdump_ascii(MSG_DEBUG, "\tCAK Name......:", body->ckn, 138 body_len + MKA_HDR_LEN - sizeof(*body)); 139} 140 141 142/** 143 * ieee802_1x_mka_dump_peer_body - 144 */ 145static void 146ieee802_1x_mka_dump_peer_body(struct ieee802_1x_mka_peer_body *body) 147{ 148 size_t body_len; 149 size_t i; 150 u8 *mi; 151 u32 mn; 152 153 if (body == NULL) 154 return; 155 156 body_len = get_mka_param_body_len(body); 157 if (body->type == MKA_LIVE_PEER_LIST) { 158 wpa_printf(MSG_DEBUG, "*** Live Peer List ***"); 159 wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len); 160 } else if (body->type == MKA_POTENTIAL_PEER_LIST) { 161 wpa_printf(MSG_DEBUG, "*** Potential Live Peer List ***"); 162 wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len); 163 } 164 165 for (i = 0; i < body_len; i += MI_LEN + sizeof(mn)) { 166 mi = body->peer + i; 167 os_memcpy(&mn, mi + MI_LEN, sizeof(mn)); 168 wpa_hexdump_ascii(MSG_DEBUG, "\tMember Id.....:", mi, MI_LEN); 169 wpa_printf(MSG_DEBUG, "\tMessage Number: %d", be_to_host32(mn)); 170 } 171} 172 173 174/** 175 * ieee802_1x_mka_dump_dist_sak_body - 176 */ 177static void 178ieee802_1x_mka_dump_dist_sak_body(struct ieee802_1x_mka_dist_sak_body *body) 179{ 180 size_t body_len; 181 182 if (body == NULL) 183 return; 184 185 body_len = get_mka_param_body_len(body); 186 wpa_printf(MSG_INFO, "*** Distributed SAK ***"); 187 wpa_printf(MSG_INFO, "\tDistributed AN........: %d", body->dan); 188 wpa_printf(MSG_INFO, "\tConfidentiality Offset: %d", 189 body->confid_offset); 190 wpa_printf(MSG_INFO, "\tBody Length...........: %d", (int) body_len); 191 if (!body_len) 192 return; 193 194 wpa_printf(MSG_INFO, "\tKey Number............: %d", 195 be_to_host32(body->kn)); 196 wpa_hexdump(MSG_INFO, "\tAES Key Wrap of SAK...:", body->sak, 24); 197} 198 199 200static const char * yes_no(int val) 201{ 202 return val ? "Yes" : "No"; 203} 204 205 206/** 207 * ieee802_1x_mka_dump_sak_use_body - 208 */ 209static void 210ieee802_1x_mka_dump_sak_use_body(struct ieee802_1x_mka_sak_use_body *body) 211{ 212 int body_len; 213 214 if (body == NULL) 215 return; 216 217 body_len = get_mka_param_body_len(body); 218 wpa_printf(MSG_DEBUG, "*** MACsec SAK Use ***"); 219 wpa_printf(MSG_DEBUG, "\tLatest Key AN....: %d", body->lan); 220 wpa_printf(MSG_DEBUG, "\tLatest Key Tx....: %s", yes_no(body->ltx)); 221 wpa_printf(MSG_DEBUG, "\tLatest Key Rx....: %s", yes_no(body->lrx)); 222 wpa_printf(MSG_DEBUG, "\tOld Key AN....: %d", body->oan); 223 wpa_printf(MSG_DEBUG, "\tOld Key Tx....: %s", yes_no(body->otx)); 224 wpa_printf(MSG_DEBUG, "\tOld Key Rx....: %s", yes_no(body->orx)); 225 wpa_printf(MSG_DEBUG, "\tPlain Key Tx....: %s", yes_no(body->ptx)); 226 wpa_printf(MSG_DEBUG, "\tPlain Key Rx....: %s", yes_no(body->prx)); 227 wpa_printf(MSG_DEBUG, "\tDelay Protect....: %s", 228 yes_no(body->delay_protect)); 229 wpa_printf(MSG_DEBUG, "\tBody Length......: %d", body_len); 230 if (!body_len) 231 return; 232 233 wpa_hexdump(MSG_DEBUG, "\tKey Server MI....:", 234 body->lsrv_mi, sizeof(body->lsrv_mi)); 235 wpa_printf(MSG_DEBUG, "\tKey Number.......: %u", 236 be_to_host32(body->lkn)); 237 wpa_printf(MSG_DEBUG, "\tLowest PN........: %u", 238 be_to_host32(body->llpn)); 239 wpa_hexdump_ascii(MSG_DEBUG, "\tOld Key Server MI....:", 240 body->osrv_mi, sizeof(body->osrv_mi)); 241 wpa_printf(MSG_DEBUG, "\tOld Key Number.......: %u", 242 be_to_host32(body->okn)); 243 wpa_printf(MSG_DEBUG, "\tOld Lowest PN........: %u", 244 be_to_host32(body->olpn)); 245} 246 247 248/** 249 * ieee802_1x_kay_get_participant - 250 */ 251static struct ieee802_1x_mka_participant * 252ieee802_1x_kay_get_participant(struct ieee802_1x_kay *kay, const u8 *ckn) 253{ 254 struct ieee802_1x_mka_participant *participant; 255 256 dl_list_for_each(participant, &kay->participant_list, 257 struct ieee802_1x_mka_participant, list) { 258 if (os_memcmp(participant->ckn.name, ckn, 259 participant->ckn.len) == 0) 260 return participant; 261 } 262 263 wpa_printf(MSG_DEBUG, "KaY: participant is not found"); 264 265 return NULL; 266} 267 268 269/** 270 * ieee802_1x_kay_get_principal_participant - 271 */ 272static struct ieee802_1x_mka_participant * 273ieee802_1x_kay_get_principal_participant(struct ieee802_1x_kay *kay) 274{ 275 struct ieee802_1x_mka_participant *participant; 276 277 dl_list_for_each(participant, &kay->participant_list, 278 struct ieee802_1x_mka_participant, list) { 279 if (participant->principal) 280 return participant; 281 } 282 283 wpa_printf(MSG_DEBUG, "KaY: principal participant is not founded"); 284 return NULL; 285} 286 287 288static struct ieee802_1x_kay_peer * get_peer_mi(struct dl_list *peers, 289 const u8 *mi) 290{ 291 struct ieee802_1x_kay_peer *peer; 292 293 dl_list_for_each(peer, peers, struct ieee802_1x_kay_peer, list) { 294 if (os_memcmp(peer->mi, mi, MI_LEN) == 0) 295 return peer; 296 } 297 298 return NULL; 299} 300 301 302/** 303 * ieee802_1x_kay_is_in_potential_peer 304 */ 305static Boolean 306ieee802_1x_kay_is_in_potential_peer( 307 struct ieee802_1x_mka_participant *participant, const u8 *mi) 308{ 309 return get_peer_mi(&participant->potential_peers, mi) != NULL; 310} 311 312 313/** 314 * ieee802_1x_kay_is_in_live_peer 315 */ 316static Boolean 317ieee802_1x_kay_is_in_live_peer( 318 struct ieee802_1x_mka_participant *participant, const u8 *mi) 319{ 320 return get_peer_mi(&participant->live_peers, mi) != NULL; 321} 322 323 324/** 325 * ieee802_1x_kay_is_in_peer 326 */ 327static Boolean 328ieee802_1x_kay_is_in_peer(struct ieee802_1x_mka_participant *participant, 329 const u8 *mi) 330{ 331 return ieee802_1x_kay_is_in_live_peer(participant, mi) || 332 ieee802_1x_kay_is_in_potential_peer(participant, mi); 333} 334 335 336/** 337 * ieee802_1x_kay_get_peer 338 */ 339static struct ieee802_1x_kay_peer * 340ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant, 341 const u8 *mi) 342{ 343 struct ieee802_1x_kay_peer *peer; 344 345 peer = get_peer_mi(&participant->live_peers, mi); 346 if (peer) 347 return peer; 348 349 return get_peer_mi(&participant->potential_peers, mi); 350} 351 352 353/** 354 * ieee802_1x_kay_get_live_peer 355 */ 356static struct ieee802_1x_kay_peer * 357ieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant *participant, 358 const u8 *mi) 359{ 360 return get_peer_mi(&participant->live_peers, mi); 361} 362 363 364/** 365 * ieee802_1x_kay_get_cipher_suite 366 */ 367static struct macsec_ciphersuite * 368ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant, 369 u8 *cs_id) 370{ 371 unsigned int i; 372 373 for (i = 0; i < CS_TABLE_SIZE; i++) { 374 if (os_memcmp(cipher_suite_tbl[i].id, cs_id, CS_ID_LEN) == 0) 375 break; 376 } 377 if (i >= CS_TABLE_SIZE) 378 return NULL; 379 380 return &cipher_suite_tbl[i]; 381} 382 383 384/** 385 * ieee802_1x_kay_get_peer_sci 386 */ 387static struct ieee802_1x_kay_peer * 388ieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant *participant, 389 const struct ieee802_1x_mka_sci *sci) 390{ 391 struct ieee802_1x_kay_peer *peer; 392 393 dl_list_for_each(peer, &participant->live_peers, 394 struct ieee802_1x_kay_peer, list) { 395 if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0) 396 return peer; 397 } 398 399 dl_list_for_each(peer, &participant->potential_peers, 400 struct ieee802_1x_kay_peer, list) { 401 if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0) 402 return peer; 403 } 404 405 return NULL; 406} 407 408 409/** 410 * ieee802_1x_kay_init_receive_sa - 411 */ 412static struct receive_sa * 413ieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn, 414 struct data_key *key) 415{ 416 struct receive_sa *psa; 417 418 if (!psc || !key) 419 return NULL; 420 421 psa = os_zalloc(sizeof(*psa)); 422 if (!psa) { 423 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 424 return NULL; 425 } 426 427 psa->pkey = key; 428 psa->lowest_pn = lowest_pn; 429 psa->next_pn = lowest_pn; 430 psa->an = an; 431 psa->sc = psc; 432 433 os_get_time(&psa->created_time); 434 psa->in_use = FALSE; 435 436 dl_list_add(&psc->sa_list, &psa->list); 437 wpa_printf(MSG_DEBUG, 438 "KaY: Create receive SA(AN: %d lowest_pn: %u of SC(channel: %d)", 439 (int) an, lowest_pn, psc->channel); 440 441 return psa; 442} 443 444 445/** 446 * ieee802_1x_kay_deinit_receive_sa - 447 */ 448static void ieee802_1x_kay_deinit_receive_sa(struct receive_sa *psa) 449{ 450 psa->pkey = NULL; 451 wpa_printf(MSG_DEBUG, 452 "KaY: Delete receive SA(an: %d) of SC(channel: %d)", 453 psa->an, psa->sc->channel); 454 dl_list_del(&psa->list); 455 os_free(psa); 456} 457 458 459/** 460 * ieee802_1x_kay_init_receive_sc - 461 */ 462static struct receive_sc * 463ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci, 464 int channel) 465{ 466 struct receive_sc *psc; 467 468 if (!psci) 469 return NULL; 470 471 psc = os_zalloc(sizeof(*psc)); 472 if (!psc) { 473 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 474 return NULL; 475 } 476 477 os_memcpy(&psc->sci, psci, sizeof(psc->sci)); 478 psc->channel = channel; 479 480 os_get_time(&psc->created_time); 481 psc->receiving = FALSE; 482 483 dl_list_init(&psc->sa_list); 484 wpa_printf(MSG_DEBUG, "KaY: Create receive SC(channel: %d)", channel); 485 wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)psci, sizeof(*psci)); 486 487 return psc; 488} 489 490 491/** 492 * ieee802_1x_kay_deinit_receive_sc - 493 **/ 494static void 495ieee802_1x_kay_deinit_receive_sc( 496 struct ieee802_1x_mka_participant *participant, struct receive_sc *psc) 497{ 498 struct receive_sa *psa, *pre_sa; 499 500 wpa_printf(MSG_DEBUG, "KaY: Delete receive SC(channel: %d)", 501 psc->channel); 502 dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, 503 list) { 504 secy_disable_receive_sa(participant->kay, psa); 505 ieee802_1x_kay_deinit_receive_sa(psa); 506 } 507 dl_list_del(&psc->list); 508 os_free(psc); 509} 510 511 512/** 513 * ieee802_1x_kay_create_live_peer 514 */ 515static struct ieee802_1x_kay_peer * 516ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant, 517 u8 *mi, u32 mn) 518{ 519 struct ieee802_1x_kay_peer *peer; 520 struct receive_sc *rxsc; 521 u32 sc_ch = 0; 522 523 peer = os_zalloc(sizeof(*peer)); 524 if (peer == NULL) { 525 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 526 return NULL; 527 } 528 529 os_memcpy(peer->mi, mi, MI_LEN); 530 peer->mn = mn; 531 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 532 peer->sak_used = FALSE; 533 os_memcpy(&peer->sci, &participant->current_peer_sci, 534 sizeof(peer->sci)); 535 dl_list_add(&participant->live_peers, &peer->list); 536 537 secy_get_available_receive_sc(participant->kay, &sc_ch); 538 539 rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci, sc_ch); 540 if (!rxsc) 541 return NULL; 542 543 dl_list_add(&participant->rxsc_list, &rxsc->list); 544 secy_create_receive_sc(participant->kay, rxsc); 545 546 wpa_printf(MSG_DEBUG, "KaY: Live peer created"); 547 wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi)); 548 wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 549 wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN); 550 wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port); 551 552 return peer; 553} 554 555 556/** 557 * ieee802_1x_kay_create_potential_peer 558 */ 559static struct ieee802_1x_kay_peer * 560ieee802_1x_kay_create_potential_peer( 561 struct ieee802_1x_mka_participant *participant, const u8 *mi, u32 mn) 562{ 563 struct ieee802_1x_kay_peer *peer; 564 565 peer = os_zalloc(sizeof(*peer)); 566 if (peer == NULL) { 567 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 568 return NULL; 569 } 570 571 os_memcpy(peer->mi, mi, MI_LEN); 572 peer->mn = mn; 573 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 574 peer->sak_used = FALSE; 575 576 dl_list_add(&participant->potential_peers, &peer->list); 577 578 wpa_printf(MSG_DEBUG, "KaY: potential peer created"); 579 wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi)); 580 wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 581 wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN); 582 wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port); 583 584 return peer; 585} 586 587 588/** 589 * ieee802_1x_kay_move_live_peer 590 */ 591static struct ieee802_1x_kay_peer * 592ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant, 593 u8 *mi, u32 mn) 594{ 595 struct ieee802_1x_kay_peer *peer; 596 struct receive_sc *rxsc; 597 u32 sc_ch = 0; 598 599 dl_list_for_each(peer, &participant->potential_peers, 600 struct ieee802_1x_kay_peer, list) { 601 if (os_memcmp(peer->mi, mi, MI_LEN) == 0) 602 break; 603 } 604 605 os_memcpy(&peer->sci, &participant->current_peer_sci, 606 sizeof(peer->sci)); 607 peer->mn = mn; 608 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 609 610 wpa_printf(MSG_DEBUG, "KaY: move potential peer to live peer"); 611 wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi)); 612 wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 613 wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN); 614 wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port); 615 616 dl_list_del(&peer->list); 617 dl_list_add_tail(&participant->live_peers, &peer->list); 618 619 secy_get_available_receive_sc(participant->kay, &sc_ch); 620 621 rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci, sc_ch); 622 if (!rxsc) 623 return NULL; 624 625 dl_list_add(&participant->rxsc_list, &rxsc->list); 626 secy_create_receive_sc(participant->kay, rxsc); 627 628 return peer; 629} 630 631 632 633/** 634 * ieee802_1x_mka_basic_body_present - 635 */ 636static Boolean 637ieee802_1x_mka_basic_body_present( 638 struct ieee802_1x_mka_participant *participant) 639{ 640 return TRUE; 641} 642 643 644/** 645 * ieee802_1x_mka_basic_body_length - 646 */ 647static int 648ieee802_1x_mka_basic_body_length(struct ieee802_1x_mka_participant *participant) 649{ 650 int length; 651 652 length = sizeof(struct ieee802_1x_mka_basic_body); 653 length += participant->ckn.len; 654 return (length + 0x3) & ~0x3; 655} 656 657 658/** 659 * ieee802_1x_mka_encode_basic_body 660 */ 661static int 662ieee802_1x_mka_encode_basic_body( 663 struct ieee802_1x_mka_participant *participant, 664 struct wpabuf *buf) 665{ 666 struct ieee802_1x_mka_basic_body *body; 667 struct ieee802_1x_kay *kay = participant->kay; 668 unsigned int length = ieee802_1x_mka_basic_body_length(participant); 669 670 body = wpabuf_put(buf, length); 671 672 body->version = kay->mka_version; 673 body->priority = kay->actor_priority; 674 if (participant->is_elected) 675 body->key_server = participant->is_key_server; 676 else 677 body->key_server = participant->can_be_key_server; 678 679 body->macsec_desired = kay->macsec_desired; 680 body->macsec_capbility = kay->macsec_capable; 681 set_mka_param_body_len(body, length - MKA_HDR_LEN); 682 683 os_memcpy(body->actor_sci.addr, kay->actor_sci.addr, 684 sizeof(kay->actor_sci.addr)); 685 body->actor_sci.port = host_to_be16(kay->actor_sci.port); 686 687 os_memcpy(body->actor_mi, participant->mi, sizeof(body->actor_mi)); 688 participant->mn = participant->mn + 1; 689 body->actor_mn = host_to_be32(participant->mn); 690 os_memcpy(body->algo_agility, participant->kay->algo_agility, 691 sizeof(body->algo_agility)); 692 693 os_memcpy(body->ckn, participant->ckn.name, participant->ckn.len); 694 695 ieee802_1x_mka_dump_basic_body(body); 696 697 return 0; 698} 699 700 701/** 702 * ieee802_1x_mka_decode_basic_body - 703 */ 704static struct ieee802_1x_mka_participant * 705ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg, 706 size_t msg_len) 707{ 708 struct ieee802_1x_mka_participant *participant; 709 const struct ieee802_1x_mka_basic_body *body; 710 struct ieee802_1x_kay_peer *peer; 711 712 body = (const struct ieee802_1x_mka_basic_body *) mka_msg; 713 714 if (body->version > MKA_VERSION_ID) { 715 wpa_printf(MSG_DEBUG, 716 "KaY: peer's version(%d) greater than mka current version(%d)", 717 body->version, MKA_VERSION_ID); 718 } 719 if (kay->is_obliged_key_server && body->key_server) { 720 wpa_printf(MSG_DEBUG, "I must be as key server"); 721 return NULL; 722 } 723 724 participant = ieee802_1x_kay_get_participant(kay, body->ckn); 725 if (!participant) { 726 wpa_printf(MSG_DEBUG, "Peer is not included in my CA"); 727 return NULL; 728 } 729 730 /* If the peer's MI is my MI, I will choose new MI */ 731 if (os_memcmp(body->actor_mi, participant->mi, MI_LEN) == 0) { 732 if (os_get_random(participant->mi, sizeof(participant->mi)) < 0) 733 return NULL; 734 participant->mn = 0; 735 } 736 737 os_memcpy(participant->current_peer_id.mi, body->actor_mi, MI_LEN); 738 participant->current_peer_id.mn = be_to_host32(body->actor_mn); 739 os_memcpy(participant->current_peer_sci.addr, body->actor_sci.addr, 740 sizeof(participant->current_peer_sci.addr)); 741 participant->current_peer_sci.port = be_to_host16(body->actor_sci.port); 742 743 /* handler peer */ 744 peer = ieee802_1x_kay_get_peer(participant, body->actor_mi); 745 if (!peer) { 746 /* Check duplicated SCI */ 747 /* TODO: What policy should be applied to detect duplicated SCI 748 * is active attacker or a valid peer whose MI is be changed? 749 */ 750 peer = ieee802_1x_kay_get_peer_sci(participant, 751 &body->actor_sci); 752 if (peer) { 753 wpa_printf(MSG_WARNING, 754 "KaY: duplicated SCI detected, Maybe active attacker"); 755 dl_list_del(&peer->list); 756 os_free(peer); 757 } 758 759 peer = ieee802_1x_kay_create_potential_peer( 760 participant, body->actor_mi, 761 be_to_host32(body->actor_mn)); 762 if (!peer) 763 return NULL; 764 765 peer->macsec_desired = body->macsec_desired; 766 peer->macsec_capbility = body->macsec_capbility; 767 peer->is_key_server = (Boolean) body->key_server; 768 peer->key_server_priority = body->priority; 769 } else if (peer->mn < be_to_host32(body->actor_mn)) { 770 peer->mn = be_to_host32(body->actor_mn); 771 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 772 peer->macsec_desired = body->macsec_desired; 773 peer->macsec_capbility = body->macsec_capbility; 774 peer->is_key_server = (Boolean) body->key_server; 775 peer->key_server_priority = body->priority; 776 } else { 777 wpa_printf(MSG_WARNING, "KaY: The peer MN have received"); 778 return NULL; 779 } 780 781 return participant; 782} 783 784 785/** 786 * ieee802_1x_mka_live_peer_body_present 787 */ 788static Boolean 789ieee802_1x_mka_live_peer_body_present( 790 struct ieee802_1x_mka_participant *participant) 791{ 792 return !dl_list_empty(&participant->live_peers); 793} 794 795 796/** 797 * ieee802_1x_kay_get_live_peer_length 798 */ 799static int 800ieee802_1x_mka_get_live_peer_length( 801 struct ieee802_1x_mka_participant *participant) 802{ 803 int len = MKA_HDR_LEN; 804 struct ieee802_1x_kay_peer *peer; 805 806 dl_list_for_each(peer, &participant->live_peers, 807 struct ieee802_1x_kay_peer, list) 808 len += sizeof(struct ieee802_1x_mka_peer_id); 809 810 return (len + 0x3) & ~0x3; 811} 812 813 814/** 815 * ieee802_1x_mka_encode_live_peer_body - 816 */ 817static int 818ieee802_1x_mka_encode_live_peer_body( 819 struct ieee802_1x_mka_participant *participant, 820 struct wpabuf *buf) 821{ 822 struct ieee802_1x_mka_peer_body *body; 823 struct ieee802_1x_kay_peer *peer; 824 unsigned int length; 825 struct ieee802_1x_mka_peer_id *body_peer; 826 827 length = ieee802_1x_mka_get_live_peer_length(participant); 828 body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body)); 829 830 body->type = MKA_LIVE_PEER_LIST; 831 set_mka_param_body_len(body, length - MKA_HDR_LEN); 832 833 dl_list_for_each(peer, &participant->live_peers, 834 struct ieee802_1x_kay_peer, list) { 835 body_peer = wpabuf_put(buf, 836 sizeof(struct ieee802_1x_mka_peer_id)); 837 os_memcpy(body_peer->mi, peer->mi, MI_LEN); 838 body_peer->mn = host_to_be32(peer->mn); 839 body_peer++; 840 } 841 842 ieee802_1x_mka_dump_peer_body(body); 843 return 0; 844} 845 846/** 847 * ieee802_1x_mka_potential_peer_body_present 848 */ 849static Boolean 850ieee802_1x_mka_potential_peer_body_present( 851 struct ieee802_1x_mka_participant *participant) 852{ 853 return !dl_list_empty(&participant->potential_peers); 854} 855 856 857/** 858 * ieee802_1x_kay_get_potential_peer_length 859 */ 860static int 861ieee802_1x_mka_get_potential_peer_length( 862 struct ieee802_1x_mka_participant *participant) 863{ 864 int len = MKA_HDR_LEN; 865 struct ieee802_1x_kay_peer *peer; 866 867 dl_list_for_each(peer, &participant->potential_peers, 868 struct ieee802_1x_kay_peer, list) 869 len += sizeof(struct ieee802_1x_mka_peer_id); 870 871 return (len + 0x3) & ~0x3; 872} 873 874 875/** 876 * ieee802_1x_mka_encode_potential_peer_body - 877 */ 878static int 879ieee802_1x_mka_encode_potential_peer_body( 880 struct ieee802_1x_mka_participant *participant, 881 struct wpabuf *buf) 882{ 883 struct ieee802_1x_mka_peer_body *body; 884 struct ieee802_1x_kay_peer *peer; 885 unsigned int length; 886 struct ieee802_1x_mka_peer_id *body_peer; 887 888 length = ieee802_1x_mka_get_potential_peer_length(participant); 889 body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body)); 890 891 body->type = MKA_POTENTIAL_PEER_LIST; 892 set_mka_param_body_len(body, length - MKA_HDR_LEN); 893 894 dl_list_for_each(peer, &participant->potential_peers, 895 struct ieee802_1x_kay_peer, list) { 896 body_peer = wpabuf_put(buf, 897 sizeof(struct ieee802_1x_mka_peer_id)); 898 os_memcpy(body_peer->mi, peer->mi, MI_LEN); 899 body_peer->mn = host_to_be32(peer->mn); 900 body_peer++; 901 } 902 903 ieee802_1x_mka_dump_peer_body(body); 904 return 0; 905} 906 907 908/** 909 * ieee802_1x_mka_i_in_peerlist - 910 */ 911static Boolean 912ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant, 913 const u8 *mka_msg, size_t msg_len) 914{ 915 Boolean included = FALSE; 916 struct ieee802_1x_mka_hdr *hdr; 917 size_t body_len; 918 size_t left_len; 919 int body_type; 920 u32 peer_mn; 921 const u8 *peer_mi; 922 const u8 *pos; 923 size_t i; 924 925 pos = mka_msg; 926 left_len = msg_len; 927 while (left_len > (MKA_HDR_LEN + DEFAULT_ICV_LEN)) { 928 hdr = (struct ieee802_1x_mka_hdr *) pos; 929 body_len = get_mka_param_body_len(hdr); 930 body_type = get_mka_param_body_type(hdr); 931 932 if (body_type != MKA_LIVE_PEER_LIST && 933 body_type != MKA_POTENTIAL_PEER_LIST) 934 goto SKIP_PEER; 935 936 ieee802_1x_mka_dump_peer_body( 937 (struct ieee802_1x_mka_peer_body *)pos); 938 939 if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) { 940 wpa_printf(MSG_ERROR, 941 "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV", 942 (int) left_len, (int) MKA_HDR_LEN, 943 (int) body_len, DEFAULT_ICV_LEN); 944 goto SKIP_PEER; 945 } 946 947 if ((body_len % 16) != 0) { 948 wpa_printf(MSG_ERROR, 949 "KaY: MKA Peer Packet Body Length (%d bytes) should multiple of 16 octets", 950 (int) body_len); 951 goto SKIP_PEER; 952 } 953 954 for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) { 955 peer_mi = MKA_HDR_LEN + pos + i; 956 os_memcpy(&peer_mn, peer_mi + MI_LEN, sizeof(peer_mn)); 957 peer_mn = be_to_host32(peer_mn); 958 if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0 && 959 peer_mn == participant->mn) { 960 included = TRUE; 961 break; 962 } 963 } 964 965 if (included) 966 return TRUE; 967 968SKIP_PEER: 969 left_len -= body_len + MKA_HDR_LEN; 970 pos += body_len + MKA_HDR_LEN; 971 } 972 973 return FALSE; 974} 975 976 977/** 978 * ieee802_1x_mka_decode_live_peer_body - 979 */ 980static int ieee802_1x_mka_decode_live_peer_body( 981 struct ieee802_1x_mka_participant *participant, 982 const u8 *peer_msg, size_t msg_len) 983{ 984 const struct ieee802_1x_mka_hdr *hdr; 985 struct ieee802_1x_kay_peer *peer; 986 size_t body_len; 987 u32 peer_mn; 988 const u8 *peer_mi; 989 size_t i; 990 Boolean is_included; 991 992 is_included = ieee802_1x_kay_is_in_live_peer( 993 participant, participant->current_peer_id.mi); 994 995 hdr = (const struct ieee802_1x_mka_hdr *) peer_msg; 996 body_len = get_mka_param_body_len(hdr); 997 998 for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) { 999 peer_mi = MKA_HDR_LEN + peer_msg + i; 1000 os_memcpy(&peer_mn, peer_mi + MI_LEN, sizeof(peer_mn)); 1001 peer_mn = be_to_host32(peer_mn); 1002 1003 /* it is myself */ 1004 if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) { 1005 /* My message id is used by other participant */ 1006 if (peer_mn > participant->mn) { 1007 if (os_get_random(participant->mi, 1008 sizeof(participant->mi)) < 0) 1009 wpa_printf(MSG_DEBUG, 1010 "KaY: Could not update mi"); 1011 participant->mn = 0; 1012 } 1013 continue; 1014 } 1015 if (!is_included) 1016 continue; 1017 1018 peer = ieee802_1x_kay_get_peer(participant, peer_mi); 1019 if (NULL != peer) { 1020 peer->mn = peer_mn; 1021 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 1022 } else { 1023 if (!ieee802_1x_kay_create_potential_peer( 1024 participant, peer_mi, peer_mn)) { 1025 return -1; 1026 } 1027 } 1028 } 1029 1030 return 0; 1031} 1032 1033 1034/** 1035 * ieee802_1x_mka_decode_potential_peer_body - 1036 */ 1037static int 1038ieee802_1x_mka_decode_potential_peer_body( 1039 struct ieee802_1x_mka_participant *participant, 1040 const u8 *peer_msg, size_t msg_len) 1041{ 1042 struct ieee802_1x_mka_hdr *hdr; 1043 size_t body_len; 1044 u32 peer_mn; 1045 const u8 *peer_mi; 1046 size_t i; 1047 1048 hdr = (struct ieee802_1x_mka_hdr *) peer_msg; 1049 body_len = get_mka_param_body_len(hdr); 1050 1051 for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) { 1052 peer_mi = MKA_HDR_LEN + peer_msg + i; 1053 os_memcpy(&peer_mn, peer_mi + MI_LEN, sizeof(peer_mn)); 1054 peer_mn = be_to_host32(peer_mn); 1055 1056 /* it is myself */ 1057 if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) { 1058 /* My message id is used by other participant */ 1059 if (peer_mn > participant->mn) { 1060 if (os_get_random(participant->mi, 1061 sizeof(participant->mi)) < 0) 1062 wpa_printf(MSG_DEBUG, 1063 "KaY: Could not update mi"); 1064 participant->mn = 0; 1065 } 1066 continue; 1067 } 1068 } 1069 1070 return 0; 1071} 1072 1073 1074/** 1075 * ieee802_1x_mka_sak_use_body_present 1076 */ 1077static Boolean 1078ieee802_1x_mka_sak_use_body_present( 1079 struct ieee802_1x_mka_participant *participant) 1080{ 1081 if (participant->to_use_sak) 1082 return TRUE; 1083 else 1084 return FALSE; 1085} 1086 1087 1088/** 1089 * ieee802_1x_mka_get_sak_use_length 1090 */ 1091static int 1092ieee802_1x_mka_get_sak_use_length( 1093 struct ieee802_1x_mka_participant *participant) 1094{ 1095 int length = MKA_HDR_LEN; 1096 1097 if (participant->kay->macsec_desired && participant->advised_desired) 1098 length = sizeof(struct ieee802_1x_mka_sak_use_body); 1099 else 1100 length = MKA_HDR_LEN; 1101 1102 length = (length + 0x3) & ~0x3; 1103 1104 return length; 1105} 1106 1107 1108/** 1109 * 1110 */ 1111static u32 1112ieee802_1x_mka_get_lpn(struct ieee802_1x_mka_participant *principal, 1113 struct ieee802_1x_mka_ki *ki) 1114{ 1115 struct receive_sa *rxsa; 1116 struct receive_sc *rxsc; 1117 u32 lpn = 0; 1118 1119 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 1120 dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) 1121 { 1122 if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) { 1123 secy_get_receive_lowest_pn(principal->kay, 1124 rxsa); 1125 1126 lpn = lpn > rxsa->lowest_pn ? 1127 lpn : rxsa->lowest_pn; 1128 break; 1129 } 1130 } 1131 } 1132 1133 if (lpn == 0) 1134 lpn = 1; 1135 1136 return lpn; 1137} 1138 1139 1140/** 1141 * ieee802_1x_mka_encode_sak_use_body - 1142 */ 1143static int 1144ieee802_1x_mka_encode_sak_use_body( 1145 struct ieee802_1x_mka_participant *participant, 1146 struct wpabuf *buf) 1147{ 1148 struct ieee802_1x_mka_sak_use_body *body; 1149 unsigned int length; 1150 u32 pn = 1; 1151 1152 length = ieee802_1x_mka_get_sak_use_length(participant); 1153 body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_sak_use_body)); 1154 1155 body->type = MKA_SAK_USE; 1156 set_mka_param_body_len(body, length - MKA_HDR_LEN); 1157 1158 if (length == MKA_HDR_LEN) { 1159 body->ptx = TRUE; 1160 body->prx = TRUE; 1161 body->lan = 0; 1162 body->lrx = FALSE; 1163 body->ltx = FALSE; 1164 body->delay_protect = FALSE; 1165 return 0; 1166 } 1167 1168 /* data protect, lowest accept packet number */ 1169 body->delay_protect = participant->kay->macsec_replay_protect; 1170 pn = ieee802_1x_mka_get_lpn(participant, &participant->lki); 1171 if (pn > participant->kay->pn_exhaustion) { 1172 wpa_printf(MSG_WARNING, "KaY: My LPN exhaustion"); 1173 if (participant->is_key_server) 1174 participant->new_sak = TRUE; 1175 } 1176 1177 body->llpn = host_to_be32(pn); 1178 pn = ieee802_1x_mka_get_lpn(participant, &participant->oki); 1179 body->olpn = host_to_be32(pn); 1180 1181 /* plain tx, plain rx */ 1182 if (participant->kay->macsec_protect) 1183 body->ptx = FALSE; 1184 else 1185 body->ptx = TRUE; 1186 1187 if (participant->kay->macsec_validate == Strict) 1188 body->prx = FALSE; 1189 else 1190 body->prx = TRUE; 1191 1192 /* latest key: rx, tx, key server member identifier key number */ 1193 body->lan = participant->lan; 1194 os_memcpy(body->lsrv_mi, participant->lki.mi, 1195 sizeof(body->lsrv_mi)); 1196 body->lkn = host_to_be32(participant->lki.kn); 1197 body->lrx = participant->lrx; 1198 body->ltx = participant->ltx; 1199 1200 /* old key: rx, tx, key server member identifier key number */ 1201 body->oan = participant->oan; 1202 if (participant->oki.kn != participant->lki.kn && 1203 participant->oki.kn != 0) { 1204 body->otx = TRUE; 1205 body->orx = TRUE; 1206 os_memcpy(body->osrv_mi, participant->oki.mi, 1207 sizeof(body->osrv_mi)); 1208 body->okn = host_to_be32(participant->oki.kn); 1209 } else { 1210 body->otx = FALSE; 1211 body->orx = FALSE; 1212 } 1213 1214 /* set CP's variable */ 1215 if (body->ltx) { 1216 if (!participant->kay->tx_enable) 1217 participant->kay->tx_enable = TRUE; 1218 1219 if (!participant->kay->port_enable) 1220 participant->kay->port_enable = TRUE; 1221 } 1222 if (body->lrx) { 1223 if (!participant->kay->rx_enable) 1224 participant->kay->rx_enable = TRUE; 1225 } 1226 1227 ieee802_1x_mka_dump_sak_use_body(body); 1228 return 0; 1229} 1230 1231 1232/** 1233 * ieee802_1x_mka_decode_sak_use_body - 1234 */ 1235static int 1236ieee802_1x_mka_decode_sak_use_body( 1237 struct ieee802_1x_mka_participant *participant, 1238 const u8 *mka_msg, size_t msg_len) 1239{ 1240 struct ieee802_1x_mka_hdr *hdr; 1241 struct ieee802_1x_mka_sak_use_body *body; 1242 struct ieee802_1x_kay_peer *peer; 1243 struct transmit_sa *txsa; 1244 struct data_key *sa_key = NULL; 1245 size_t body_len; 1246 struct ieee802_1x_mka_ki ki; 1247 u32 lpn; 1248 Boolean all_receiving; 1249 Boolean founded; 1250 1251 if (!participant->principal) { 1252 wpa_printf(MSG_WARNING, "KaY: Participant is not principal"); 1253 return -1; 1254 } 1255 peer = ieee802_1x_kay_get_live_peer(participant, 1256 participant->current_peer_id.mi); 1257 if (!peer) { 1258 wpa_printf(MSG_WARNING, "KaY: the peer is not my live peer"); 1259 return -1; 1260 } 1261 1262 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1263 body_len = get_mka_param_body_len(hdr); 1264 body = (struct ieee802_1x_mka_sak_use_body *) mka_msg; 1265 ieee802_1x_mka_dump_sak_use_body(body); 1266 1267 if ((body_len != 0) && (body_len < 40)) { 1268 wpa_printf(MSG_ERROR, 1269 "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 40, or more octets", 1270 (int) body_len); 1271 return -1; 1272 } 1273 1274 /* TODO: what action should I take when peer does not support MACsec */ 1275 if (body_len == 0) { 1276 wpa_printf(MSG_WARNING, "KaY: Peer does not support MACsec"); 1277 return 0; 1278 } 1279 1280 /* TODO: when the plain tx or rx of peer is true, should I change 1281 * the attribute of controlled port 1282 */ 1283 if (body->prx) 1284 wpa_printf(MSG_WARNING, "KaY: peer's plain rx are TRUE"); 1285 1286 if (body->ptx) 1287 wpa_printf(MSG_WARNING, "KaY: peer's plain tx are TRUE"); 1288 1289 /* check latest key is valid */ 1290 if (body->ltx || body->lrx) { 1291 founded = FALSE; 1292 os_memcpy(ki.mi, body->lsrv_mi, sizeof(ki.mi)); 1293 ki.kn = ntohl(body->lkn); 1294 dl_list_for_each(sa_key, &participant->sak_list, 1295 struct data_key, list) { 1296 if (is_ki_equal(&sa_key->key_identifier, &ki)) { 1297 founded = TRUE; 1298 break; 1299 } 1300 } 1301 if (!founded) { 1302 wpa_printf(MSG_WARNING, "KaY: Latest key is invalid"); 1303 return -1; 1304 } 1305 if (os_memcmp(participant->lki.mi, body->lsrv_mi, 1306 sizeof(participant->lki.mi)) == 0 && 1307 ntohl(body->lkn) == participant->lki.kn && 1308 body->lan == participant->lan) { 1309 peer->sak_used = TRUE; 1310 } 1311 if (body->ltx && peer->is_key_server) { 1312 ieee802_1x_cp_set_servertransmitting( 1313 participant->kay->cp, TRUE); 1314 ieee802_1x_cp_sm_step(participant->kay->cp); 1315 } 1316 } 1317 1318 /* check old key is valid */ 1319 if (body->otx || body->orx) { 1320 if (os_memcmp(participant->oki.mi, body->osrv_mi, 1321 sizeof(participant->oki.mi)) != 0 || 1322 ntohl(body->okn) != participant->oki.kn || 1323 body->oan != participant->oan) { 1324 wpa_printf(MSG_WARNING, "KaY: Old key is invalid"); 1325 return -1; 1326 } 1327 } 1328 1329 /* TODO: how to set the MACsec hardware when delay_protect is true */ 1330 if (body->delay_protect && (!ntohl(body->llpn) || !ntohl(body->olpn))) { 1331 wpa_printf(MSG_WARNING, 1332 "KaY: Lowest packet number should greater than 0 when delay_protect is TRUE"); 1333 return -1; 1334 } 1335 1336 /* check all live peer have used the sak for receiving sa */ 1337 all_receiving = TRUE; 1338 dl_list_for_each(peer, &participant->live_peers, 1339 struct ieee802_1x_kay_peer, list) { 1340 if (!peer->sak_used) { 1341 all_receiving = FALSE; 1342 break; 1343 } 1344 } 1345 if (all_receiving) { 1346 participant->to_dist_sak = FALSE; 1347 ieee802_1x_cp_set_allreceiving(participant->kay->cp, TRUE); 1348 ieee802_1x_cp_sm_step(participant->kay->cp); 1349 } 1350 1351 /* if i'm key server, and detects peer member pn exhaustion, rekey.*/ 1352 lpn = ntohl(body->llpn); 1353 if (lpn > participant->kay->pn_exhaustion) { 1354 if (participant->is_key_server) { 1355 participant->new_sak = TRUE; 1356 wpa_printf(MSG_WARNING, "KaY: Peer LPN exhaustion"); 1357 } 1358 } 1359 1360 founded = FALSE; 1361 dl_list_for_each(txsa, &participant->txsc->sa_list, 1362 struct transmit_sa, list) { 1363 if (sa_key != NULL && txsa->pkey == sa_key) { 1364 founded = TRUE; 1365 break; 1366 } 1367 } 1368 if (!founded) { 1369 wpa_printf(MSG_WARNING, "KaY: Can't find txsa"); 1370 return -1; 1371 } 1372 1373 /* FIXME: Secy creates txsa with default npn. If MKA detected Latest Key 1374 * npn is larger than txsa's npn, set it to txsa. 1375 */ 1376 secy_get_transmit_next_pn(participant->kay, txsa); 1377 if (lpn > txsa->next_pn) { 1378 secy_set_transmit_next_pn(participant->kay, txsa); 1379 wpa_printf(MSG_INFO, "KaY: update lpn =0x%x", lpn); 1380 } 1381 1382 return 0; 1383} 1384 1385 1386/** 1387 * ieee802_1x_mka_dist_sak_body_present 1388 */ 1389static Boolean 1390ieee802_1x_mka_dist_sak_body_present( 1391 struct ieee802_1x_mka_participant *participant) 1392{ 1393 if (!participant->to_dist_sak || !participant->new_key) 1394 return FALSE; 1395 1396 return TRUE; 1397} 1398 1399 1400/** 1401 * ieee802_1x_kay_get_dist_sak_length 1402 */ 1403static int 1404ieee802_1x_mka_get_dist_sak_length( 1405 struct ieee802_1x_mka_participant *participant) 1406{ 1407 int length; 1408 int cs_index = participant->kay->macsec_csindex; 1409 1410 if (participant->advised_desired) { 1411 length = sizeof(struct ieee802_1x_mka_dist_sak_body); 1412 if (cs_index != DEFAULT_CS_INDEX) 1413 length += CS_ID_LEN; 1414 1415 length += cipher_suite_tbl[cs_index].sak_len + 8; 1416 } else { 1417 length = MKA_HDR_LEN; 1418 } 1419 length = (length + 0x3) & ~0x3; 1420 1421 return length; 1422} 1423 1424 1425/** 1426 * ieee802_1x_mka_encode_dist_sak_body - 1427 */ 1428static int 1429ieee802_1x_mka_encode_dist_sak_body( 1430 struct ieee802_1x_mka_participant *participant, 1431 struct wpabuf *buf) 1432{ 1433 struct ieee802_1x_mka_dist_sak_body *body; 1434 struct data_key *sak; 1435 unsigned int length; 1436 int cs_index; 1437 int sak_pos; 1438 1439 length = ieee802_1x_mka_get_dist_sak_length(participant); 1440 body = wpabuf_put(buf, length); 1441 body->type = MKA_DISTRIBUTED_SAK; 1442 set_mka_param_body_len(body, length - MKA_HDR_LEN); 1443 if (length == MKA_HDR_LEN) { 1444 body->confid_offset = 0; 1445 body->dan = 0; 1446 return 0; 1447 } 1448 1449 sak = participant->new_key; 1450 body->confid_offset = sak->confidentiality_offset; 1451 body->dan = sak->an; 1452 body->kn = host_to_be32(sak->key_identifier.kn); 1453 cs_index = participant->kay->macsec_csindex; 1454 sak_pos = 0; 1455 if (cs_index != DEFAULT_CS_INDEX) { 1456 os_memcpy(body->sak, cipher_suite_tbl[cs_index].id, CS_ID_LEN); 1457 sak_pos = CS_ID_LEN; 1458 } 1459 if (aes_wrap(participant->kek.key, 16, 1460 cipher_suite_tbl[cs_index].sak_len / 8, 1461 sak->key, body->sak + sak_pos)) { 1462 wpa_printf(MSG_ERROR, "KaY: AES wrap failed"); 1463 return -1; 1464 } 1465 1466 ieee802_1x_mka_dump_dist_sak_body(body); 1467 1468 return 0; 1469} 1470 1471 1472/** 1473 * ieee802_1x_kay_init_data_key - 1474 */ 1475static struct data_key * 1476ieee802_1x_kay_init_data_key(const struct key_conf *conf) 1477{ 1478 struct data_key *pkey; 1479 1480 if (!conf) 1481 return NULL; 1482 1483 pkey = os_zalloc(sizeof(*pkey)); 1484 if (pkey == NULL) { 1485 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 1486 return NULL; 1487 } 1488 1489 pkey->key = os_zalloc(conf->key_len); 1490 if (pkey->key == NULL) { 1491 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 1492 os_free(pkey); 1493 return NULL; 1494 } 1495 1496 os_memcpy(pkey->key, conf->key, conf->key_len); 1497 os_memcpy(&pkey->key_identifier, &conf->ki, 1498 sizeof(pkey->key_identifier)); 1499 pkey->confidentiality_offset = conf->offset; 1500 pkey->an = conf->an; 1501 pkey->transmits = conf->tx; 1502 pkey->receives = conf->rx; 1503 os_get_time(&pkey->created_time); 1504 1505 pkey->user = 1; 1506 1507 return pkey; 1508} 1509 1510 1511/** 1512 * ieee802_1x_kay_decode_dist_sak_body - 1513 */ 1514static int 1515ieee802_1x_mka_decode_dist_sak_body( 1516 struct ieee802_1x_mka_participant *participant, 1517 const u8 *mka_msg, size_t msg_len) 1518{ 1519 struct ieee802_1x_mka_hdr *hdr; 1520 struct ieee802_1x_mka_dist_sak_body *body; 1521 struct ieee802_1x_kay_peer *peer; 1522 struct macsec_ciphersuite *cs; 1523 size_t body_len; 1524 struct key_conf *conf; 1525 struct data_key *sa_key = NULL; 1526 struct ieee802_1x_mka_ki sak_ki; 1527 int sak_len; 1528 u8 *wrap_sak; 1529 u8 *unwrap_sak; 1530 1531 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1532 body_len = get_mka_param_body_len(hdr); 1533 if ((body_len != 0) && (body_len != 28) && (body_len < 36)) { 1534 wpa_printf(MSG_ERROR, 1535 "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 28, 36, or more octets", 1536 (int) body_len); 1537 return -1; 1538 } 1539 1540 if (!participant->principal) { 1541 wpa_printf(MSG_ERROR, 1542 "KaY: I can't accept the distributed SAK as I am not principal"); 1543 return -1; 1544 } 1545 if (participant->is_key_server) { 1546 wpa_printf(MSG_ERROR, 1547 "KaY: I can't accept the distributed SAK as myself is key server "); 1548 return -1; 1549 } 1550 if (!participant->kay->macsec_desired || 1551 participant->kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { 1552 wpa_printf(MSG_ERROR, 1553 "KaY: I am not MACsec-desired or without MACsec capable"); 1554 return -1; 1555 } 1556 1557 peer = ieee802_1x_kay_get_live_peer(participant, 1558 participant->current_peer_id.mi); 1559 if (!peer) { 1560 wpa_printf(MSG_ERROR, 1561 "KaY: The key server is not in my live peers list"); 1562 return -1; 1563 } 1564 if (os_memcmp(&participant->kay->key_server_sci, 1565 &peer->sci, sizeof(struct ieee802_1x_mka_sci)) != 0) { 1566 wpa_printf(MSG_ERROR, "KaY: The key server is not elected"); 1567 return -1; 1568 } 1569 if (body_len == 0) { 1570 participant->kay->authenticated = TRUE; 1571 participant->kay->secured = FALSE; 1572 participant->kay->failed = FALSE; 1573 participant->advised_desired = FALSE; 1574 ieee802_1x_cp_connect_authenticated(participant->kay->cp); 1575 ieee802_1x_cp_sm_step(participant->kay->cp); 1576 wpa_printf(MSG_WARNING, "KaY:The Key server advise no MACsec"); 1577 participant->to_use_sak = TRUE; 1578 return 0; 1579 } 1580 participant->advised_desired = TRUE; 1581 participant->kay->authenticated = FALSE; 1582 participant->kay->secured = TRUE; 1583 participant->kay->failed = FALSE; 1584 ieee802_1x_cp_connect_secure(participant->kay->cp); 1585 ieee802_1x_cp_sm_step(participant->kay->cp); 1586 1587 body = (struct ieee802_1x_mka_dist_sak_body *)mka_msg; 1588 ieee802_1x_mka_dump_dist_sak_body(body); 1589 dl_list_for_each(sa_key, &participant->sak_list, struct data_key, list) 1590 { 1591 if (os_memcmp(sa_key->key_identifier.mi, 1592 participant->current_peer_id.mi, MI_LEN) == 0 && 1593 sa_key->key_identifier.kn == be_to_host32(body->kn)) { 1594 wpa_printf(MSG_WARNING, "KaY:The Key has installed"); 1595 return 0; 1596 } 1597 } 1598 if (body_len == 28) { 1599 sak_len = DEFAULT_SA_KEY_LEN; 1600 wrap_sak = body->sak; 1601 participant->kay->macsec_csindex = DEFAULT_CS_INDEX; 1602 } else { 1603 cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak); 1604 if (!cs) { 1605 wpa_printf(MSG_ERROR, 1606 "KaY: I can't support the Cipher Suite advised by key server"); 1607 return -1; 1608 } 1609 sak_len = cs->sak_len; 1610 wrap_sak = body->sak + CS_ID_LEN; 1611 participant->kay->macsec_csindex = cs->index; 1612 } 1613 1614 unwrap_sak = os_zalloc(sak_len); 1615 if (!unwrap_sak) { 1616 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 1617 return -1; 1618 } 1619 if (aes_unwrap(participant->kek.key, 16, sak_len >> 3, wrap_sak, 1620 unwrap_sak)) { 1621 wpa_printf(MSG_ERROR, "KaY: AES unwrap failed"); 1622 os_free(unwrap_sak); 1623 return -1; 1624 } 1625 wpa_hexdump(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len); 1626 1627 conf = os_zalloc(sizeof(*conf)); 1628 if (!conf) { 1629 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 1630 os_free(unwrap_sak); 1631 return -1; 1632 } 1633 conf->key_len = sak_len; 1634 1635 conf->key = os_zalloc(conf->key_len); 1636 if (!conf->key) { 1637 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 1638 os_free(unwrap_sak); 1639 os_free(conf); 1640 return -1; 1641 } 1642 1643 os_memcpy(conf->key, unwrap_sak, conf->key_len); 1644 1645 os_memcpy(&sak_ki.mi, &participant->current_peer_id.mi, 1646 sizeof(sak_ki.mi)); 1647 sak_ki.kn = be_to_host32(body->kn); 1648 1649 os_memcpy(conf->ki.mi, sak_ki.mi, MI_LEN); 1650 conf->ki.kn = sak_ki.kn; 1651 conf->an = body->dan; 1652 conf->offset = body->confid_offset; 1653 conf->rx = TRUE; 1654 conf->tx = TRUE; 1655 1656 sa_key = ieee802_1x_kay_init_data_key(conf); 1657 if (!sa_key) { 1658 os_free(unwrap_sak); 1659 os_free(conf->key); 1660 os_free(conf); 1661 return -1; 1662 } 1663 1664 dl_list_add(&participant->sak_list, &sa_key->list); 1665 1666 ieee802_1x_cp_set_ciphersuite( 1667 participant->kay->cp, 1668 cipher_suite_tbl[participant->kay->macsec_csindex].id); 1669 ieee802_1x_cp_sm_step(participant->kay->cp); 1670 ieee802_1x_cp_set_offset(participant->kay->cp, body->confid_offset); 1671 ieee802_1x_cp_sm_step(participant->kay->cp); 1672 ieee802_1x_cp_set_distributedki(participant->kay->cp, &sak_ki); 1673 ieee802_1x_cp_set_distributedan(participant->kay->cp, body->dan); 1674 ieee802_1x_cp_signal_newsak(participant->kay->cp); 1675 ieee802_1x_cp_sm_step(participant->kay->cp); 1676 1677 participant->to_use_sak = TRUE; 1678 1679 os_free(unwrap_sak); 1680 os_free(conf->key); 1681 os_free(conf); 1682 1683 return 0; 1684} 1685 1686 1687/** 1688 * ieee802_1x_mka_icv_body_present 1689 */ 1690static Boolean 1691ieee802_1x_mka_icv_body_present(struct ieee802_1x_mka_participant *participant) 1692{ 1693 return TRUE; 1694} 1695 1696 1697/** 1698 * ieee802_1x_kay_get_icv_length 1699 */ 1700static int 1701ieee802_1x_mka_get_icv_length(struct ieee802_1x_mka_participant *participant) 1702{ 1703 int length; 1704 1705 length = sizeof(struct ieee802_1x_mka_icv_body); 1706 length += mka_alg_tbl[participant->kay->mka_algindex].icv_len; 1707 1708 return (length + 0x3) & ~0x3; 1709} 1710 1711 1712/** 1713 * ieee802_1x_mka_encode_icv_body - 1714 */ 1715static int 1716ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant, 1717 struct wpabuf *buf) 1718{ 1719 struct ieee802_1x_mka_icv_body *body; 1720 unsigned int length; 1721 u8 cmac[MAX_ICV_LEN]; 1722 1723 length = ieee802_1x_mka_get_icv_length(participant); 1724 if (length != DEFAULT_ICV_LEN) { 1725 body = wpabuf_put(buf, MKA_HDR_LEN); 1726 body->type = MKA_ICV_INDICATOR; 1727 set_mka_param_body_len(body, length - MKA_HDR_LEN); 1728 } 1729 1730 if (mka_alg_tbl[participant->kay->mka_algindex].icv_hash( 1731 participant->ick.key, wpabuf_head(buf), buf->used, cmac)) { 1732 wpa_printf(MSG_ERROR, "KaY, omac1_aes_128 failed"); 1733 return -1; 1734 } 1735 1736 if (length != DEFAULT_ICV_LEN) { 1737 os_memcpy(wpabuf_put(buf, length - MKA_HDR_LEN), cmac, 1738 length - MKA_HDR_LEN); 1739 } else { 1740 os_memcpy(wpabuf_put(buf, length), cmac, length); 1741 } 1742 1743 return 0; 1744} 1745 1746/** 1747 * ieee802_1x_mka_decode_icv_body - 1748 */ 1749static u8 * 1750ieee802_1x_mka_decode_icv_body(struct ieee802_1x_mka_participant *participant, 1751 const u8 *mka_msg, size_t msg_len) 1752{ 1753 struct ieee802_1x_mka_hdr *hdr; 1754 struct ieee802_1x_mka_icv_body *body; 1755 size_t body_len; 1756 size_t left_len; 1757 int body_type; 1758 const u8 *pos; 1759 1760 pos = mka_msg; 1761 left_len = msg_len; 1762 while (left_len > (MKA_HDR_LEN + DEFAULT_ICV_LEN)) { 1763 hdr = (struct ieee802_1x_mka_hdr *) pos; 1764 body_len = get_mka_param_body_len(hdr); 1765 body_type = get_mka_param_body_type(hdr); 1766 1767 if (left_len < (body_len + MKA_HDR_LEN)) 1768 break; 1769 1770 if (body_type != MKA_ICV_INDICATOR) { 1771 left_len -= MKA_HDR_LEN + body_len; 1772 pos += MKA_HDR_LEN + body_len; 1773 continue; 1774 } 1775 1776 body = (struct ieee802_1x_mka_icv_body *)pos; 1777 if (body_len 1778 < mka_alg_tbl[participant->kay->mka_algindex].icv_len) { 1779 return NULL; 1780 } 1781 1782 return body->icv; 1783 } 1784 1785 return (u8 *) (mka_msg + msg_len - DEFAULT_ICV_LEN); 1786} 1787 1788 1789/** 1790 * ieee802_1x_mka_decode_dist_cak_body- 1791 */ 1792static int 1793ieee802_1x_mka_decode_dist_cak_body( 1794 struct ieee802_1x_mka_participant *participant, 1795 const u8 *mka_msg, size_t msg_len) 1796{ 1797 struct ieee802_1x_mka_hdr *hdr; 1798 size_t body_len; 1799 1800 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1801 body_len = get_mka_param_body_len(hdr); 1802 if (body_len < 28) { 1803 wpa_printf(MSG_ERROR, 1804 "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 28 or more octets", 1805 (int) body_len); 1806 return -1; 1807 } 1808 1809 return 0; 1810} 1811 1812 1813/** 1814 * ieee802_1x_mka_decode_kmd_body - 1815 */ 1816static int 1817ieee802_1x_mka_decode_kmd_body( 1818 struct ieee802_1x_mka_participant *participant, 1819 const u8 *mka_msg, size_t msg_len) 1820{ 1821 struct ieee802_1x_mka_hdr *hdr; 1822 size_t body_len; 1823 1824 hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 1825 body_len = get_mka_param_body_len(hdr); 1826 if (body_len < 5) { 1827 wpa_printf(MSG_ERROR, 1828 "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 5 or more octets", 1829 (int) body_len); 1830 return -1; 1831 } 1832 1833 return 0; 1834} 1835 1836 1837/** 1838 * ieee802_1x_mka_decode_announce_body - 1839 */ 1840static int ieee802_1x_mka_decode_announce_body( 1841 struct ieee802_1x_mka_participant *participant, 1842 const u8 *mka_msg, size_t msg_len) 1843{ 1844 return 0; 1845} 1846 1847 1848static struct mka_param_body_handler mak_body_handler[] = { 1849 /* basic parameter set */ 1850 { 1851 ieee802_1x_mka_encode_basic_body, 1852 NULL, 1853 ieee802_1x_mka_basic_body_length, 1854 ieee802_1x_mka_basic_body_present 1855 }, 1856 1857 /* live peer list parameter set */ 1858 { 1859 ieee802_1x_mka_encode_live_peer_body, 1860 ieee802_1x_mka_decode_live_peer_body, 1861 ieee802_1x_mka_get_live_peer_length, 1862 ieee802_1x_mka_live_peer_body_present 1863 }, 1864 1865 /* potential peer list parameter set */ 1866 { 1867 ieee802_1x_mka_encode_potential_peer_body, 1868 ieee802_1x_mka_decode_potential_peer_body, 1869 ieee802_1x_mka_get_potential_peer_length, 1870 ieee802_1x_mka_potential_peer_body_present 1871 }, 1872 1873 /* sak use parameter set */ 1874 { 1875 ieee802_1x_mka_encode_sak_use_body, 1876 ieee802_1x_mka_decode_sak_use_body, 1877 ieee802_1x_mka_get_sak_use_length, 1878 ieee802_1x_mka_sak_use_body_present 1879 }, 1880 1881 /* distribute sak parameter set */ 1882 { 1883 ieee802_1x_mka_encode_dist_sak_body, 1884 ieee802_1x_mka_decode_dist_sak_body, 1885 ieee802_1x_mka_get_dist_sak_length, 1886 ieee802_1x_mka_dist_sak_body_present 1887 }, 1888 1889 /* distribute cak parameter set */ 1890 { 1891 NULL, 1892 ieee802_1x_mka_decode_dist_cak_body, 1893 NULL, 1894 NULL 1895 }, 1896 1897 /* kmd parameter set */ 1898 { 1899 NULL, 1900 ieee802_1x_mka_decode_kmd_body, 1901 NULL, 1902 NULL 1903 }, 1904 1905 /* announce parameter set */ 1906 { 1907 NULL, 1908 ieee802_1x_mka_decode_announce_body, 1909 NULL, 1910 NULL 1911 }, 1912 1913 /* icv parameter set */ 1914 { 1915 ieee802_1x_mka_encode_icv_body, 1916 NULL, 1917 ieee802_1x_mka_get_icv_length, 1918 ieee802_1x_mka_icv_body_present 1919 }, 1920}; 1921 1922 1923/** 1924 * ieee802_1x_kay_deinit_data_key - 1925 */ 1926void ieee802_1x_kay_deinit_data_key(struct data_key *pkey) 1927{ 1928 if (!pkey) 1929 return; 1930 1931 pkey->user--; 1932 if (pkey->user > 1) 1933 return; 1934 1935 dl_list_del(&pkey->list); 1936 os_free(pkey->key); 1937 os_free(pkey); 1938} 1939 1940 1941/** 1942 * ieee802_1x_kay_generate_new_sak - 1943 */ 1944static int 1945ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant) 1946{ 1947 struct data_key *sa_key = NULL; 1948 struct key_conf *conf; 1949 struct ieee802_1x_kay_peer *peer; 1950 struct ieee802_1x_kay *kay = participant->kay; 1951 int ctx_len, ctx_offset; 1952 u8 *context; 1953 1954 /* check condition for generating a fresh SAK: 1955 * must have one live peer 1956 * and MKA life time elapse since last distribution 1957 * or potential peer is empty 1958 */ 1959 if (dl_list_empty(&participant->live_peers)) { 1960 wpa_printf(MSG_ERROR, 1961 "KaY: Live peers list must not empty when generating fresh SAK"); 1962 return -1; 1963 } 1964 1965 /* FIXME: A fresh SAK not generated until 1966 * the live peer list contains at least one peer and 1967 * MKA life time has elapsed since the prior SAK was first distributed, 1968 * or the Key server's potential peer is empty 1969 * but I can't understand the second item, so 1970 * here only check first item and ingore 1971 * && (!dl_list_empty(&participant->potential_peers))) { 1972 */ 1973 if ((time(NULL) - kay->dist_time) < MKA_LIFE_TIME / 1000) { 1974 wpa_printf(MSG_ERROR, 1975 "KaY: Life time have not elapsed since prior SAK distributed"); 1976 return -1; 1977 } 1978 1979 conf = os_zalloc(sizeof(*conf)); 1980 if (!conf) { 1981 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 1982 return -1; 1983 } 1984 conf->key_len = cipher_suite_tbl[kay->macsec_csindex].sak_len; 1985 1986 conf->key = os_zalloc(conf->key_len); 1987 if (!conf->key) { 1988 os_free(conf); 1989 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 1990 return -1; 1991 } 1992 1993 ctx_len = conf->key_len + sizeof(kay->dist_kn); 1994 dl_list_for_each(peer, &participant->live_peers, 1995 struct ieee802_1x_kay_peer, list) 1996 ctx_len += sizeof(peer->mi); 1997 ctx_len += sizeof(participant->mi); 1998 1999 context = os_zalloc(ctx_len); 2000 if (!context) { 2001 os_free(conf->key); 2002 os_free(conf); 2003 return -1; 2004 } 2005 ctx_offset = 0; 2006 if (os_get_random(context + ctx_offset, conf->key_len) < 0) { 2007 os_free(context); 2008 os_free(conf->key); 2009 os_free(conf); 2010 return -1; 2011 } 2012 ctx_offset += conf->key_len; 2013 dl_list_for_each(peer, &participant->live_peers, 2014 struct ieee802_1x_kay_peer, list) { 2015 os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi)); 2016 ctx_offset += sizeof(peer->mi); 2017 } 2018 os_memcpy(context + ctx_offset, participant->mi, 2019 sizeof(participant->mi)); 2020 ctx_offset += sizeof(participant->mi); 2021 os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn)); 2022 2023 if (conf->key_len == 16) { 2024 ieee802_1x_sak_128bits_aes_cmac(participant->cak.key, 2025 context, ctx_len, conf->key); 2026 } else if (conf->key_len == 32) { 2027 ieee802_1x_sak_128bits_aes_cmac(participant->cak.key, 2028 context, ctx_len, conf->key); 2029 } else { 2030 wpa_printf(MSG_ERROR, "KaY: SAK Length not support"); 2031 os_free(conf->key); 2032 os_free(conf); 2033 os_free(context); 2034 return -1; 2035 } 2036 wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK", 2037 conf->key, conf->key_len); 2038 2039 os_memcpy(conf->ki.mi, participant->mi, MI_LEN); 2040 conf->ki.kn = participant->kay->dist_kn; 2041 conf->an = participant->kay->dist_an; 2042 conf->offset = kay->macsec_confidentiality; 2043 conf->rx = TRUE; 2044 conf->tx = TRUE; 2045 2046 sa_key = ieee802_1x_kay_init_data_key(conf); 2047 if (!sa_key) { 2048 os_free(conf->key); 2049 os_free(conf); 2050 os_free(context); 2051 return -1; 2052 } 2053 participant->new_key = sa_key; 2054 2055 dl_list_add(&participant->sak_list, &sa_key->list); 2056 ieee802_1x_cp_set_ciphersuite(participant->kay->cp, 2057 cipher_suite_tbl[kay->macsec_csindex].id); 2058 ieee802_1x_cp_sm_step(kay->cp); 2059 ieee802_1x_cp_set_offset(kay->cp, conf->offset); 2060 ieee802_1x_cp_sm_step(kay->cp); 2061 ieee802_1x_cp_set_distributedki(kay->cp, &conf->ki); 2062 ieee802_1x_cp_set_distributedan(kay->cp, conf->an); 2063 ieee802_1x_cp_signal_newsak(kay->cp); 2064 ieee802_1x_cp_sm_step(kay->cp); 2065 2066 dl_list_for_each(peer, &participant->live_peers, 2067 struct ieee802_1x_kay_peer, list) 2068 peer->sak_used = FALSE; 2069 2070 participant->kay->dist_kn++; 2071 participant->kay->dist_an++; 2072 if (participant->kay->dist_an > 3) 2073 participant->kay->dist_an = 0; 2074 2075 participant->kay->dist_time = time(NULL); 2076 2077 os_free(conf->key); 2078 os_free(conf); 2079 os_free(context); 2080 return 0; 2081} 2082 2083 2084/** 2085 * ieee802_1x_kay_elect_key_server - elect the key server 2086 * when to elect: whenever the live peers list changes 2087 */ 2088static int 2089ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant) 2090{ 2091 struct ieee802_1x_kay_peer *peer; 2092 struct ieee802_1x_kay_peer *key_server = NULL; 2093 struct ieee802_1x_kay *kay = participant->kay; 2094 Boolean i_is_key_server; 2095 int i; 2096 2097 if (participant->is_obliged_key_server) { 2098 participant->new_sak = TRUE; 2099 participant->to_dist_sak = FALSE; 2100 ieee802_1x_cp_set_electedself(kay->cp, TRUE); 2101 return 0; 2102 } 2103 2104 /* elect the key server among the peers */ 2105 dl_list_for_each(peer, &participant->live_peers, 2106 struct ieee802_1x_kay_peer, list) { 2107 if (!peer->is_key_server) 2108 continue; 2109 2110 if (!key_server) { 2111 key_server = peer; 2112 continue; 2113 } 2114 2115 if (peer->key_server_priority < 2116 key_server->key_server_priority) { 2117 key_server = peer; 2118 } else if (peer->key_server_priority == 2119 key_server->key_server_priority) { 2120 for (i = 0; i < 6; i++) { 2121 if (peer->sci.addr[i] < 2122 key_server->sci.addr[i]) 2123 key_server = peer; 2124 } 2125 } 2126 } 2127 2128 /* elect the key server between me and the above elected peer */ 2129 i_is_key_server = FALSE; 2130 if (key_server && participant->can_be_key_server) { 2131 if (kay->actor_priority 2132 < key_server->key_server_priority) { 2133 i_is_key_server = TRUE; 2134 } else if (kay->actor_priority 2135 == key_server->key_server_priority) { 2136 for (i = 0; i < 6; i++) { 2137 if (kay->actor_sci.addr[i] 2138 < key_server->sci.addr[i]) { 2139 i_is_key_server = TRUE; 2140 } 2141 } 2142 } 2143 } 2144 2145 if (!key_server && !i_is_key_server) { 2146 participant->principal = FALSE; 2147 participant->is_key_server = FALSE; 2148 participant->is_elected = FALSE; 2149 return 0; 2150 } 2151 2152 if (i_is_key_server) { 2153 ieee802_1x_cp_set_electedself(kay->cp, TRUE); 2154 if (os_memcmp(&kay->key_server_sci, &kay->actor_sci, 2155 sizeof(kay->key_server_sci))) { 2156 ieee802_1x_cp_signal_chgdserver(kay->cp); 2157 ieee802_1x_cp_sm_step(kay->cp); 2158 } 2159 2160 participant->is_key_server = TRUE; 2161 participant->principal = TRUE; 2162 participant->new_sak = TRUE; 2163 wpa_printf(MSG_DEBUG, "KaY: I is elected as key server"); 2164 participant->to_dist_sak = FALSE; 2165 participant->is_elected = TRUE; 2166 2167 os_memcpy(&kay->key_server_sci, &kay->actor_sci, 2168 sizeof(kay->key_server_sci)); 2169 kay->key_server_priority = kay->actor_priority; 2170 } 2171 2172 if (key_server) { 2173 ieee802_1x_cp_set_electedself(kay->cp, FALSE); 2174 if (os_memcmp(&kay->key_server_sci, &key_server->sci, 2175 sizeof(kay->key_server_sci))) { 2176 ieee802_1x_cp_signal_chgdserver(kay->cp); 2177 ieee802_1x_cp_sm_step(kay->cp); 2178 } 2179 2180 participant->is_key_server = FALSE; 2181 participant->principal = TRUE; 2182 participant->is_elected = TRUE; 2183 2184 os_memcpy(&kay->key_server_sci, &key_server->sci, 2185 sizeof(kay->key_server_sci)); 2186 kay->key_server_priority = key_server->key_server_priority; 2187 } 2188 2189 return 0; 2190} 2191 2192 2193/** 2194 * ieee802_1x_kay_decide_macsec_use - the key server determinate 2195 * how to use MACsec: whether use MACsec and its capability 2196 * protectFrames will be advised if the key server and one of its live peers are 2197 * MACsec capable and one of those request MACsec protection 2198 */ 2199static int 2200ieee802_1x_kay_decide_macsec_use( 2201 struct ieee802_1x_mka_participant *participant) 2202{ 2203 struct ieee802_1x_kay *kay = participant->kay; 2204 struct ieee802_1x_kay_peer *peer; 2205 enum macsec_cap less_capability; 2206 Boolean has_peer; 2207 2208 if (!participant->is_key_server) 2209 return -1; 2210 2211 /* key server self is MACsec-desired and requesting MACsec */ 2212 if (!kay->macsec_desired) { 2213 participant->advised_desired = FALSE; 2214 return -1; 2215 } 2216 if (kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { 2217 participant->advised_desired = FALSE; 2218 return -1; 2219 } 2220 less_capability = kay->macsec_capable; 2221 2222 /* at least one of peers is MACsec-desired and requesting MACsec */ 2223 has_peer = FALSE; 2224 dl_list_for_each(peer, &participant->live_peers, 2225 struct ieee802_1x_kay_peer, list) { 2226 if (!peer->macsec_desired) 2227 continue; 2228 2229 if (peer->macsec_capbility == MACSEC_CAP_NOT_IMPLEMENTED) 2230 continue; 2231 2232 less_capability = (less_capability < peer->macsec_capbility) ? 2233 less_capability : peer->macsec_capbility; 2234 has_peer = TRUE; 2235 } 2236 2237 if (has_peer) { 2238 participant->advised_desired = TRUE; 2239 participant->advised_capability = less_capability; 2240 kay->authenticated = FALSE; 2241 kay->secured = TRUE; 2242 kay->failed = FALSE; 2243 ieee802_1x_cp_connect_secure(kay->cp); 2244 ieee802_1x_cp_sm_step(kay->cp); 2245 } else { 2246 participant->advised_desired = FALSE; 2247 participant->advised_capability = MACSEC_CAP_NOT_IMPLEMENTED; 2248 participant->to_use_sak = FALSE; 2249 kay->authenticated = TRUE; 2250 kay->secured = FALSE; 2251 kay->failed = FALSE; 2252 kay->ltx_kn = 0; 2253 kay->ltx_an = 0; 2254 kay->lrx_kn = 0; 2255 kay->lrx_an = 0; 2256 kay->otx_kn = 0; 2257 kay->otx_an = 0; 2258 kay->orx_kn = 0; 2259 kay->orx_an = 0; 2260 ieee802_1x_cp_connect_authenticated(kay->cp); 2261 ieee802_1x_cp_sm_step(kay->cp); 2262 } 2263 2264 return 0; 2265} 2266 2267static const u8 pae_group_addr[ETH_ALEN] = { 2268 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 2269}; 2270 2271 2272/** 2273 * ieee802_1x_kay_encode_mkpdu - 2274 */ 2275static int 2276ieee802_1x_kay_encode_mkpdu(struct ieee802_1x_mka_participant *participant, 2277 struct wpabuf *pbuf) 2278{ 2279 unsigned int i; 2280 struct ieee8023_hdr *ether_hdr; 2281 struct ieee802_1x_hdr *eapol_hdr; 2282 2283 ether_hdr = wpabuf_put(pbuf, sizeof(*ether_hdr)); 2284 os_memcpy(ether_hdr->dest, pae_group_addr, sizeof(ether_hdr->dest)); 2285 os_memcpy(ether_hdr->src, participant->kay->actor_sci.addr, 2286 sizeof(ether_hdr->dest)); 2287 ether_hdr->ethertype = host_to_be16(ETH_P_EAPOL); 2288 2289 eapol_hdr = wpabuf_put(pbuf, sizeof(*eapol_hdr)); 2290 eapol_hdr->version = EAPOL_VERSION; 2291 eapol_hdr->type = IEEE802_1X_TYPE_EAPOL_MKA; 2292 eapol_hdr->length = host_to_be16(pbuf->size - pbuf->used); 2293 2294 for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) { 2295 if (mak_body_handler[i].body_present && 2296 mak_body_handler[i].body_present(participant)) { 2297 if (mak_body_handler[i].body_tx(participant, pbuf)) 2298 return -1; 2299 } 2300 } 2301 2302 return 0; 2303} 2304 2305/** 2306 * ieee802_1x_participant_send_mkpdu - 2307 */ 2308static int 2309ieee802_1x_participant_send_mkpdu( 2310 struct ieee802_1x_mka_participant *participant) 2311{ 2312 struct wpabuf *buf; 2313 struct ieee802_1x_kay *kay = participant->kay; 2314 size_t length = 0; 2315 unsigned int i; 2316 2317 wpa_printf(MSG_DEBUG, "KaY: to enpacket and send the MKPDU"); 2318 length += sizeof(struct ieee802_1x_hdr) + sizeof(struct ieee8023_hdr); 2319 for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) { 2320 if (mak_body_handler[i].body_present && 2321 mak_body_handler[i].body_present(participant)) 2322 length += mak_body_handler[i].body_length(participant); 2323 } 2324 2325 buf = wpabuf_alloc(length); 2326 if (!buf) { 2327 wpa_printf(MSG_ERROR, "KaY: out of memory"); 2328 return -1; 2329 } 2330 2331 if (ieee802_1x_kay_encode_mkpdu(participant, buf)) { 2332 wpa_printf(MSG_ERROR, "KaY: encode mkpdu fail!"); 2333 return -1; 2334 } 2335 2336 l2_packet_send(kay->l2_mka, NULL, 0, wpabuf_head(buf), wpabuf_len(buf)); 2337 wpabuf_free(buf); 2338 2339 kay->active = TRUE; 2340 participant->active = TRUE; 2341 2342 return 0; 2343} 2344 2345 2346static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa); 2347/** 2348 * ieee802_1x_participant_timer - 2349 */ 2350static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) 2351{ 2352 struct ieee802_1x_mka_participant *participant; 2353 struct ieee802_1x_kay *kay; 2354 struct ieee802_1x_kay_peer *peer, *pre_peer; 2355 time_t now = time(NULL); 2356 Boolean lp_changed; 2357 struct receive_sc *rxsc, *pre_rxsc; 2358 struct transmit_sa *txsa, *pre_txsa; 2359 2360 participant = (struct ieee802_1x_mka_participant *)eloop_ctx; 2361 kay = participant->kay; 2362 if (participant->cak_life) { 2363 if (now > participant->cak_life) { 2364 kay->authenticated = FALSE; 2365 kay->secured = FALSE; 2366 kay->failed = TRUE; 2367 ieee802_1x_kay_delete_mka(kay, &participant->ckn); 2368 return; 2369 } 2370 } 2371 2372 /* should delete MKA instance if there are not live peers 2373 * when the MKA life elapsed since its creating */ 2374 if (participant->mka_life) { 2375 if (dl_list_empty(&participant->live_peers)) { 2376 if (now > participant->mka_life) { 2377 kay->authenticated = FALSE; 2378 kay->secured = FALSE; 2379 kay->failed = TRUE; 2380 ieee802_1x_kay_delete_mka(kay, 2381 &participant->ckn); 2382 return; 2383 } 2384 } else { 2385 participant->mka_life = 0; 2386 } 2387 } 2388 2389 lp_changed = FALSE; 2390 dl_list_for_each_safe(peer, pre_peer, &participant->live_peers, 2391 struct ieee802_1x_kay_peer, list) { 2392 if (now > peer->expire) { 2393 wpa_printf(MSG_DEBUG, "KaY: Live peer removed"); 2394 wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, 2395 sizeof(peer->mi)); 2396 wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 2397 dl_list_for_each_safe(rxsc, pre_rxsc, 2398 &participant->rxsc_list, 2399 struct receive_sc, list) { 2400 if (os_memcmp(&rxsc->sci, &peer->sci, 2401 sizeof(rxsc->sci)) == 0) { 2402 secy_delete_receive_sc(kay, rxsc); 2403 ieee802_1x_kay_deinit_receive_sc( 2404 participant, rxsc); 2405 } 2406 } 2407 dl_list_del(&peer->list); 2408 os_free(peer); 2409 lp_changed = TRUE; 2410 } 2411 } 2412 2413 if (lp_changed) { 2414 if (dl_list_empty(&participant->live_peers)) { 2415 participant->advised_desired = FALSE; 2416 participant->advised_capability = 2417 MACSEC_CAP_NOT_IMPLEMENTED; 2418 participant->to_use_sak = FALSE; 2419 kay->authenticated = TRUE; 2420 kay->secured = FALSE; 2421 kay->failed = FALSE; 2422 kay->ltx_kn = 0; 2423 kay->ltx_an = 0; 2424 kay->lrx_kn = 0; 2425 kay->lrx_an = 0; 2426 kay->otx_kn = 0; 2427 kay->otx_an = 0; 2428 kay->orx_kn = 0; 2429 kay->orx_an = 0; 2430 dl_list_for_each_safe(txsa, pre_txsa, 2431 &participant->txsc->sa_list, 2432 struct transmit_sa, list) { 2433 secy_disable_transmit_sa(kay, txsa); 2434 ieee802_1x_kay_deinit_transmit_sa(txsa); 2435 } 2436 2437 ieee802_1x_cp_connect_authenticated(kay->cp); 2438 ieee802_1x_cp_sm_step(kay->cp); 2439 } else { 2440 ieee802_1x_kay_elect_key_server(participant); 2441 ieee802_1x_kay_decide_macsec_use(participant); 2442 } 2443 } 2444 2445 dl_list_for_each_safe(peer, pre_peer, &participant->potential_peers, 2446 struct ieee802_1x_kay_peer, list) { 2447 if (now > peer->expire) { 2448 wpa_printf(MSG_DEBUG, "KaY: Potential peer removed"); 2449 wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, 2450 sizeof(peer->mi)); 2451 wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 2452 dl_list_del(&peer->list); 2453 os_free(peer); 2454 } 2455 } 2456 2457 if (participant->new_sak) { 2458 if (!ieee802_1x_kay_generate_new_sak(participant)) 2459 participant->to_dist_sak = TRUE; 2460 2461 participant->new_sak = FALSE; 2462 } 2463 2464 if (participant->retry_count < MAX_RETRY_CNT) { 2465 ieee802_1x_participant_send_mkpdu(participant); 2466 participant->retry_count++; 2467 } 2468 2469 eloop_register_timeout(MKA_HELLO_TIME / 1000, 0, 2470 ieee802_1x_participant_timer, 2471 participant, NULL); 2472} 2473 2474 2475/** 2476 * ieee802_1x_kay_init_transmit_sa - 2477 */ 2478static struct transmit_sa * 2479ieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN, 2480 struct data_key *key) 2481{ 2482 struct transmit_sa *psa; 2483 2484 key->tx_latest = TRUE; 2485 key->rx_latest = TRUE; 2486 2487 psa = os_zalloc(sizeof(*psa)); 2488 if (!psa) { 2489 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 2490 return NULL; 2491 } 2492 2493 if (key->confidentiality_offset >= CONFIDENTIALITY_OFFSET_0 && 2494 key->confidentiality_offset <= CONFIDENTIALITY_OFFSET_50) 2495 psa->confidentiality = TRUE; 2496 else 2497 psa->confidentiality = FALSE; 2498 2499 psa->an = an; 2500 psa->pkey = key; 2501 psa->next_pn = next_PN; 2502 psa->sc = psc; 2503 2504 os_get_time(&psa->created_time); 2505 psa->in_use = FALSE; 2506 2507 dl_list_add(&psc->sa_list, &psa->list); 2508 wpa_printf(MSG_DEBUG, 2509 "KaY: Create transmit SA(an: %d, next_PN: %u) of SC(channel: %d)", 2510 (int) an, next_PN, psc->channel); 2511 2512 return psa; 2513} 2514 2515 2516/** 2517 * ieee802_1x_kay_deinit_transmit_sa - 2518 */ 2519static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa) 2520{ 2521 psa->pkey = NULL; 2522 wpa_printf(MSG_DEBUG, 2523 "KaY: Delete transmit SA(an: %d) of SC(channel: %d)", 2524 psa->an, psa->sc->channel); 2525 dl_list_del(&psa->list); 2526 os_free(psa); 2527} 2528 2529 2530/** 2531 * init_transmit_sc - 2532 */ 2533static struct transmit_sc * 2534ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci, 2535 int channel) 2536{ 2537 struct transmit_sc *psc; 2538 2539 psc = os_zalloc(sizeof(*psc)); 2540 if (!psc) { 2541 wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 2542 return NULL; 2543 } 2544 os_memcpy(&psc->sci, sci, sizeof(psc->sci)); 2545 psc->channel = channel; 2546 2547 os_get_time(&psc->created_time); 2548 psc->transmitting = FALSE; 2549 psc->encoding_sa = FALSE; 2550 psc->enciphering_sa = FALSE; 2551 2552 dl_list_init(&psc->sa_list); 2553 wpa_printf(MSG_DEBUG, "KaY: Create transmit SC(channel: %d)", channel); 2554 wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)sci , sizeof(*sci)); 2555 2556 return psc; 2557} 2558 2559 2560/** 2561 * ieee802_1x_kay_deinit_transmit_sc - 2562 */ 2563static void 2564ieee802_1x_kay_deinit_transmit_sc( 2565 struct ieee802_1x_mka_participant *participant, struct transmit_sc *psc) 2566{ 2567 struct transmit_sa *psa, *tmp; 2568 2569 wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC(channel: %d)", 2570 psc->channel); 2571 dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, 2572 list) { 2573 secy_disable_transmit_sa(participant->kay, psa); 2574 ieee802_1x_kay_deinit_transmit_sa(psa); 2575 } 2576 2577 os_free(psc); 2578} 2579 2580 2581/****************** Interface between CP and KAY *********************/ 2582/** 2583 * ieee802_1x_kay_set_latest_sa_attr - 2584 */ 2585int ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay, 2586 struct ieee802_1x_mka_ki *lki, u8 lan, 2587 Boolean ltx, Boolean lrx) 2588{ 2589 struct ieee802_1x_mka_participant *principal; 2590 2591 principal = ieee802_1x_kay_get_principal_participant(kay); 2592 if (!principal) 2593 return -1; 2594 2595 if (!lki) 2596 os_memset(&principal->lki, 0, sizeof(principal->lki)); 2597 else 2598 os_memcpy(&principal->lki, lki, sizeof(principal->lki)); 2599 2600 principal->lan = lan; 2601 principal->ltx = ltx; 2602 principal->lrx = lrx; 2603 if (!lki) { 2604 kay->ltx_kn = 0; 2605 kay->lrx_kn = 0; 2606 } else { 2607 kay->ltx_kn = lki->kn; 2608 kay->lrx_kn = lki->kn; 2609 } 2610 kay->ltx_an = lan; 2611 kay->lrx_an = lan; 2612 2613 return 0; 2614} 2615 2616 2617/** 2618 * ieee802_1x_kay_set_old_sa_attr - 2619 */ 2620int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay, 2621 struct ieee802_1x_mka_ki *oki, 2622 u8 oan, Boolean otx, Boolean orx) 2623{ 2624 struct ieee802_1x_mka_participant *principal; 2625 2626 principal = ieee802_1x_kay_get_principal_participant(kay); 2627 if (!principal) 2628 return -1; 2629 2630 if (!oki) 2631 os_memset(&principal->oki, 0, sizeof(principal->oki)); 2632 else 2633 os_memcpy(&principal->oki, oki, sizeof(principal->oki)); 2634 2635 principal->oan = oan; 2636 principal->otx = otx; 2637 principal->orx = orx; 2638 2639 if (!oki) { 2640 kay->otx_kn = 0; 2641 kay->orx_kn = 0; 2642 } else { 2643 kay->otx_kn = oki->kn; 2644 kay->orx_kn = oki->kn; 2645 } 2646 kay->otx_an = oan; 2647 kay->orx_an = oan; 2648 2649 return 0; 2650} 2651 2652 2653/** 2654 * ieee802_1x_kay_create_sas - 2655 */ 2656int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, 2657 struct ieee802_1x_mka_ki *lki) 2658{ 2659 struct data_key *sa_key, *latest_sak; 2660 struct ieee802_1x_mka_participant *principal; 2661 struct receive_sc *rxsc; 2662 struct receive_sa *rxsa; 2663 struct transmit_sa *txsa; 2664 2665 principal = ieee802_1x_kay_get_principal_participant(kay); 2666 if (!principal) 2667 return -1; 2668 2669 latest_sak = NULL; 2670 dl_list_for_each(sa_key, &principal->sak_list, struct data_key, list) { 2671 if (is_ki_equal(&sa_key->key_identifier, lki)) { 2672 sa_key->rx_latest = TRUE; 2673 sa_key->tx_latest = TRUE; 2674 latest_sak = sa_key; 2675 principal->to_use_sak = TRUE; 2676 } else { 2677 sa_key->rx_latest = FALSE; 2678 sa_key->tx_latest = FALSE; 2679 } 2680 } 2681 if (!latest_sak) { 2682 wpa_printf(MSG_ERROR, "lki related sak not found"); 2683 return -1; 2684 } 2685 2686 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 2687 rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1, 2688 latest_sak); 2689 if (!rxsa) 2690 return -1; 2691 2692 secy_create_receive_sa(kay, rxsa); 2693 } 2694 2695 txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an, 2696 1, latest_sak); 2697 if (!txsa) 2698 return -1; 2699 2700 secy_create_transmit_sa(kay, txsa); 2701 2702 2703 2704 return 0; 2705} 2706 2707 2708/** 2709 * ieee802_1x_kay_delete_sas - 2710 */ 2711int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay, 2712 struct ieee802_1x_mka_ki *ki) 2713{ 2714 struct data_key *sa_key, *pre_key; 2715 struct transmit_sa *txsa, *pre_txsa; 2716 struct receive_sa *rxsa, *pre_rxsa; 2717 struct receive_sc *rxsc; 2718 struct ieee802_1x_mka_participant *principal; 2719 2720 wpa_printf(MSG_DEBUG, "KaY: Entry into %s", __func__); 2721 principal = ieee802_1x_kay_get_principal_participant(kay); 2722 if (!principal) 2723 return -1; 2724 2725 /* remove the transmit sa */ 2726 dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list, 2727 struct transmit_sa, list) { 2728 if (is_ki_equal(&txsa->pkey->key_identifier, ki)) { 2729 secy_disable_transmit_sa(kay, txsa); 2730 ieee802_1x_kay_deinit_transmit_sa(txsa); 2731 } 2732 } 2733 2734 /* remove the receive sa */ 2735 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 2736 dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list, 2737 struct receive_sa, list) { 2738 if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) { 2739 secy_disable_receive_sa(kay, rxsa); 2740 ieee802_1x_kay_deinit_receive_sa(rxsa); 2741 } 2742 } 2743 } 2744 2745 /* remove the sak */ 2746 dl_list_for_each_safe(sa_key, pre_key, &principal->sak_list, 2747 struct data_key, list) { 2748 if (is_ki_equal(&sa_key->key_identifier, ki)) { 2749 ieee802_1x_kay_deinit_data_key(sa_key); 2750 break; 2751 } 2752 if (principal->new_key == sa_key) 2753 principal->new_key = NULL; 2754 } 2755 2756 return 0; 2757} 2758 2759 2760/** 2761 * ieee802_1x_kay_enable_tx_sas - 2762 */ 2763int ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay, 2764 struct ieee802_1x_mka_ki *lki) 2765{ 2766 struct ieee802_1x_mka_participant *principal; 2767 struct transmit_sa *txsa; 2768 2769 principal = ieee802_1x_kay_get_principal_participant(kay); 2770 if (!principal) 2771 return -1; 2772 2773 dl_list_for_each(txsa, &principal->txsc->sa_list, struct transmit_sa, 2774 list) { 2775 if (is_ki_equal(&txsa->pkey->key_identifier, lki)) { 2776 txsa->in_use = TRUE; 2777 secy_enable_transmit_sa(kay, txsa); 2778 ieee802_1x_cp_set_usingtransmitas( 2779 principal->kay->cp, TRUE); 2780 ieee802_1x_cp_sm_step(principal->kay->cp); 2781 } 2782 } 2783 2784 return 0; 2785} 2786 2787 2788/** 2789 * ieee802_1x_kay_enable_rx_sas - 2790 */ 2791int ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay, 2792 struct ieee802_1x_mka_ki *lki) 2793{ 2794 struct ieee802_1x_mka_participant *principal; 2795 struct receive_sa *rxsa; 2796 struct receive_sc *rxsc; 2797 2798 principal = ieee802_1x_kay_get_principal_participant(kay); 2799 if (!principal) 2800 return -1; 2801 2802 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 2803 dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) 2804 { 2805 if (is_ki_equal(&rxsa->pkey->key_identifier, lki)) { 2806 rxsa->in_use = TRUE; 2807 secy_enable_receive_sa(kay, rxsa); 2808 ieee802_1x_cp_set_usingreceivesas( 2809 principal->kay->cp, TRUE); 2810 ieee802_1x_cp_sm_step(principal->kay->cp); 2811 } 2812 } 2813 } 2814 2815 return 0; 2816} 2817 2818 2819/** 2820 * ieee802_1x_kay_enable_new_info - 2821 */ 2822int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay) 2823{ 2824 struct ieee802_1x_mka_participant *principal; 2825 2826 principal = ieee802_1x_kay_get_principal_participant(kay); 2827 if (!principal) 2828 return -1; 2829 2830 if (principal->retry_count < MAX_RETRY_CNT) { 2831 ieee802_1x_participant_send_mkpdu(principal); 2832 principal->retry_count++; 2833 } 2834 2835 return 0; 2836} 2837 2838 2839/** 2840 * ieee802_1x_kay_cp_conf - 2841 */ 2842int ieee802_1x_kay_cp_conf(struct ieee802_1x_kay *kay, 2843 struct ieee802_1x_cp_conf *pconf) 2844{ 2845 pconf->protect = kay->macsec_protect; 2846 pconf->replay_protect = kay->macsec_replay_protect; 2847 pconf->validate = kay->macsec_validate; 2848 2849 return 0; 2850} 2851 2852 2853/** 2854 * ieee802_1x_kay_alloc_cp_sm - 2855 */ 2856static struct ieee802_1x_cp_sm * 2857ieee802_1x_kay_alloc_cp_sm(struct ieee802_1x_kay *kay) 2858{ 2859 struct ieee802_1x_cp_conf conf; 2860 2861 os_memset(&conf, 0, sizeof(conf)); 2862 conf.protect = kay->macsec_protect; 2863 conf.replay_protect = kay->macsec_replay_protect; 2864 conf.validate = kay->macsec_validate; 2865 conf.replay_window = kay->macsec_replay_window; 2866 2867 return ieee802_1x_cp_sm_init(kay, &conf); 2868} 2869 2870 2871/** 2872 * ieee802_1x_kay_mkpdu_sanity_check - 2873 * sanity check specified in clause 11.11.2 of IEEE802.1X-2010 2874 */ 2875static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay, 2876 const u8 *buf, size_t len) 2877{ 2878 struct ieee8023_hdr *eth_hdr; 2879 struct ieee802_1x_hdr *eapol_hdr; 2880 struct ieee802_1x_mka_hdr *mka_hdr; 2881 struct ieee802_1x_mka_basic_body *body; 2882 size_t mka_msg_len; 2883 struct ieee802_1x_mka_participant *participant; 2884 size_t body_len; 2885 u8 icv[MAX_ICV_LEN]; 2886 u8 *msg_icv; 2887 2888 eth_hdr = (struct ieee8023_hdr *) buf; 2889 eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1); 2890 mka_hdr = (struct ieee802_1x_mka_hdr *) (eapol_hdr + 1); 2891 2892 /* destination address should be not individual address */ 2893 if (os_memcmp(eth_hdr->dest, pae_group_addr, ETH_ALEN) != 0) { 2894 wpa_printf(MSG_MSGDUMP, 2895 "KaY: ethernet destination address is not PAE group address"); 2896 return -1; 2897 } 2898 2899 /* MKPDU should not less than 32 octets */ 2900 mka_msg_len = be_to_host16(eapol_hdr->length); 2901 if (mka_msg_len < 32) { 2902 wpa_printf(MSG_MSGDUMP, "KaY: MKPDU is less than 32 octets"); 2903 return -1; 2904 } 2905 /* MKPDU should multiple 4 octets */ 2906 if ((mka_msg_len % 4) != 0) { 2907 wpa_printf(MSG_MSGDUMP, 2908 "KaY: MKPDU is not multiple of 4 octets"); 2909 return -1; 2910 } 2911 2912 body = (struct ieee802_1x_mka_basic_body *) mka_hdr; 2913 ieee802_1x_mka_dump_basic_body(body); 2914 body_len = get_mka_param_body_len(body); 2915 /* EAPOL-MKA body should comprise basic parameter set and ICV */ 2916 if (mka_msg_len < MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN) { 2917 wpa_printf(MSG_ERROR, 2918 "KaY: Received EAPOL-MKA Packet Body Length (%d bytes) is less than the Basic Parameter Set Header Length (%d bytes) + the Basic Parameter Set Body Length (%d bytes) + %d bytes of ICV", 2919 (int) mka_msg_len, (int) MKA_HDR_LEN, 2920 (int) body_len, DEFAULT_ICV_LEN); 2921 return -1; 2922 } 2923 2924 /* CKN should be owned by I */ 2925 participant = ieee802_1x_kay_get_participant(kay, body->ckn); 2926 if (!participant) { 2927 wpa_printf(MSG_DEBUG, "CKN is not included in my CA"); 2928 return -1; 2929 } 2930 2931 /* algorithm agility check */ 2932 if (os_memcmp(body->algo_agility, mka_algo_agility, 2933 sizeof(body->algo_agility)) != 0) { 2934 wpa_printf(MSG_ERROR, 2935 "KaY: peer's algorithm agility not supported for me"); 2936 return -1; 2937 } 2938 2939 /* ICV check */ 2940 /* 2941 * The ICV will comprise the final octets of the packet body, whatever 2942 * its size, not the fixed length 16 octets, indicated by the EAPOL 2943 * packet body length. 2944 */ 2945 if (mka_alg_tbl[kay->mka_algindex].icv_hash( 2946 participant->ick.key, 2947 buf, len - mka_alg_tbl[kay->mka_algindex].icv_len, icv)) { 2948 wpa_printf(MSG_ERROR, "KaY: omac1_aes_128 failed"); 2949 return -1; 2950 } 2951 msg_icv = ieee802_1x_mka_decode_icv_body(participant, (u8 *) mka_hdr, 2952 mka_msg_len); 2953 2954 if (msg_icv) { 2955 if (os_memcmp_const(msg_icv, icv, 2956 mka_alg_tbl[kay->mka_algindex].icv_len) != 2957 0) { 2958 wpa_printf(MSG_ERROR, 2959 "KaY: Computed ICV is not equal to Received ICV"); 2960 return -1; 2961 } 2962 } else { 2963 wpa_printf(MSG_ERROR, "KaY: No ICV"); 2964 return -1; 2965 } 2966 2967 return 0; 2968} 2969 2970 2971/** 2972 * ieee802_1x_kay_decode_mkpdu - 2973 */ 2974static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay, 2975 const u8 *buf, size_t len) 2976{ 2977 struct ieee802_1x_mka_participant *participant; 2978 struct ieee802_1x_mka_hdr *hdr; 2979 size_t body_len; 2980 size_t left_len; 2981 int body_type; 2982 int i; 2983 const u8 *pos; 2984 Boolean my_included; 2985 Boolean handled[256]; 2986 2987 if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len)) 2988 return -1; 2989 2990 /* handle basic parameter set */ 2991 pos = buf + sizeof(struct ieee8023_hdr) + sizeof(struct ieee802_1x_hdr); 2992 left_len = len - sizeof(struct ieee8023_hdr) - 2993 sizeof(struct ieee802_1x_hdr); 2994 participant = ieee802_1x_mka_decode_basic_body(kay, pos, left_len); 2995 if (!participant) 2996 return -1; 2997 2998 /* to skip basic parameter set */ 2999 hdr = (struct ieee802_1x_mka_hdr *) pos; 3000 body_len = get_mka_param_body_len(hdr); 3001 pos += body_len + MKA_HDR_LEN; 3002 left_len -= body_len + MKA_HDR_LEN; 3003 3004 /* check i am in the peer's peer list */ 3005 my_included = ieee802_1x_mka_i_in_peerlist(participant, pos, left_len); 3006 if (my_included) { 3007 /* accept the peer as live peer */ 3008 if (!ieee802_1x_kay_is_in_peer( 3009 participant, 3010 participant->current_peer_id.mi)) { 3011 if (!ieee802_1x_kay_create_live_peer( 3012 participant, 3013 participant->current_peer_id.mi, 3014 participant->current_peer_id.mn)) 3015 return -1; 3016 ieee802_1x_kay_elect_key_server(participant); 3017 ieee802_1x_kay_decide_macsec_use(participant); 3018 } 3019 if (ieee802_1x_kay_is_in_potential_peer( 3020 participant, participant->current_peer_id.mi)) { 3021 ieee802_1x_kay_move_live_peer( 3022 participant, participant->current_peer_id.mi, 3023 participant->current_peer_id.mn); 3024 ieee802_1x_kay_elect_key_server(participant); 3025 ieee802_1x_kay_decide_macsec_use(participant); 3026 } 3027 } 3028 3029 /* 3030 * Handle other parameter set than basic parameter set. 3031 * Each parameter set should be present only once. 3032 */ 3033 for (i = 0; i < 256; i++) 3034 handled[i] = FALSE; 3035 3036 handled[0] = TRUE; 3037 while (left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN) { 3038 hdr = (struct ieee802_1x_mka_hdr *) pos; 3039 body_len = get_mka_param_body_len(hdr); 3040 body_type = get_mka_param_body_type(hdr); 3041 3042 if (body_type == MKA_ICV_INDICATOR) 3043 return 0; 3044 3045 if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) { 3046 wpa_printf(MSG_ERROR, 3047 "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV", 3048 (int) left_len, (int) MKA_HDR_LEN, 3049 (int) body_len, DEFAULT_ICV_LEN); 3050 goto next_para_set; 3051 } 3052 3053 if (handled[body_type]) 3054 goto next_para_set; 3055 3056 handled[body_type] = TRUE; 3057 if (mak_body_handler[body_type].body_rx) { 3058 mak_body_handler[body_type].body_rx 3059 (participant, pos, left_len); 3060 } else { 3061 wpa_printf(MSG_ERROR, 3062 "The type %d not supported in this MKA version %d", 3063 body_type, MKA_VERSION_ID); 3064 } 3065 3066next_para_set: 3067 pos += body_len + MKA_HDR_LEN; 3068 left_len -= body_len + MKA_HDR_LEN; 3069 } 3070 3071 kay->active = TRUE; 3072 participant->retry_count = 0; 3073 participant->active = TRUE; 3074 3075 return 0; 3076} 3077 3078 3079 3080static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf, 3081 size_t len) 3082{ 3083 struct ieee802_1x_kay *kay = ctx; 3084 struct ieee8023_hdr *eth_hdr; 3085 struct ieee802_1x_hdr *eapol_hdr; 3086 3087 /* must contain at least ieee8023_hdr + ieee802_1x_hdr */ 3088 if (len < sizeof(*eth_hdr) + sizeof(*eapol_hdr)) { 3089 wpa_printf(MSG_MSGDUMP, "KaY: EAPOL frame too short (%lu)", 3090 (unsigned long) len); 3091 return; 3092 } 3093 3094 eth_hdr = (struct ieee8023_hdr *) buf; 3095 eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1); 3096 if (len != sizeof(*eth_hdr) + sizeof(*eapol_hdr) + 3097 ntohs(eapol_hdr->length)) { 3098 wpa_printf(MSG_MSGDUMP, "KAY: EAPOL MPDU is invalid: (%lu-%lu)", 3099 (unsigned long) len, 3100 (unsigned long) ntohs(eapol_hdr->length)); 3101 return; 3102 } 3103 3104 if (eapol_hdr->version < EAPOL_VERSION) { 3105 wpa_printf(MSG_MSGDUMP, "KaY: version %d does not support MKA", 3106 eapol_hdr->version); 3107 return; 3108 } 3109 if (ntohs(eth_hdr->ethertype) != ETH_P_PAE || 3110 eapol_hdr->type != IEEE802_1X_TYPE_EAPOL_MKA) 3111 return; 3112 3113 wpa_hexdump(MSG_DEBUG, "RX EAPOL-MKA: ", buf, len); 3114 if (dl_list_empty(&kay->participant_list)) { 3115 wpa_printf(MSG_ERROR, "KaY: no MKA participant instance"); 3116 return; 3117 } 3118 3119 ieee802_1x_kay_decode_mkpdu(kay, buf, len); 3120} 3121 3122 3123/** 3124 * ieee802_1x_kay_init - 3125 */ 3126struct ieee802_1x_kay * 3127ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, 3128 const char *ifname, const u8 *addr) 3129{ 3130 struct ieee802_1x_kay *kay; 3131 3132 kay = os_zalloc(sizeof(*kay)); 3133 if (!kay) { 3134 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 3135 return NULL; 3136 } 3137 3138 kay->ctx = ctx; 3139 3140 kay->enable = TRUE; 3141 kay->active = FALSE; 3142 3143 kay->authenticated = FALSE; 3144 kay->secured = FALSE; 3145 kay->failed = FALSE; 3146 kay->policy = policy; 3147 3148 os_strlcpy(kay->if_name, ifname, IFNAMSIZ); 3149 os_memcpy(kay->actor_sci.addr, addr, ETH_ALEN); 3150 kay->actor_sci.port = 0x0001; 3151 kay->actor_priority = DEFAULT_PRIO_NOT_KEY_SERVER; 3152 3153 /* While actor acts as a key server, shall distribute sakey */ 3154 kay->dist_kn = 1; 3155 kay->dist_an = 0; 3156 kay->dist_time = 0; 3157 3158 kay->pn_exhaustion = PENDING_PN_EXHAUSTION; 3159 kay->macsec_csindex = DEFAULT_CS_INDEX; 3160 kay->mka_algindex = DEFAULT_MKA_ALG_INDEX; 3161 kay->mka_version = MKA_VERSION_ID; 3162 3163 os_memcpy(kay->algo_agility, mka_algo_agility, 3164 sizeof(kay->algo_agility)); 3165 3166 dl_list_init(&kay->participant_list); 3167 3168 if (policy == DO_NOT_SECURE) { 3169 kay->macsec_capable = MACSEC_CAP_NOT_IMPLEMENTED; 3170 kay->macsec_desired = FALSE; 3171 kay->macsec_protect = FALSE; 3172 kay->macsec_validate = Disabled; 3173 kay->macsec_replay_protect = FALSE; 3174 kay->macsec_replay_window = 0; 3175 kay->macsec_confidentiality = CONFIDENTIALITY_NONE; 3176 } else { 3177 kay->macsec_capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50; 3178 kay->macsec_desired = TRUE; 3179 kay->macsec_protect = TRUE; 3180 kay->macsec_validate = Strict; 3181 kay->macsec_replay_protect = FALSE; 3182 kay->macsec_replay_window = 0; 3183 kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0; 3184 } 3185 3186 wpa_printf(MSG_DEBUG, "KaY: state machine created"); 3187 3188 /* Initialize the SecY must be prio to CP, as CP will control SecY */ 3189 secy_init_macsec(kay); 3190 secy_get_available_transmit_sc(kay, &kay->sc_ch); 3191 3192 wpa_printf(MSG_DEBUG, "KaY: secy init macsec done"); 3193 3194 /* init CP */ 3195 kay->cp = ieee802_1x_kay_alloc_cp_sm(kay); 3196 if (kay->cp == NULL) { 3197 ieee802_1x_kay_deinit(kay); 3198 return NULL; 3199 } 3200 3201 if (policy == DO_NOT_SECURE) { 3202 ieee802_1x_cp_connect_authenticated(kay->cp); 3203 ieee802_1x_cp_sm_step(kay->cp); 3204 } else { 3205 kay->l2_mka = l2_packet_init(kay->if_name, NULL, ETH_P_PAE, 3206 kay_l2_receive, kay, 1); 3207 if (kay->l2_mka == NULL) { 3208 wpa_printf(MSG_WARNING, 3209 "KaY: Failed to initialize L2 packet processing for MKA packet"); 3210 ieee802_1x_kay_deinit(kay); 3211 return NULL; 3212 } 3213 } 3214 3215 return kay; 3216} 3217 3218 3219/** 3220 * ieee802_1x_kay_deinit - 3221 */ 3222void 3223ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay) 3224{ 3225 struct ieee802_1x_mka_participant *participant; 3226 3227 if (!kay) 3228 return; 3229 3230 wpa_printf(MSG_DEBUG, "KaY: state machine removed"); 3231 3232 while (!dl_list_empty(&kay->participant_list)) { 3233 participant = dl_list_entry(kay->participant_list.next, 3234 struct ieee802_1x_mka_participant, 3235 list); 3236 ieee802_1x_kay_delete_mka(kay, &participant->ckn); 3237 } 3238 3239 ieee802_1x_cp_sm_deinit(kay->cp); 3240 secy_deinit_macsec(kay); 3241 3242 if (kay->l2_mka) { 3243 l2_packet_deinit(kay->l2_mka); 3244 kay->l2_mka = NULL; 3245 } 3246 3247 os_free(kay->ctx); 3248 os_free(kay); 3249} 3250 3251 3252/** 3253 * ieee802_1x_kay_create_mka - 3254 */ 3255struct ieee802_1x_mka_participant * 3256ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn, 3257 struct mka_key *cak, u32 life, 3258 enum mka_created_mode mode, Boolean is_authenticator) 3259{ 3260 struct ieee802_1x_mka_participant *participant; 3261 unsigned int usecs; 3262 3263 if (!kay || !ckn || !cak) { 3264 wpa_printf(MSG_ERROR, "KaY: ckn or cak is null"); 3265 return NULL; 3266 } 3267 3268 if (cak->len != mka_alg_tbl[kay->mka_algindex].cak_len) { 3269 wpa_printf(MSG_ERROR, "KaY: CAK length not follow key schema"); 3270 return NULL; 3271 } 3272 if (ckn->len > MAX_CKN_LEN) { 3273 wpa_printf(MSG_ERROR, "KaY: CKN is out of range(<=32 bytes)"); 3274 return NULL; 3275 } 3276 if (!kay->enable) { 3277 wpa_printf(MSG_ERROR, "KaY: Now is at disable state"); 3278 return NULL; 3279 } 3280 3281 participant = os_zalloc(sizeof(*participant)); 3282 if (!participant) { 3283 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 3284 return NULL; 3285 } 3286 3287 participant->ckn.len = ckn->len; 3288 os_memcpy(participant->ckn.name, ckn->name, ckn->len); 3289 participant->cak.len = cak->len; 3290 os_memcpy(participant->cak.key, cak->key, cak->len); 3291 if (life) 3292 participant->cak_life = life + time(NULL); 3293 3294 switch (mode) { 3295 case EAP_EXCHANGE: 3296 if (is_authenticator) { 3297 participant->is_obliged_key_server = TRUE; 3298 participant->can_be_key_server = TRUE; 3299 participant->is_key_server = TRUE; 3300 participant->principal = TRUE; 3301 3302 os_memcpy(&kay->key_server_sci, &kay->actor_sci, 3303 sizeof(kay->key_server_sci)); 3304 kay->key_server_priority = kay->actor_priority; 3305 participant->is_elected = TRUE; 3306 } else { 3307 participant->is_obliged_key_server = FALSE; 3308 participant->can_be_key_server = FALSE; 3309 participant->is_key_server = FALSE; 3310 participant->is_elected = TRUE; 3311 } 3312 break; 3313 3314 default: 3315 participant->is_obliged_key_server = FALSE; 3316 participant->can_be_key_server = TRUE; 3317 participant->is_key_server = FALSE; 3318 participant->is_elected = FALSE; 3319 break; 3320 } 3321 3322 participant->cached = FALSE; 3323 3324 participant->active = FALSE; 3325 participant->participant = FALSE; 3326 participant->retain = FALSE; 3327 participant->activate = DEFAULT; 3328 3329 if (participant->is_key_server) 3330 participant->principal = TRUE; 3331 3332 dl_list_init(&participant->live_peers); 3333 dl_list_init(&participant->potential_peers); 3334 3335 participant->retry_count = 0; 3336 participant->kay = kay; 3337 3338 if (os_get_random(participant->mi, sizeof(participant->mi)) < 0) 3339 goto fail; 3340 participant->mn = 0; 3341 3342 participant->lrx = FALSE; 3343 participant->ltx = FALSE; 3344 participant->orx = FALSE; 3345 participant->otx = FALSE; 3346 participant->to_dist_sak = FALSE; 3347 participant->to_use_sak = FALSE; 3348 participant->new_sak = FALSE; 3349 dl_list_init(&participant->sak_list); 3350 participant->new_key = NULL; 3351 dl_list_init(&participant->rxsc_list); 3352 participant->txsc = ieee802_1x_kay_init_transmit_sc(&kay->actor_sci, 3353 kay->sc_ch); 3354 secy_cp_control_protect_frames(kay, kay->macsec_protect); 3355 secy_cp_control_replay(kay, kay->macsec_replay_protect, 3356 kay->macsec_replay_window); 3357 secy_create_transmit_sc(kay, participant->txsc); 3358 3359 /* to derive KEK from CAK and CKN */ 3360 participant->kek.len = mka_alg_tbl[kay->mka_algindex].kek_len; 3361 if (mka_alg_tbl[kay->mka_algindex].kek_trfm(participant->cak.key, 3362 participant->ckn.name, 3363 participant->ckn.len, 3364 participant->kek.key)) { 3365 wpa_printf(MSG_ERROR, "KaY: Derived KEK failed"); 3366 goto fail; 3367 } 3368 wpa_hexdump_key(MSG_DEBUG, "KaY: Derived KEK", 3369 participant->kek.key, participant->kek.len); 3370 3371 /* to derive ICK from CAK and CKN */ 3372 participant->ick.len = mka_alg_tbl[kay->mka_algindex].ick_len; 3373 if (mka_alg_tbl[kay->mka_algindex].ick_trfm(participant->cak.key, 3374 participant->ckn.name, 3375 participant->ckn.len, 3376 participant->ick.key)) { 3377 wpa_printf(MSG_ERROR, "KaY: Derived ICK failed"); 3378 goto fail; 3379 } 3380 wpa_hexdump_key(MSG_DEBUG, "KaY: Derived ICK", 3381 participant->ick.key, participant->ick.len); 3382 3383 dl_list_add(&kay->participant_list, &participant->list); 3384 wpa_hexdump(MSG_DEBUG, "KaY: Participant created:", 3385 ckn->name, ckn->len); 3386 3387 usecs = os_random() % (MKA_HELLO_TIME * 1000); 3388 eloop_register_timeout(0, usecs, ieee802_1x_participant_timer, 3389 participant, NULL); 3390 participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) + 3391 usecs / 1000000; 3392 3393 return participant; 3394 3395fail: 3396 os_free(participant); 3397 return NULL; 3398} 3399 3400 3401/** 3402 * ieee802_1x_kay_delete_mka - 3403 */ 3404void 3405ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn) 3406{ 3407 struct ieee802_1x_mka_participant *participant; 3408 struct ieee802_1x_kay_peer *peer; 3409 struct data_key *sak; 3410 struct receive_sc *rxsc; 3411 3412 if (!kay || !ckn) 3413 return; 3414 3415 wpa_printf(MSG_DEBUG, "KaY: participant removed"); 3416 3417 /* get the participant */ 3418 participant = ieee802_1x_kay_get_participant(kay, ckn->name); 3419 if (!participant) { 3420 wpa_hexdump(MSG_DEBUG, "KaY: participant is not found", 3421 ckn->name, ckn->len); 3422 return; 3423 } 3424 3425 dl_list_del(&participant->list); 3426 3427 /* remove live peer */ 3428 while (!dl_list_empty(&participant->live_peers)) { 3429 peer = dl_list_entry(participant->live_peers.next, 3430 struct ieee802_1x_kay_peer, list); 3431 dl_list_del(&peer->list); 3432 os_free(peer); 3433 } 3434 3435 /* remove potential peer */ 3436 while (!dl_list_empty(&participant->potential_peers)) { 3437 peer = dl_list_entry(participant->potential_peers.next, 3438 struct ieee802_1x_kay_peer, list); 3439 dl_list_del(&peer->list); 3440 os_free(peer); 3441 } 3442 3443 /* remove sak */ 3444 while (!dl_list_empty(&participant->sak_list)) { 3445 sak = dl_list_entry(participant->sak_list.next, 3446 struct data_key, list); 3447 dl_list_del(&sak->list); 3448 os_free(sak->key); 3449 os_free(sak); 3450 } 3451 while (!dl_list_empty(&participant->rxsc_list)) { 3452 rxsc = dl_list_entry(participant->rxsc_list.next, 3453 struct receive_sc, list); 3454 secy_delete_receive_sc(kay, rxsc); 3455 ieee802_1x_kay_deinit_receive_sc(participant, rxsc); 3456 } 3457 secy_delete_transmit_sc(kay, participant->txsc); 3458 ieee802_1x_kay_deinit_transmit_sc(participant, participant->txsc); 3459 3460 os_memset(&participant->cak, 0, sizeof(participant->cak)); 3461 os_memset(&participant->kek, 0, sizeof(participant->kek)); 3462 os_memset(&participant->ick, 0, sizeof(participant->ick)); 3463 os_free(participant); 3464} 3465 3466 3467/** 3468 * ieee802_1x_kay_mka_participate - 3469 */ 3470void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay, 3471 struct mka_key_name *ckn, 3472 Boolean status) 3473{ 3474 struct ieee802_1x_mka_participant *participant; 3475 3476 if (!kay || !ckn) 3477 return; 3478 3479 participant = ieee802_1x_kay_get_participant(kay, ckn->name); 3480 if (!participant) 3481 return; 3482 3483 participant->active = status; 3484} 3485 3486 3487/** 3488 * ieee802_1x_kay_new_sak - 3489 */ 3490int 3491ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay) 3492{ 3493 struct ieee802_1x_mka_participant *participant; 3494 3495 if (!kay) 3496 return -1; 3497 3498 participant = ieee802_1x_kay_get_principal_participant(kay); 3499 if (!participant) 3500 return -1; 3501 3502 participant->new_sak = TRUE; 3503 wpa_printf(MSG_DEBUG, "KaY: new SAK signal"); 3504 3505 return 0; 3506} 3507 3508 3509/** 3510 * ieee802_1x_kay_change_cipher_suite - 3511 */ 3512int 3513ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, int cs_index) 3514{ 3515 struct ieee802_1x_mka_participant *participant; 3516 3517 if (!kay) 3518 return -1; 3519 3520 if ((unsigned int) cs_index >= CS_TABLE_SIZE) { 3521 wpa_printf(MSG_ERROR, 3522 "KaY: Configured cipher suite index is out of range"); 3523 return -1; 3524 } 3525 if (kay->macsec_csindex == cs_index) 3526 return -2; 3527 3528 if (cs_index == 0) 3529 kay->macsec_desired = FALSE; 3530 3531 kay->macsec_csindex = cs_index; 3532 kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable; 3533 3534 participant = ieee802_1x_kay_get_principal_participant(kay); 3535 if (participant) { 3536 wpa_printf(MSG_INFO, "KaY: Cipher Suite changed"); 3537 participant->new_sak = TRUE; 3538 } 3539 3540 return 0; 3541} 3542