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