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