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