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