]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/pae/ieee802_1x_kay.c
Update to ELF Tool Chain r3668
[FreeBSD/FreeBSD.git] / contrib / wpa / src / pae / ieee802_1x_kay.c
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 */