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