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