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