Home | History | Annotate | Download | only in pae
      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,
   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, 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