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