1 /*
2 * IEEE 802.1X-2010 Key Agreement 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 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
26 #include "aidl/aidl_psk.h"
27 #endif
28
29
30 #define DEFAULT_SA_KEY_LEN 16
31 #define DEFAULT_ICV_LEN 16
32 #define MAX_ICV_LEN 32 /* 32 bytes, 256 bits */
33
34 #define MAX_MISSING_SAK_USE 10 /* Accept up to 10 inbound MKPDUs without
35 * SAK-USE before dropping */
36
37 #define PENDING_PN_EXHAUSTION 0xC0000000
38
39 #define MKA_ALIGN_LENGTH(len) (((len) + 0x3) & ~0x3)
40
41 /* IEEE Std 802.1X-2010, Table 9-1 - MKA Algorithm Agility */
42 #define MKA_ALGO_AGILITY_2009 { 0x00, 0x80, 0xC2, 0x01 }
43 static u8 mka_algo_agility[4] = MKA_ALGO_AGILITY_2009;
44
45 /* IEEE802.1AE-2006 Table 14-1 MACsec Cipher Suites */
46 static struct macsec_ciphersuite cipher_suite_tbl[] = {
47 /* GCM-AES-128 */
48 {
49 .id = CS_ID_GCM_AES_128,
50 .name = CS_NAME_GCM_AES_128,
51 .capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50,
52 .sak_len = DEFAULT_SA_KEY_LEN,
53 },
54 /* GCM-AES-256 */
55 {
56 .id = CS_ID_GCM_AES_256,
57 .name = CS_NAME_GCM_AES_256,
58 .capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50,
59 .sak_len = 32,
60 },
61 };
62 #define CS_TABLE_SIZE (ARRAY_SIZE(cipher_suite_tbl))
63 #define DEFAULT_CS_INDEX 0
64
65 static struct mka_alg mka_alg_tbl[] = {
66 {
67 .parameter = MKA_ALGO_AGILITY_2009,
68
69 .icv_len = DEFAULT_ICV_LEN,
70
71 .cak_trfm = ieee802_1x_cak_aes_cmac,
72 .ckn_trfm = ieee802_1x_ckn_aes_cmac,
73 .kek_trfm = ieee802_1x_kek_aes_cmac,
74 .ick_trfm = ieee802_1x_ick_aes_cmac,
75 .icv_hash = ieee802_1x_icv_aes_cmac,
76 },
77 };
78 #define MKA_ALG_TABLE_SIZE (ARRAY_SIZE(mka_alg_tbl))
79
80
is_ki_equal(struct ieee802_1x_mka_ki * ki1,struct ieee802_1x_mka_ki * ki2)81 static int is_ki_equal(struct ieee802_1x_mka_ki *ki1,
82 struct ieee802_1x_mka_ki *ki2)
83 {
84 return os_memcmp(ki1->mi, ki2->mi, MI_LEN) == 0 &&
85 ki1->kn == ki2->kn;
86 }
87
88
set_mka_param_body_len(void * body,unsigned int len)89 static void set_mka_param_body_len(void *body, unsigned int len)
90 {
91 struct ieee802_1x_mka_hdr *hdr = body;
92 hdr->length = (len >> 8) & 0x0f;
93 hdr->length1 = len & 0xff;
94 }
95
96
get_mka_param_body_len(const void * body)97 static unsigned int get_mka_param_body_len(const void *body)
98 {
99 const struct ieee802_1x_mka_hdr *hdr = body;
100 return (hdr->length << 8) | hdr->length1;
101 }
102
103
get_mka_param_body_type(const void * body)104 static u8 get_mka_param_body_type(const void *body)
105 {
106 const struct ieee802_1x_mka_hdr *hdr = body;
107 return hdr->type;
108 }
109
110
mi_txt(const u8 * mi)111 static const char * mi_txt(const u8 *mi)
112 {
113 static char txt[MI_LEN * 2 + 1];
114
115 wpa_snprintf_hex(txt, sizeof(txt), mi, MI_LEN);
116 return txt;
117 }
118
119
sci_txt(const struct ieee802_1x_mka_sci * sci)120 static const char * sci_txt(const struct ieee802_1x_mka_sci *sci)
121 {
122 static char txt[ETH_ALEN * 3 + 1 + 5 + 1];
123
124 os_snprintf(txt, sizeof(txt), MACSTR "@%u",
125 MAC2STR(sci->addr), be_to_host16(sci->port));
126 return txt;
127 }
128
129
algo_agility_txt(const u8 * algo_agility)130 static const char * algo_agility_txt(const u8 *algo_agility)
131 {
132 static char txt[4 * 2 + 1];
133
134 wpa_snprintf_hex(txt, sizeof(txt), algo_agility, 4);
135 return txt;
136 }
137
138
139 /**
140 * ieee802_1x_mka_dump_basic_body -
141 */
142 static void
ieee802_1x_mka_dump_basic_body(struct ieee802_1x_mka_basic_body * body)143 ieee802_1x_mka_dump_basic_body(struct ieee802_1x_mka_basic_body *body)
144 {
145 size_t body_len;
146
147 if (!body)
148 return;
149
150 /* IEEE Std 802.1X-2010, Figure 11-8 */
151 body_len = get_mka_param_body_len(body);
152 wpa_printf(MSG_DEBUG, "MKA Basic Parameter Set");
153 wpa_printf(MSG_DEBUG, "\tMKA Version Identifier: %d", body->version);
154 wpa_printf(MSG_DEBUG, "\tKey Server Priority: %d", body->priority);
155 wpa_printf(MSG_DEBUG, "\tKey Server: %d", body->key_server);
156 wpa_printf(MSG_DEBUG, "\tMACsec Desired: %d", body->macsec_desired);
157 wpa_printf(MSG_DEBUG, "\tMACsec Capability: %d",
158 body->macsec_capability);
159 wpa_printf(MSG_DEBUG, "\tParameter set body length: %zu", body_len);
160 wpa_printf(MSG_DEBUG, "\tSCI: %s", sci_txt(&body->actor_sci));
161 wpa_printf(MSG_DEBUG, "\tActor's Member Identifier: %s",
162 mi_txt(body->actor_mi));
163 wpa_printf(MSG_DEBUG, "\tActor's Message Number: %d",
164 be_to_host32(body->actor_mn));
165 wpa_printf(MSG_DEBUG, "\tAlgorithm Agility: %s",
166 algo_agility_txt(body->algo_agility));
167 wpa_hexdump(MSG_DEBUG, "\tCAK Name", body->ckn,
168 body_len + MKA_HDR_LEN - sizeof(*body));
169 }
170
171
172 /**
173 * ieee802_1x_mka_dump_peer_body -
174 */
175 static void
ieee802_1x_mka_dump_peer_body(struct ieee802_1x_mka_peer_body * body)176 ieee802_1x_mka_dump_peer_body(struct ieee802_1x_mka_peer_body *body)
177 {
178 size_t body_len;
179 size_t i;
180 u8 *mi;
181 be32 mn;
182
183 if (body == NULL)
184 return;
185
186 /* IEEE Std 802.1X-2010, Figure 11-9 */
187 body_len = get_mka_param_body_len(body);
188 if (body->type == MKA_LIVE_PEER_LIST) {
189 wpa_printf(MSG_DEBUG, "Live Peer List parameter set");
190 wpa_printf(MSG_DEBUG, "\tBody Length: %zu", body_len);
191 } else if (body->type == MKA_POTENTIAL_PEER_LIST) {
192 wpa_printf(MSG_DEBUG, "Potential Peer List parameter set");
193 wpa_printf(MSG_DEBUG, "\tBody Length: %zu", body_len);
194 }
195
196 for (i = 0; i < body_len; i += MI_LEN + sizeof(mn)) {
197 mi = body->peer + i;
198 os_memcpy(&mn, mi + MI_LEN, sizeof(mn));
199 wpa_printf(MSG_DEBUG, "\tMember Id: %s Message Number: %d",
200 mi_txt(mi), be_to_host32(mn));
201 }
202 }
203
204
205 /**
206 * ieee802_1x_mka_dump_dist_sak_body -
207 */
208 static void
ieee802_1x_mka_dump_dist_sak_body(struct ieee802_1x_mka_dist_sak_body * body)209 ieee802_1x_mka_dump_dist_sak_body(struct ieee802_1x_mka_dist_sak_body *body)
210 {
211 size_t body_len;
212
213 if (body == NULL)
214 return;
215
216 /* IEEE Std 802.1X-2010, Figure 11-11 and 11-12 */
217 body_len = get_mka_param_body_len(body);
218 wpa_printf(MSG_DEBUG, "Distributed SAK parameter set");
219 wpa_printf(MSG_DEBUG, "\tDistributed AN........: %d", body->dan);
220 wpa_printf(MSG_DEBUG, "\tConfidentiality Offset: %d",
221 body->confid_offset);
222 wpa_printf(MSG_DEBUG, "\tBody Length...........: %zu", body_len);
223 if (!body_len)
224 return;
225
226 wpa_printf(MSG_DEBUG, "\tKey Number............: %d",
227 be_to_host32(body->kn));
228 if (body_len == 28) {
229 wpa_hexdump(MSG_DEBUG, "\tAES Key Wrap of SAK...:",
230 body->sak, 24);
231 } else if (body_len > CS_ID_LEN - sizeof(body->kn)) {
232 wpa_hexdump(MSG_DEBUG, "\tMACsec Cipher Suite...:",
233 body->sak, CS_ID_LEN);
234 wpa_hexdump(MSG_DEBUG, "\tAES Key Wrap of SAK...:",
235 body->sak + CS_ID_LEN,
236 body_len - CS_ID_LEN - sizeof(body->kn));
237 }
238 }
239
240
yes_no(int val)241 static const char * yes_no(int val)
242 {
243 return val ? "Yes" : "No";
244 }
245
246
247 /**
248 * ieee802_1x_mka_dump_sak_use_body -
249 */
250 static void
ieee802_1x_mka_dump_sak_use_body(struct ieee802_1x_mka_sak_use_body * body)251 ieee802_1x_mka_dump_sak_use_body(struct ieee802_1x_mka_sak_use_body *body)
252 {
253 int body_len;
254
255 if (body == NULL)
256 return;
257
258 /* IEEE Std 802.1X-2010, Figure 11-10 */
259 body_len = get_mka_param_body_len(body);
260 wpa_printf(MSG_DEBUG, "MACsec SAK Use parameter set");
261 wpa_printf(MSG_DEBUG, "\tLatest Key AN....: %d", body->lan);
262 wpa_printf(MSG_DEBUG, "\tLatest Key Tx....: %s", yes_no(body->ltx));
263 wpa_printf(MSG_DEBUG, "\tLatest Key Rx....: %s", yes_no(body->lrx));
264 wpa_printf(MSG_DEBUG, "\tOld Key AN.......: %d", body->oan);
265 wpa_printf(MSG_DEBUG, "\tOld Key Tx.......: %s", yes_no(body->otx));
266 wpa_printf(MSG_DEBUG, "\tOld Key Rx.......: %s", yes_no(body->orx));
267 wpa_printf(MSG_DEBUG, "\tPlain Tx.........: %s", yes_no(body->ptx));
268 wpa_printf(MSG_DEBUG, "\tPlain Rx.........: %s", yes_no(body->prx));
269 wpa_printf(MSG_DEBUG, "\tDelay Protect....: %s",
270 yes_no(body->delay_protect));
271 wpa_printf(MSG_DEBUG, "\tBody Length......: %d", body_len);
272 if (!body_len)
273 return;
274
275 wpa_printf(MSG_DEBUG, "\tKey Server MI....: %s", mi_txt(body->lsrv_mi));
276 wpa_printf(MSG_DEBUG, "\tKey Number.......: %u",
277 be_to_host32(body->lkn));
278 wpa_printf(MSG_DEBUG, "\tLowest PN........: %u",
279 be_to_host32(body->llpn));
280 wpa_printf(MSG_DEBUG, "\tOld Key Server MI: %s", mi_txt(body->osrv_mi));
281 wpa_printf(MSG_DEBUG, "\tOld Key Number...: %u",
282 be_to_host32(body->okn));
283 wpa_printf(MSG_DEBUG, "\tOld Lowest PN....: %u",
284 be_to_host32(body->olpn));
285 }
286
287
288 /**
289 * ieee802_1x_kay_get_participant -
290 */
291 static struct ieee802_1x_mka_participant *
ieee802_1x_kay_get_participant(struct ieee802_1x_kay * kay,const u8 * ckn,size_t len)292 ieee802_1x_kay_get_participant(struct ieee802_1x_kay *kay, const u8 *ckn,
293 size_t len)
294 {
295 struct ieee802_1x_mka_participant *participant;
296
297 dl_list_for_each(participant, &kay->participant_list,
298 struct ieee802_1x_mka_participant, list) {
299 if (participant->ckn.len == len &&
300 os_memcmp(participant->ckn.name, ckn,
301 participant->ckn.len) == 0)
302 return participant;
303 }
304
305 wpa_printf(MSG_DEBUG, "KaY: participant is not found");
306
307 return NULL;
308 }
309
310
311 /**
312 * ieee802_1x_kay_get_principal_participant -
313 */
314 static struct ieee802_1x_mka_participant *
ieee802_1x_kay_get_principal_participant(struct ieee802_1x_kay * kay)315 ieee802_1x_kay_get_principal_participant(struct ieee802_1x_kay *kay)
316 {
317 struct ieee802_1x_mka_participant *participant;
318
319 dl_list_for_each(participant, &kay->participant_list,
320 struct ieee802_1x_mka_participant, list) {
321 if (participant->principal)
322 return participant;
323 }
324
325 wpa_printf(MSG_DEBUG, "KaY: principal participant is not found");
326 return NULL;
327 }
328
329
get_peer_mi(struct dl_list * peers,const u8 * mi)330 static struct ieee802_1x_kay_peer * get_peer_mi(struct dl_list *peers,
331 const u8 *mi)
332 {
333 struct ieee802_1x_kay_peer *peer;
334
335 dl_list_for_each(peer, peers, struct ieee802_1x_kay_peer, list) {
336 if (os_memcmp(peer->mi, mi, MI_LEN) == 0)
337 return peer;
338 }
339
340 return NULL;
341 }
342
343
344 /**
345 * ieee802_1x_kay_get_potential_peer
346 */
347 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_get_potential_peer(struct ieee802_1x_mka_participant * participant,const u8 * mi)348 ieee802_1x_kay_get_potential_peer(
349 struct ieee802_1x_mka_participant *participant, const u8 *mi)
350 {
351 return get_peer_mi(&participant->potential_peers, mi);
352 }
353
354
355 /**
356 * ieee802_1x_kay_get_live_peer
357 */
358 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant * participant,const u8 * mi)359 ieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant *participant,
360 const u8 *mi)
361 {
362 return get_peer_mi(&participant->live_peers, mi);
363 }
364
365
366 /**
367 * ieee802_1x_kay_is_in_potential_peer
368 */
369 static bool
ieee802_1x_kay_is_in_potential_peer(struct ieee802_1x_mka_participant * participant,const u8 * mi)370 ieee802_1x_kay_is_in_potential_peer(
371 struct ieee802_1x_mka_participant *participant, const u8 *mi)
372 {
373 return ieee802_1x_kay_get_potential_peer(participant, mi) != NULL;
374 }
375
376
377 /**
378 * ieee802_1x_kay_is_in_live_peer
379 */
380 static bool
ieee802_1x_kay_is_in_live_peer(struct ieee802_1x_mka_participant * participant,const u8 * mi)381 ieee802_1x_kay_is_in_live_peer(
382 struct ieee802_1x_mka_participant *participant, const u8 *mi)
383 {
384 return ieee802_1x_kay_get_live_peer(participant, mi) != NULL;
385 }
386
387
388 /**
389 * ieee802_1x_kay_get_peer
390 */
391 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant * participant,const u8 * mi)392 ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant,
393 const u8 *mi)
394 {
395 struct ieee802_1x_kay_peer *peer;
396
397 peer = ieee802_1x_kay_get_live_peer(participant, mi);
398 if (peer)
399 return peer;
400
401 return ieee802_1x_kay_get_potential_peer(participant, mi);
402 }
403
404
405 /**
406 * ieee802_1x_kay_get_cipher_suite
407 */
408 static struct macsec_ciphersuite *
ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant * participant,const u8 * cs_id,unsigned int * idx)409 ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant,
410 const u8 *cs_id, unsigned int *idx)
411 {
412 unsigned int i;
413 u64 cs;
414 be64 _cs;
415
416 os_memcpy(&_cs, cs_id, CS_ID_LEN);
417 cs = be_to_host64(_cs);
418
419 for (i = 0; i < CS_TABLE_SIZE; i++) {
420 if (cipher_suite_tbl[i].id == cs) {
421 *idx = i;
422 return &cipher_suite_tbl[i];
423 }
424 }
425
426 return NULL;
427 }
428
429
mka_sci_u64(struct ieee802_1x_mka_sci * sci)430 u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci)
431 {
432 struct ieee802_1x_mka_sci tmp;
433
434 os_memcpy(tmp.addr, sci->addr, ETH_ALEN);
435 tmp.port = sci->port;
436
437 return *((u64 *) &tmp);
438 }
439
440
sci_equal(const struct ieee802_1x_mka_sci * a,const struct ieee802_1x_mka_sci * b)441 static bool sci_equal(const struct ieee802_1x_mka_sci *a,
442 const struct ieee802_1x_mka_sci *b)
443 {
444 return os_memcmp(a, b, sizeof(struct ieee802_1x_mka_sci)) == 0;
445 }
446
447
448 /**
449 * ieee802_1x_kay_get_peer_sci
450 */
451 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant * participant,const struct ieee802_1x_mka_sci * sci)452 ieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant *participant,
453 const struct ieee802_1x_mka_sci *sci)
454 {
455 struct ieee802_1x_kay_peer *peer;
456
457 dl_list_for_each(peer, &participant->live_peers,
458 struct ieee802_1x_kay_peer, list) {
459 if (sci_equal(&peer->sci, sci))
460 return peer;
461 }
462
463 dl_list_for_each(peer, &participant->potential_peers,
464 struct ieee802_1x_kay_peer, list) {
465 if (sci_equal(&peer->sci, sci))
466 return peer;
467 }
468
469 return NULL;
470 }
471
472
473 static void ieee802_1x_kay_use_data_key(struct data_key *pkey);
474
475 /**
476 * ieee802_1x_kay_init_receive_sa -
477 */
478 static struct receive_sa *
ieee802_1x_kay_init_receive_sa(struct receive_sc * psc,u8 an,u32 lowest_pn,struct data_key * key)479 ieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn,
480 struct data_key *key)
481 {
482 struct receive_sa *psa;
483
484 if (!psc || !key)
485 return NULL;
486
487 psa = os_zalloc(sizeof(*psa));
488 if (!psa) {
489 wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
490 return NULL;
491 }
492
493 ieee802_1x_kay_use_data_key(key);
494 psa->pkey = key;
495 psa->lowest_pn = lowest_pn;
496 psa->next_pn = lowest_pn;
497 psa->an = an;
498 psa->sc = psc;
499
500 os_get_time(&psa->created_time);
501 psa->in_use = false;
502
503 dl_list_add(&psc->sa_list, &psa->list);
504 wpa_printf(MSG_DEBUG,
505 "KaY: Create receive SA(an: %hhu lowest_pn: %u) of SC",
506 an, lowest_pn);
507
508 return psa;
509 }
510
511
512 static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey);
513
514 /**
515 * ieee802_1x_kay_deinit_receive_sa -
516 */
ieee802_1x_kay_deinit_receive_sa(struct receive_sa * psa)517 static void ieee802_1x_kay_deinit_receive_sa(struct receive_sa *psa)
518 {
519 ieee802_1x_kay_deinit_data_key(psa->pkey);
520 psa->pkey = NULL;
521 wpa_printf(MSG_DEBUG,
522 "KaY: Delete receive SA(an: %hhu) of SC",
523 psa->an);
524 dl_list_del(&psa->list);
525 os_free(psa);
526 }
527
528
529 /**
530 * ieee802_1x_kay_init_receive_sc -
531 */
532 static struct receive_sc *
ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci * psci)533 ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci)
534 {
535 struct receive_sc *psc;
536
537 if (!psci)
538 return NULL;
539
540 psc = os_zalloc(sizeof(*psc));
541 if (!psc) {
542 wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
543 return NULL;
544 }
545
546 os_memcpy(&psc->sci, psci, sizeof(psc->sci));
547
548 os_get_time(&psc->created_time);
549 psc->receiving = false;
550
551 dl_list_init(&psc->sa_list);
552 wpa_printf(MSG_DEBUG, "KaY: Create receive SC: SCI %s",
553 sci_txt(&psc->sci));
554
555 return psc;
556 }
557
558
ieee802_1x_delete_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * sa)559 static void ieee802_1x_delete_receive_sa(struct ieee802_1x_kay *kay,
560 struct receive_sa *sa)
561 {
562 secy_disable_receive_sa(kay, sa);
563 secy_delete_receive_sa(kay, sa);
564 ieee802_1x_kay_deinit_receive_sa(sa);
565 }
566
567
568 /**
569 * ieee802_1x_kay_deinit_receive_sc -
570 **/
571 static void
ieee802_1x_kay_deinit_receive_sc(struct ieee802_1x_mka_participant * participant,struct receive_sc * psc)572 ieee802_1x_kay_deinit_receive_sc(
573 struct ieee802_1x_mka_participant *participant, struct receive_sc *psc)
574 {
575 struct receive_sa *psa, *pre_sa;
576
577 wpa_printf(MSG_DEBUG, "KaY: Delete receive SC");
578 dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa,
579 list)
580 ieee802_1x_delete_receive_sa(participant->kay, psa);
581
582 dl_list_del(&psc->list);
583 secy_delete_receive_sc(participant->kay, psc);
584 os_free(psc);
585 }
586
587
ieee802_1x_kay_dump_peer(struct ieee802_1x_kay_peer * peer)588 static void ieee802_1x_kay_dump_peer(struct ieee802_1x_kay_peer *peer)
589 {
590 wpa_printf(MSG_DEBUG, "\tMI: %s MN: %d SCI: %s",
591 mi_txt(peer->mi), peer->mn, sci_txt(&peer->sci));
592 }
593
594
595 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_create_peer(const u8 * mi,u32 mn)596 ieee802_1x_kay_create_peer(const u8 *mi, u32 mn)
597 {
598 struct ieee802_1x_kay_peer *peer;
599 struct os_reltime now;
600
601 peer = os_zalloc(sizeof(*peer));
602 if (!peer) {
603 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
604 return NULL;
605 }
606
607 os_memcpy(peer->mi, mi, MI_LEN);
608 peer->mn = mn;
609 os_get_reltime(&now);
610 peer->expire = now.sec + MKA_LIFE_TIME / 1000;
611 peer->sak_used = false;
612 peer->missing_sak_use_count = 0;
613
614 return peer;
615 }
616
617
618 /**
619 * ieee802_1x_kay_create_live_peer
620 */
621 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant * participant,const u8 * mi,u32 mn)622 ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant,
623 const u8 *mi, u32 mn)
624 {
625 struct ieee802_1x_kay_peer *peer;
626 struct receive_sc *rxsc;
627
628 peer = ieee802_1x_kay_create_peer(mi, mn);
629 if (!peer)
630 return NULL;
631
632 os_memcpy(&peer->sci, &participant->current_peer_sci,
633 sizeof(peer->sci));
634
635 rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci);
636 if (!rxsc) {
637 os_free(peer);
638 return NULL;
639 }
640
641 if (secy_create_receive_sc(participant->kay, rxsc)) {
642 os_free(rxsc);
643 os_free(peer);
644 return NULL;
645 }
646 dl_list_add(&participant->live_peers, &peer->list);
647 dl_list_add(&participant->rxsc_list, &rxsc->list);
648
649 wpa_printf(MSG_DEBUG, "KaY: Live peer created");
650 ieee802_1x_kay_dump_peer(peer);
651
652 return peer;
653 }
654
655
656 /**
657 * ieee802_1x_kay_create_potential_peer
658 */
659 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_create_potential_peer(struct ieee802_1x_mka_participant * participant,const u8 * mi,u32 mn)660 ieee802_1x_kay_create_potential_peer(
661 struct ieee802_1x_mka_participant *participant, const u8 *mi, u32 mn)
662 {
663 struct ieee802_1x_kay_peer *peer;
664
665 peer = ieee802_1x_kay_create_peer(mi, mn);
666 if (!peer)
667 return NULL;
668
669 dl_list_add(&participant->potential_peers, &peer->list);
670
671 wpa_printf(MSG_DEBUG, "KaY: Potential peer created");
672 ieee802_1x_kay_dump_peer(peer);
673
674 return peer;
675 }
676
677
678 /**
679 * ieee802_1x_kay_move_live_peer
680 */
681 static struct ieee802_1x_kay_peer *
ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant * participant,u8 * mi,u32 mn)682 ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant,
683 u8 *mi, u32 mn)
684 {
685 struct ieee802_1x_kay_peer *peer;
686 struct receive_sc *rxsc;
687 struct os_reltime now;
688
689 peer = ieee802_1x_kay_get_potential_peer(participant, mi);
690 if (!peer)
691 return NULL;
692
693 rxsc = ieee802_1x_kay_init_receive_sc(&participant->current_peer_sci);
694 if (!rxsc)
695 return NULL;
696
697 os_memcpy(&peer->sci, &participant->current_peer_sci,
698 sizeof(peer->sci));
699 peer->mn = mn;
700 os_get_reltime(&now);
701 peer->expire = now.sec + MKA_LIFE_TIME / 1000;
702
703 wpa_printf(MSG_DEBUG, "KaY: Move potential peer to live peer");
704 ieee802_1x_kay_dump_peer(peer);
705
706 dl_list_del(&peer->list);
707 if (secy_create_receive_sc(participant->kay, rxsc)) {
708 wpa_printf(MSG_ERROR, "KaY: Can't create SC, discard peer");
709 os_free(rxsc);
710 os_free(peer);
711 return NULL;
712 }
713 dl_list_add_tail(&participant->live_peers, &peer->list);
714
715 dl_list_add(&participant->rxsc_list, &rxsc->list);
716
717 return peer;
718 }
719
720
721
722 /**
723 * ieee802_1x_mka_basic_body_present -
724 */
725 static bool
ieee802_1x_mka_basic_body_present(struct ieee802_1x_mka_participant * participant)726 ieee802_1x_mka_basic_body_present(
727 struct ieee802_1x_mka_participant *participant)
728 {
729 return true;
730 }
731
732
733 /**
734 * ieee802_1x_mka_basic_body_length -
735 */
736 static int
ieee802_1x_mka_basic_body_length(struct ieee802_1x_mka_participant * participant)737 ieee802_1x_mka_basic_body_length(struct ieee802_1x_mka_participant *participant)
738 {
739 int length;
740
741 length = sizeof(struct ieee802_1x_mka_basic_body);
742 length += participant->ckn.len;
743 return MKA_ALIGN_LENGTH(length);
744 }
745
746
747 /**
748 * ieee802_1x_mka_encode_basic_body
749 */
750 static int
ieee802_1x_mka_encode_basic_body(struct ieee802_1x_mka_participant * participant,struct wpabuf * buf)751 ieee802_1x_mka_encode_basic_body(
752 struct ieee802_1x_mka_participant *participant,
753 struct wpabuf *buf)
754 {
755 struct ieee802_1x_mka_basic_body *body;
756 struct ieee802_1x_kay *kay = participant->kay;
757 unsigned int length = sizeof(struct ieee802_1x_mka_basic_body);
758
759 length += participant->ckn.len;
760 body = wpabuf_put(buf, MKA_ALIGN_LENGTH(length));
761
762 body->version = kay->mka_version;
763 body->priority = kay->actor_priority;
764 /* The Key Server flag is set if and only if the participant has not
765 * decided that another participant is or will be the Key Server. */
766 if (participant->is_elected)
767 body->key_server = participant->is_key_server;
768 else
769 body->key_server = participant->can_be_key_server;
770
771 body->macsec_desired = kay->macsec_desired;
772 body->macsec_capability = kay->macsec_capable;
773 set_mka_param_body_len(body, length - MKA_HDR_LEN);
774
775 os_memcpy(body->actor_sci.addr, kay->actor_sci.addr,
776 sizeof(kay->actor_sci.addr));
777 body->actor_sci.port = kay->actor_sci.port;
778
779 os_memcpy(body->actor_mi, participant->mi, sizeof(body->actor_mi));
780 participant->mn = participant->mn + 1;
781 body->actor_mn = host_to_be32(participant->mn);
782 os_memcpy(body->algo_agility, kay->algo_agility,
783 sizeof(body->algo_agility));
784
785 os_memcpy(body->ckn, participant->ckn.name, participant->ckn.len);
786
787 ieee802_1x_mka_dump_basic_body(body);
788
789 return 0;
790 }
791
792
793 static bool
reset_participant_mi(struct ieee802_1x_mka_participant * participant)794 reset_participant_mi(struct ieee802_1x_mka_participant *participant)
795 {
796 if (os_get_random(participant->mi, sizeof(participant->mi)) < 0)
797 return false;
798 participant->mn = 0;
799
800 return true;
801 }
802
803
804 /**
805 * ieee802_1x_mka_decode_basic_body -
806 */
807 static struct ieee802_1x_mka_participant *
ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay * kay,const u8 * mka_msg,size_t msg_len)808 ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
809 size_t msg_len)
810 {
811 struct ieee802_1x_mka_participant *participant;
812 const struct ieee802_1x_mka_basic_body *body;
813 struct ieee802_1x_kay_peer *peer;
814 size_t ckn_len;
815 size_t body_len;
816
817 body = (const struct ieee802_1x_mka_basic_body *) mka_msg;
818
819 if (body->version > MKA_VERSION_ID) {
820 wpa_printf(MSG_DEBUG,
821 "KaY: Peer's version(%d) greater than MKA current version(%d)",
822 body->version, MKA_VERSION_ID);
823 }
824 if (kay->is_obliged_key_server && body->key_server) {
825 wpa_printf(MSG_DEBUG, "KaY: I must be key server - ignore MKPDU claiming to be from a key server");
826 return NULL;
827 }
828
829 body_len = get_mka_param_body_len(body);
830 if (body_len < sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN) {
831 wpa_printf(MSG_DEBUG, "KaY: Too small body length %zu",
832 body_len);
833 return NULL;
834 }
835 ckn_len = body_len -
836 (sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN);
837 participant = ieee802_1x_kay_get_participant(kay, body->ckn, ckn_len);
838 if (!participant) {
839 wpa_printf(MSG_DEBUG,
840 "KaY: Peer is not included in my CA - ignore MKPDU");
841 return NULL;
842 }
843
844 /* If the peer's MI is my MI, I will choose new MI */
845 if (os_memcmp(body->actor_mi, participant->mi, MI_LEN) == 0) {
846 if (!reset_participant_mi(participant))
847 return NULL;
848 wpa_printf(MSG_DEBUG,
849 "KaY: Peer using my MI - selected a new random MI: %s",
850 mi_txt(participant->mi));
851 }
852
853 os_memcpy(participant->current_peer_id.mi, body->actor_mi, MI_LEN);
854 participant->current_peer_id.mn = body->actor_mn;
855 os_memcpy(participant->current_peer_sci.addr, body->actor_sci.addr,
856 sizeof(participant->current_peer_sci.addr));
857 participant->current_peer_sci.port = body->actor_sci.port;
858
859 /* handler peer */
860 peer = ieee802_1x_kay_get_peer(participant, body->actor_mi);
861 if (!peer) {
862 /* Check duplicated SCI
863 *
864 * A duplicated SCI indicates either an active attacker or
865 * a valid peer whose MI is being changed. The latter scenario
866 * is more likely because to have gotten this far the received
867 * MKPDU must have had a valid ICV, indicating the peer holds
868 * the same CAK as our participant.
869 *
870 * Before creating a new peer object for the new MI we must
871 * clean up the resources (SCs and SAs) associated with the
872 * old peer. An easy way to do this is to ignore MKPDUs with
873 * the new MI's for now and just wait for the old peer to
874 * time out and clean itself up (within MKA_LIFE_TIME).
875 *
876 * This method is preferable to deleting the old peer here
877 * and now and continuing on with processing because if this
878 * MKPDU is from an attacker it's better to ignore the MKPDU
879 * than to process it (and delete a valid peer as well).
880 */
881 peer = ieee802_1x_kay_get_peer_sci(participant,
882 &body->actor_sci);
883 if (peer) {
884 os_time_t new_expire;
885 struct os_reltime now;
886
887 wpa_printf(MSG_WARNING,
888 "KaY: duplicated SCI detected - maybe active attacker or peer selected new MI - ignore MKPDU");
889 /* Reduce timeout to speed up this process but left the
890 * chance for old one to prove aliveness. */
891 os_get_reltime(&now);
892 new_expire = now.sec + MKA_HELLO_TIME * 1.5 / 1000;
893 if (peer->expire > new_expire)
894 peer->expire = new_expire;
895 return NULL;
896 }
897
898 peer = ieee802_1x_kay_create_potential_peer(
899 participant, body->actor_mi,
900 be_to_host32(body->actor_mn));
901 if (!peer) {
902 wpa_printf(MSG_DEBUG,
903 "KaY: No potential peer entry found - ignore MKPDU");
904 return NULL;
905 }
906
907 peer->macsec_desired = body->macsec_desired;
908 peer->macsec_capability = body->macsec_capability;
909 peer->is_key_server = body->key_server;
910 peer->key_server_priority = body->priority;
911 } else if (peer->mn < be_to_host32(body->actor_mn)) {
912 peer->mn = be_to_host32(body->actor_mn);
913 peer->macsec_desired = body->macsec_desired;
914 peer->macsec_capability = body->macsec_capability;
915 peer->is_key_server = body->key_server;
916 peer->key_server_priority = body->priority;
917 } else {
918 wpa_printf(MSG_WARNING,
919 "KaY: The peer MN did not increase - ignore MKPDU");
920 return NULL;
921 }
922
923 return participant;
924 }
925
926
927 /**
928 * ieee802_1x_mka_live_peer_body_present
929 */
930 static bool
ieee802_1x_mka_live_peer_body_present(struct ieee802_1x_mka_participant * participant)931 ieee802_1x_mka_live_peer_body_present(
932 struct ieee802_1x_mka_participant *participant)
933 {
934 return !dl_list_empty(&participant->live_peers);
935 }
936
937
938 /**
939 * ieee802_1x_kay_get_live_peer_length
940 */
941 static int
ieee802_1x_mka_get_live_peer_length(struct ieee802_1x_mka_participant * participant)942 ieee802_1x_mka_get_live_peer_length(
943 struct ieee802_1x_mka_participant *participant)
944 {
945 int len = MKA_HDR_LEN;
946 struct ieee802_1x_kay_peer *peer;
947
948 dl_list_for_each(peer, &participant->live_peers,
949 struct ieee802_1x_kay_peer, list)
950 len += sizeof(struct ieee802_1x_mka_peer_id);
951
952 return MKA_ALIGN_LENGTH(len);
953 }
954
955
956 /**
957 * ieee802_1x_mka_encode_live_peer_body -
958 */
959 static int
ieee802_1x_mka_encode_live_peer_body(struct ieee802_1x_mka_participant * participant,struct wpabuf * buf)960 ieee802_1x_mka_encode_live_peer_body(
961 struct ieee802_1x_mka_participant *participant,
962 struct wpabuf *buf)
963 {
964 struct ieee802_1x_mka_peer_body *body;
965 struct ieee802_1x_kay_peer *peer;
966 unsigned int length;
967 struct ieee802_1x_mka_peer_id *body_peer;
968
969 length = ieee802_1x_mka_get_live_peer_length(participant);
970 body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body));
971
972 body->type = MKA_LIVE_PEER_LIST;
973 set_mka_param_body_len(body, length - MKA_HDR_LEN);
974
975 dl_list_for_each(peer, &participant->live_peers,
976 struct ieee802_1x_kay_peer, list) {
977 body_peer = wpabuf_put(buf,
978 sizeof(struct ieee802_1x_mka_peer_id));
979 os_memcpy(body_peer->mi, peer->mi, MI_LEN);
980 body_peer->mn = host_to_be32(peer->mn);
981 }
982
983 ieee802_1x_mka_dump_peer_body(body);
984 return 0;
985 }
986
987 /**
988 * ieee802_1x_mka_potential_peer_body_present
989 */
990 static bool
ieee802_1x_mka_potential_peer_body_present(struct ieee802_1x_mka_participant * participant)991 ieee802_1x_mka_potential_peer_body_present(
992 struct ieee802_1x_mka_participant *participant)
993 {
994 return !dl_list_empty(&participant->potential_peers);
995 }
996
997
998 /**
999 * ieee802_1x_kay_get_potential_peer_length
1000 */
1001 static int
ieee802_1x_mka_get_potential_peer_length(struct ieee802_1x_mka_participant * participant)1002 ieee802_1x_mka_get_potential_peer_length(
1003 struct ieee802_1x_mka_participant *participant)
1004 {
1005 int len = MKA_HDR_LEN;
1006 struct ieee802_1x_kay_peer *peer;
1007
1008 dl_list_for_each(peer, &participant->potential_peers,
1009 struct ieee802_1x_kay_peer, list)
1010 len += sizeof(struct ieee802_1x_mka_peer_id);
1011
1012 return MKA_ALIGN_LENGTH(len);
1013 }
1014
1015
1016 /**
1017 * ieee802_1x_mka_encode_potential_peer_body -
1018 */
1019 static int
ieee802_1x_mka_encode_potential_peer_body(struct ieee802_1x_mka_participant * participant,struct wpabuf * buf)1020 ieee802_1x_mka_encode_potential_peer_body(
1021 struct ieee802_1x_mka_participant *participant,
1022 struct wpabuf *buf)
1023 {
1024 struct ieee802_1x_mka_peer_body *body;
1025 struct ieee802_1x_kay_peer *peer;
1026 unsigned int length;
1027 struct ieee802_1x_mka_peer_id *body_peer;
1028
1029 length = ieee802_1x_mka_get_potential_peer_length(participant);
1030 body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body));
1031
1032 body->type = MKA_POTENTIAL_PEER_LIST;
1033 set_mka_param_body_len(body, length - MKA_HDR_LEN);
1034
1035 dl_list_for_each(peer, &participant->potential_peers,
1036 struct ieee802_1x_kay_peer, list) {
1037 body_peer = wpabuf_put(buf,
1038 sizeof(struct ieee802_1x_mka_peer_id));
1039 os_memcpy(body_peer->mi, peer->mi, MI_LEN);
1040 body_peer->mn = host_to_be32(peer->mn);
1041 }
1042
1043 ieee802_1x_mka_dump_peer_body(body);
1044 return 0;
1045 }
1046
1047
1048 /**
1049 * ieee802_1x_mka_i_in_peerlist -
1050 */
1051 static bool
ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant * participant,const u8 * mka_msg,size_t msg_len)1052 ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant,
1053 const u8 *mka_msg, size_t msg_len)
1054 {
1055 struct ieee802_1x_mka_hdr *hdr;
1056 size_t body_len;
1057 size_t left_len;
1058 u8 body_type;
1059 const u8 *pos;
1060 size_t i;
1061
1062 for (pos = mka_msg, left_len = msg_len;
1063 left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN;
1064 left_len -= MKA_ALIGN_LENGTH(body_len) + MKA_HDR_LEN,
1065 pos += MKA_ALIGN_LENGTH(body_len) + MKA_HDR_LEN) {
1066 hdr = (struct ieee802_1x_mka_hdr *) pos;
1067 body_len = get_mka_param_body_len(hdr);
1068 body_type = get_mka_param_body_type(hdr);
1069
1070 if (left_len < (MKA_HDR_LEN + MKA_ALIGN_LENGTH(body_len) + DEFAULT_ICV_LEN)) {
1071 wpa_printf(MSG_ERROR,
1072 "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
1073 left_len, MKA_HDR_LEN,
1074 MKA_ALIGN_LENGTH(body_len),
1075 DEFAULT_ICV_LEN);
1076 return false;
1077 }
1078
1079 if (body_type != MKA_LIVE_PEER_LIST &&
1080 body_type != MKA_POTENTIAL_PEER_LIST)
1081 continue;
1082
1083 if ((body_len % 16) != 0) {
1084 wpa_printf(MSG_ERROR,
1085 "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets",
1086 body_len);
1087 continue;
1088 }
1089
1090 ieee802_1x_mka_dump_peer_body(
1091 (struct ieee802_1x_mka_peer_body *)pos);
1092
1093 for (i = 0; i < body_len;
1094 i += sizeof(struct ieee802_1x_mka_peer_id)) {
1095 const struct ieee802_1x_mka_peer_id *peer_mi;
1096
1097 peer_mi = (const struct ieee802_1x_mka_peer_id *)
1098 (pos + MKA_HDR_LEN + i);
1099 if (os_memcmp(peer_mi->mi, participant->mi,
1100 MI_LEN) == 0) {
1101 u32 mn = be_to_host32(peer_mi->mn);
1102
1103 wpa_printf(MSG_DEBUG,
1104 "KaY: My MI - received MN %u, most recently transmitted MN %u",
1105 mn, participant->mn);
1106 /* IEEE Std 802.1X-2010 is not exactly clear
1107 * which values of MN should be accepted here.
1108 * It uses "acceptably recent MN" language
1109 * without defining what would be acceptable
1110 * recent. For now, allow the last two used MN
1111 * values (i.e., peer having copied my MI,MN
1112 * from either of the last two MKPDUs that I
1113 * have sent). */
1114 if (mn == participant->mn ||
1115 (participant->mn > 1 &&
1116 mn == participant->mn - 1))
1117 return true;
1118 }
1119 }
1120 }
1121
1122 return false;
1123 }
1124
1125
1126 /**
1127 * ieee802_1x_mka_decode_live_peer_body -
1128 */
ieee802_1x_mka_decode_live_peer_body(struct ieee802_1x_mka_participant * participant,const u8 * peer_msg,size_t msg_len)1129 static int ieee802_1x_mka_decode_live_peer_body(
1130 struct ieee802_1x_mka_participant *participant,
1131 const u8 *peer_msg, size_t msg_len)
1132 {
1133 const struct ieee802_1x_mka_hdr *hdr;
1134 struct ieee802_1x_kay_peer *peer;
1135 size_t body_len;
1136 size_t i;
1137 bool is_included;
1138
1139 is_included = ieee802_1x_kay_is_in_live_peer(
1140 participant, participant->current_peer_id.mi);
1141
1142 hdr = (const struct ieee802_1x_mka_hdr *) peer_msg;
1143 body_len = get_mka_param_body_len(hdr);
1144 if (body_len % 16 != 0) {
1145 wpa_printf(MSG_ERROR,
1146 "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets",
1147 body_len);
1148 return -1;
1149 }
1150
1151 for (i = 0; i < body_len; i += sizeof(struct ieee802_1x_mka_peer_id)) {
1152 const struct ieee802_1x_mka_peer_id *peer_mi;
1153 u32 peer_mn;
1154
1155 peer_mi = (const struct ieee802_1x_mka_peer_id *)
1156 (peer_msg + MKA_HDR_LEN + i);
1157 peer_mn = be_to_host32(peer_mi->mn);
1158
1159 /* it is myself */
1160 if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) {
1161 /* My message id is used by other participant */
1162 if (peer_mn > participant->mn &&
1163 !reset_participant_mi(participant))
1164 wpa_printf(MSG_DEBUG, "KaY: Could not update mi");
1165 continue;
1166 }
1167
1168 if (!is_included)
1169 continue;
1170
1171 peer = ieee802_1x_kay_get_peer(participant, peer_mi->mi);
1172 if (peer) {
1173 peer->mn = peer_mn;
1174 } else if (!ieee802_1x_kay_create_potential_peer(
1175 participant, peer_mi->mi, peer_mn)) {
1176 return -1;
1177 }
1178 }
1179
1180 return 0;
1181 }
1182
1183
1184 /**
1185 * ieee802_1x_mka_decode_potential_peer_body -
1186 */
1187 static int
ieee802_1x_mka_decode_potential_peer_body(struct ieee802_1x_mka_participant * participant,const u8 * peer_msg,size_t msg_len)1188 ieee802_1x_mka_decode_potential_peer_body(
1189 struct ieee802_1x_mka_participant *participant,
1190 const u8 *peer_msg, size_t msg_len)
1191 {
1192 const struct ieee802_1x_mka_hdr *hdr;
1193 size_t body_len;
1194 size_t i;
1195
1196 hdr = (const struct ieee802_1x_mka_hdr *) peer_msg;
1197 body_len = get_mka_param_body_len(hdr);
1198 if (body_len % 16 != 0) {
1199 wpa_printf(MSG_ERROR,
1200 "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets",
1201 body_len);
1202 return -1;
1203 }
1204
1205 for (i = 0; i < body_len; i += sizeof(struct ieee802_1x_mka_peer_id)) {
1206 const struct ieee802_1x_mka_peer_id *peer_mi;
1207 u32 peer_mn;
1208
1209 peer_mi = (struct ieee802_1x_mka_peer_id *)
1210 (peer_msg + MKA_HDR_LEN + i);
1211 peer_mn = be_to_host32(peer_mi->mn);
1212
1213 /* it is myself */
1214 if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) {
1215 /* My message id is used by other participant */
1216 if (peer_mn > participant->mn &&
1217 !reset_participant_mi(participant))
1218 wpa_printf(MSG_DEBUG, "KaY: Could not update MI");
1219 continue;
1220 }
1221 }
1222
1223 return 0;
1224 }
1225
1226
1227 /**
1228 * ieee802_1x_mka_sak_use_body_present
1229 */
1230 static bool
ieee802_1x_mka_sak_use_body_present(struct ieee802_1x_mka_participant * participant)1231 ieee802_1x_mka_sak_use_body_present(
1232 struct ieee802_1x_mka_participant *participant)
1233 {
1234 return participant->to_use_sak;
1235 }
1236
1237
1238 /**
1239 * ieee802_1x_mka_get_sak_use_length
1240 */
1241 static int
ieee802_1x_mka_get_sak_use_length(struct ieee802_1x_mka_participant * participant)1242 ieee802_1x_mka_get_sak_use_length(
1243 struct ieee802_1x_mka_participant *participant)
1244 {
1245 int length = MKA_HDR_LEN;
1246
1247 if (participant->kay->macsec_desired && participant->advised_desired)
1248 length = sizeof(struct ieee802_1x_mka_sak_use_body);
1249
1250 return MKA_ALIGN_LENGTH(length);
1251 }
1252
1253
1254 /**
1255 * ieee802_1x_mka_get_lpn
1256 */
1257 static u32
ieee802_1x_mka_get_lpn(struct ieee802_1x_mka_participant * principal,struct ieee802_1x_mka_ki * ki)1258 ieee802_1x_mka_get_lpn(struct ieee802_1x_mka_participant *principal,
1259 struct ieee802_1x_mka_ki *ki)
1260 {
1261 struct transmit_sa *txsa;
1262 u32 lpn = 0;
1263
1264 dl_list_for_each(txsa, &principal->txsc->sa_list,
1265 struct transmit_sa, list) {
1266 if (is_ki_equal(&txsa->pkey->key_identifier, ki)) {
1267 /* Per IEEE Std 802.1X-2010, Clause 9, "Each SecY uses
1268 * MKA to communicate the lowest PN used for
1269 * transmission with the SAK within the last two
1270 * seconds". Achieve this 2 second delay by setting the
1271 * lpn using the transmit next PN (i.e., txsa->next_pn)
1272 * that was read last time here (i.e., mka_hello_time
1273 * 2 seconds ago).
1274 *
1275 * The lowest acceptable PN is the same as the last
1276 * transmitted PN, which is one less than the next
1277 * transmit PN.
1278 *
1279 * NOTE: This method only works if mka_hello_time is 2s.
1280 */
1281 lpn = (txsa->next_pn > 0) ? (txsa->next_pn - 1) : 0;
1282
1283 /* Now read the current transmit next PN for use next
1284 * time through. */
1285 secy_get_transmit_next_pn(principal->kay, txsa);
1286 break;
1287 }
1288 }
1289
1290 if (lpn == 0)
1291 lpn = 1;
1292
1293 return lpn;
1294 }
1295
1296
1297 /**
1298 * ieee802_1x_mka_encode_sak_use_body -
1299 */
1300 static int
ieee802_1x_mka_encode_sak_use_body(struct ieee802_1x_mka_participant * participant,struct wpabuf * buf)1301 ieee802_1x_mka_encode_sak_use_body(
1302 struct ieee802_1x_mka_participant *participant,
1303 struct wpabuf *buf)
1304 {
1305 struct ieee802_1x_mka_sak_use_body *body;
1306 struct ieee802_1x_kay *kay = participant->kay;
1307 unsigned int length;
1308 u32 olpn, llpn;
1309
1310 length = ieee802_1x_mka_get_sak_use_length(participant);
1311 body = wpabuf_put(buf, length);
1312
1313 body->type = MKA_SAK_USE;
1314 set_mka_param_body_len(body, length - MKA_HDR_LEN);
1315
1316 if (length == MKA_HDR_LEN) {
1317 body->ptx = true;
1318 body->prx = true;
1319 body->lan = 0;
1320 body->lrx = false;
1321 body->ltx = false;
1322 body->delay_protect = false;
1323 return 0;
1324 }
1325
1326 /* data delay protect */
1327 body->delay_protect = kay->mka_hello_time <= MKA_BOUNDED_HELLO_TIME;
1328 /* lowest accept packet numbers */
1329 olpn = ieee802_1x_mka_get_lpn(participant, &participant->oki);
1330 body->olpn = host_to_be32(olpn);
1331 llpn = ieee802_1x_mka_get_lpn(participant, &participant->lki);
1332 body->llpn = host_to_be32(llpn);
1333 if (participant->is_key_server) {
1334 /* The CP will spend most of it's time in RETIRE where only
1335 * the old key is populated. Therefore we should be checking
1336 * the OLPN most of the time.
1337 */
1338 if (participant->lrx) {
1339 if (llpn > kay->pn_exhaustion) {
1340 wpa_printf(MSG_WARNING,
1341 "KaY: My LLPN exhaustion");
1342 participant->new_sak = true;
1343 }
1344 } else {
1345 if (olpn > kay->pn_exhaustion) {
1346 wpa_printf(MSG_WARNING,
1347 "KaY: My OLPN exhaustion");
1348 participant->new_sak = true;
1349 }
1350 }
1351 }
1352
1353 /* plain tx, plain rx */
1354 body->ptx = !kay->macsec_protect;
1355 body->prx = kay->macsec_validate != Strict;
1356
1357 /* latest key: rx, tx, key server member identifier key number */
1358 body->lan = participant->lan;
1359 os_memcpy(body->lsrv_mi, participant->lki.mi, sizeof(body->lsrv_mi));
1360 body->lkn = host_to_be32(participant->lki.kn);
1361 body->lrx = participant->lrx;
1362 body->ltx = participant->ltx;
1363
1364 /* old key: rx, tx, key server member identifier key number */
1365 body->oan = participant->oan;
1366 if (participant->oki.kn != participant->lki.kn &&
1367 participant->oki.kn != 0) {
1368 body->otx = true;
1369 body->orx = true;
1370 os_memcpy(body->osrv_mi, participant->oki.mi,
1371 sizeof(body->osrv_mi));
1372 body->okn = host_to_be32(participant->oki.kn);
1373 } else {
1374 body->otx = false;
1375 body->orx = false;
1376 }
1377
1378 /* set CP's variable */
1379 if (body->ltx) {
1380 kay->tx_enable = true;
1381 kay->port_enable = true;
1382 }
1383 if (body->lrx)
1384 kay->rx_enable = true;
1385
1386 ieee802_1x_mka_dump_sak_use_body(body);
1387 return 0;
1388 }
1389
1390
1391 /**
1392 * ieee802_1x_mka_decode_sak_use_body -
1393 */
1394 static int
ieee802_1x_mka_decode_sak_use_body(struct ieee802_1x_mka_participant * participant,const u8 * mka_msg,size_t msg_len)1395 ieee802_1x_mka_decode_sak_use_body(
1396 struct ieee802_1x_mka_participant *participant,
1397 const u8 *mka_msg, size_t msg_len)
1398 {
1399 struct ieee802_1x_mka_hdr *hdr;
1400 struct ieee802_1x_mka_sak_use_body *body;
1401 struct ieee802_1x_kay_peer *peer;
1402 struct data_key *sa_key = NULL;
1403 size_t body_len;
1404 struct ieee802_1x_mka_ki ki;
1405 u32 lpn;
1406 struct ieee802_1x_kay *kay = participant->kay;
1407 u32 olpn, llpn;
1408
1409 if (!participant->principal) {
1410 wpa_printf(MSG_WARNING, "KaY: Participant is not principal");
1411 return -1;
1412 }
1413 peer = ieee802_1x_kay_get_live_peer(participant,
1414 participant->current_peer_id.mi);
1415 if (!peer) {
1416 wpa_printf(MSG_WARNING,
1417 "KaY: The peer (%s) is not my live peer - ignore MACsec SAK Use parameter set",
1418 mi_txt(participant->current_peer_id.mi));
1419 return -1;
1420 }
1421
1422 hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
1423 body_len = get_mka_param_body_len(hdr);
1424 body = (struct ieee802_1x_mka_sak_use_body *) mka_msg;
1425 ieee802_1x_mka_dump_sak_use_body(body);
1426
1427 if ((body_len != 0) && (body_len < 40)) {
1428 wpa_printf(MSG_ERROR,
1429 "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 0, 40, or more octets",
1430 body_len);
1431 return -1;
1432 }
1433
1434 /* TODO: what action should I take when peer does not support MACsec */
1435 if (body_len == 0) {
1436 wpa_printf(MSG_WARNING, "KaY: Peer does not support MACsec");
1437 return 0;
1438 }
1439
1440 /* TODO: when the plain tx or rx of peer is true, should I change
1441 * the attribute of controlled port
1442 */
1443 if (body->prx)
1444 wpa_printf(MSG_WARNING, "KaY: peer's plain rx are TRUE");
1445
1446 if (body->ptx)
1447 wpa_printf(MSG_WARNING, "KaY: peer's plain tx are TRUE");
1448 /* TODO: how to set the MACsec hardware when delay_protect is true */
1449 if (body->delay_protect &&
1450 (!be_to_host32(body->llpn) || !be_to_host32(body->olpn))) {
1451 wpa_printf(MSG_WARNING,
1452 "KaY: Lowest packet number should be greater than 0 when delay_protect is TRUE");
1453 return -1;
1454 }
1455
1456 olpn = be_to_host32(body->olpn);
1457 llpn = be_to_host32(body->llpn);
1458
1459 /* Our most recent distributed key should be the first in the list.
1460 * If it doesn't exist then we can't really do anything.
1461 * Be lenient and don't return error here as there are legitimate cases
1462 * where this can happen such as when a new participant joins the CA and
1463 * the first frame it receives can have a SAKuse but not distSAK.
1464 */
1465 sa_key = dl_list_first(&participant->sak_list, struct data_key, list);
1466 if (!sa_key) {
1467 wpa_printf(MSG_INFO,
1468 "KaY: We don't have a latest distributed key - ignore SAK use");
1469 return 0;
1470 }
1471
1472 /* The peer's most recent key will be the "latest key" if it is present
1473 * otherwise it will be the "old key" if in the RETIRE state.
1474 */
1475 if (body->lrx) {
1476 os_memcpy(ki.mi, body->lsrv_mi, sizeof(ki.mi));
1477 ki.kn = be_to_host32(body->lkn);
1478 lpn = llpn;
1479 } else {
1480 os_memcpy(ki.mi, body->osrv_mi, sizeof(ki.mi));
1481 ki.kn = be_to_host32(body->okn);
1482 lpn = olpn;
1483 }
1484
1485 /* If the most recent distributed keys don't agree then someone is out
1486 * of sync. Perhaps non key server hasn't processed the most recent
1487 * distSAK yet and the key server is processing an old packet after it
1488 * has done distSAK. Be lenient and don't return error in this
1489 * particular case; otherwise, the key server will reset its MI and
1490 * cause a traffic disruption which is really undesired for a simple
1491 * timing issue.
1492 */
1493 if (!is_ki_equal(&sa_key->key_identifier, &ki)) {
1494 wpa_printf(MSG_INFO,
1495 "KaY: Distributed keys don't match - ignore SAK use");
1496 return 0;
1497 }
1498 sa_key->next_pn = lpn;
1499
1500 /* The key server must check that all peers are using the most recent
1501 * distributed key. Non key servers must check if the key server is
1502 * transmitting.
1503 */
1504 if (participant->is_key_server) {
1505 struct ieee802_1x_kay_peer *peer_iter;
1506 bool all_receiving = true;
1507
1508 /* Distributed keys are equal from above comparison. */
1509 peer->sak_used = true;
1510
1511 dl_list_for_each(peer_iter, &participant->live_peers,
1512 struct ieee802_1x_kay_peer, list) {
1513 if (!peer_iter->sak_used) {
1514 all_receiving = false;
1515 break;
1516 }
1517 }
1518 if (all_receiving) {
1519 participant->to_dist_sak = false;
1520 ieee802_1x_cp_set_allreceiving(kay->cp, true);
1521 ieee802_1x_cp_sm_step(kay->cp);
1522 }
1523 } else if (peer->is_key_server) {
1524 if (body->ltx) {
1525 ieee802_1x_cp_set_servertransmitting(kay->cp, true);
1526 ieee802_1x_cp_sm_step(kay->cp);
1527 }
1528 }
1529
1530 /* If I'm key server, and detects peer member PN exhaustion, rekey.
1531 * We only need to check the PN of the most recent distributed key. This
1532 * could be the peer's "latest" or "old" key depending on its current
1533 * state. If both "old" and "latest" keys are present then the "old" key
1534 * has already been exhausted.
1535 */
1536 if (participant->is_key_server && lpn > kay->pn_exhaustion) {
1537 participant->new_sak = true;
1538 wpa_printf(MSG_WARNING, "KaY: Peer LPN exhaustion");
1539 }
1540
1541 /* Get the associated RX SAs of the keys for delay protection since both
1542 * can be in use. Delay protect window (communicated via MKA) is tighter
1543 * than SecY's current replay protect window, so tell SecY the new (and
1544 * higher) lpn.
1545 */
1546 if (body->delay_protect) {
1547 struct receive_sc *rxsc;
1548 struct receive_sa *rxsa;
1549 bool found = false;
1550
1551 dl_list_for_each(rxsc, &participant->rxsc_list,
1552 struct receive_sc, list) {
1553 dl_list_for_each(rxsa, &rxsc->sa_list,
1554 struct receive_sa, list) {
1555 if (sa_key && rxsa->pkey == sa_key) {
1556 found = true;
1557 break;
1558 }
1559 }
1560 if (found)
1561 break;
1562 }
1563 if (found) {
1564 secy_get_receive_lowest_pn(participant->kay, rxsa);
1565 if (lpn > rxsa->lowest_pn) {
1566 rxsa->lowest_pn = lpn;
1567 secy_set_receive_lowest_pn(participant->kay,
1568 rxsa);
1569 wpa_printf(MSG_DEBUG,
1570 "KaY: update dist LPN=0x%x", lpn);
1571 }
1572 }
1573
1574 /* FIX: Delay protection for the SA being replaced is not
1575 * implemented. Note that this key will be active for at least
1576 * MKA_SAK_RETIRE_TIME (3 seconds) but could be longer depending
1577 * on how long it takes to get from RECEIVE to TRANSMITTING or
1578 * if going via ABANDON. Delay protection does allow PNs within
1579 * a 2 second window, so getting PN would be a lot of work for
1580 * just 1 second's worth of protection.
1581 */
1582 }
1583
1584 return 0;
1585 }
1586
1587
1588 /**
1589 * ieee802_1x_mka_dist_sak_body_present
1590 */
1591 static bool
ieee802_1x_mka_dist_sak_body_present(struct ieee802_1x_mka_participant * participant)1592 ieee802_1x_mka_dist_sak_body_present(
1593 struct ieee802_1x_mka_participant *participant)
1594 {
1595 return participant->is_key_server && participant->to_dist_sak &&
1596 participant->new_key;
1597 }
1598
1599
1600 /**
1601 * ieee802_1x_kay_get_dist_sak_length
1602 */
1603 static int
ieee802_1x_mka_get_dist_sak_length(struct ieee802_1x_mka_participant * participant)1604 ieee802_1x_mka_get_dist_sak_length(
1605 struct ieee802_1x_mka_participant *participant)
1606 {
1607 int length = MKA_HDR_LEN;
1608 unsigned int cs_index = participant->kay->macsec_csindex;
1609
1610 if (participant->advised_desired && cs_index < CS_TABLE_SIZE) {
1611 length = sizeof(struct ieee802_1x_mka_dist_sak_body);
1612 if (cs_index != DEFAULT_CS_INDEX)
1613 length += CS_ID_LEN;
1614
1615 length += cipher_suite_tbl[cs_index].sak_len + 8;
1616 }
1617
1618 return MKA_ALIGN_LENGTH(length);
1619 }
1620
1621
1622 /**
1623 * ieee802_1x_mka_encode_dist_sak_body -
1624 */
1625 static int
ieee802_1x_mka_encode_dist_sak_body(struct ieee802_1x_mka_participant * participant,struct wpabuf * buf)1626 ieee802_1x_mka_encode_dist_sak_body(
1627 struct ieee802_1x_mka_participant *participant,
1628 struct wpabuf *buf)
1629 {
1630 struct ieee802_1x_mka_dist_sak_body *body;
1631 struct data_key *sak;
1632 unsigned int length;
1633 unsigned int cs_index;
1634 int sak_pos;
1635
1636 length = ieee802_1x_mka_get_dist_sak_length(participant);
1637 body = wpabuf_put(buf, length);
1638 body->type = MKA_DISTRIBUTED_SAK;
1639 set_mka_param_body_len(body, length - MKA_HDR_LEN);
1640 if (length == MKA_HDR_LEN) {
1641 body->confid_offset = 0;
1642 body->dan = 0;
1643 return 0;
1644 }
1645
1646 sak = participant->new_key;
1647 if (!sak) {
1648 wpa_printf(MSG_DEBUG,
1649 "KaY: No SAK available to build Distributed SAK parameter set");
1650 return -1;
1651 }
1652 body->confid_offset = sak->confidentiality_offset;
1653 body->dan = sak->an;
1654 body->kn = host_to_be32(sak->key_identifier.kn);
1655 cs_index = participant->kay->macsec_csindex;
1656 sak_pos = 0;
1657 if (cs_index >= CS_TABLE_SIZE)
1658 return -1;
1659 if (cs_index != DEFAULT_CS_INDEX) {
1660 be64 cs;
1661
1662 cs = host_to_be64(cipher_suite_tbl[cs_index].id);
1663 os_memcpy(body->sak, &cs, CS_ID_LEN);
1664 sak_pos = CS_ID_LEN;
1665 }
1666 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
1667 if (aidl_psk_aes_wrap(participant->kek.key, participant->kek.len,
1668 cipher_suite_tbl[cs_index].sak_len / 8,
1669 sak->key, body->sak + sak_pos)) {
1670 #else
1671 if (aes_wrap(participant->kek.key, participant->kek.len,
1672 cipher_suite_tbl[cs_index].sak_len / 8,
1673 sak->key, body->sak + sak_pos)) {
1674 #endif
1675 wpa_printf(MSG_ERROR, "KaY: AES wrap failed");
1676 return -1;
1677 }
1678
1679 ieee802_1x_mka_dump_dist_sak_body(body);
1680
1681 return 0;
1682 }
1683
1684
1685 /**
1686 * ieee802_1x_kay_init_data_key -
1687 */
1688 static void ieee802_1x_kay_init_data_key(struct data_key *pkey)
1689 {
1690 pkey->transmits = true;
1691 pkey->receives = true;
1692 os_get_time(&pkey->created_time);
1693
1694 pkey->next_pn = 1;
1695 pkey->user = 1;
1696 }
1697
1698
1699 /**
1700 * ieee802_1x_kay_decode_dist_sak_body -
1701 */
1702 static int
1703 ieee802_1x_mka_decode_dist_sak_body(
1704 struct ieee802_1x_mka_participant *participant,
1705 const u8 *mka_msg, size_t msg_len)
1706 {
1707 struct ieee802_1x_mka_hdr *hdr;
1708 struct ieee802_1x_mka_dist_sak_body *body;
1709 struct ieee802_1x_kay_peer *peer;
1710 struct macsec_ciphersuite *cs;
1711 size_t body_len;
1712 struct data_key *sa_key = NULL;
1713 int sak_len;
1714 u8 *wrap_sak;
1715 u8 *unwrap_sak;
1716 struct ieee802_1x_kay *kay = participant->kay;
1717
1718 hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
1719 body_len = get_mka_param_body_len(hdr);
1720 if ((body_len != 0) && (body_len != 28) && (body_len < 36)) {
1721 wpa_printf(MSG_ERROR,
1722 "KaY: MKA Use SAK Packet Body Length (%zu bytes) should be 0, 28, 36, or more octets",
1723 body_len);
1724 return -1;
1725 }
1726
1727 if (!participant->principal) {
1728 wpa_printf(MSG_ERROR,
1729 "KaY: I can't accept the distributed SAK as I am not principal");
1730 return -1;
1731 }
1732 if (participant->is_key_server) {
1733 wpa_printf(MSG_ERROR,
1734 "KaY: Reject distributed SAK since I'm a key server");
1735 return -1;
1736 }
1737 if (!kay->macsec_desired ||
1738 kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
1739 wpa_printf(MSG_ERROR,
1740 "KaY: I am not MACsec-desired or without MACsec capable");
1741 return -1;
1742 }
1743
1744 peer = ieee802_1x_kay_get_live_peer(participant,
1745 participant->current_peer_id.mi);
1746 if (!peer) {
1747 wpa_printf(MSG_ERROR,
1748 "KaY: The key server is not in my live peers list");
1749 return -1;
1750 }
1751 if (!sci_equal(&kay->key_server_sci, &peer->sci)) {
1752 wpa_printf(MSG_ERROR, "KaY: The key server is not elected");
1753 return -1;
1754 }
1755
1756 if (body_len == 0) {
1757 kay->authenticated = true;
1758 kay->secured = false;
1759 kay->failed = false;
1760 participant->advised_desired = false;
1761 ieee802_1x_cp_connect_authenticated(kay->cp);
1762 ieee802_1x_cp_sm_step(kay->cp);
1763 wpa_printf(MSG_WARNING, "KaY: The Key server advise no MACsec");
1764 participant->to_use_sak = false;
1765 return 0;
1766 }
1767
1768 participant->advised_desired = true;
1769 kay->authenticated = false;
1770 kay->secured = true;
1771 kay->failed = false;
1772 ieee802_1x_cp_connect_secure(kay->cp);
1773 ieee802_1x_cp_sm_step(kay->cp);
1774
1775 body = (struct ieee802_1x_mka_dist_sak_body *)mka_msg;
1776 ieee802_1x_mka_dump_dist_sak_body(body);
1777 dl_list_for_each(sa_key, &participant->sak_list, struct data_key, list)
1778 {
1779 if (os_memcmp(sa_key->key_identifier.mi,
1780 participant->current_peer_id.mi, MI_LEN) == 0 &&
1781 sa_key->key_identifier.kn == be_to_host32(body->kn)) {
1782 wpa_printf(MSG_DEBUG,
1783 "KaY: SAK has already been installed - do not set it again");
1784 return 0;
1785 }
1786 }
1787
1788 if (body_len == 28) {
1789 sak_len = DEFAULT_SA_KEY_LEN;
1790 wrap_sak = body->sak;
1791 kay->macsec_csindex = DEFAULT_CS_INDEX;
1792 cs = &cipher_suite_tbl[kay->macsec_csindex];
1793 } else {
1794 unsigned int idx;
1795
1796 cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak,
1797 &idx);
1798 if (!cs) {
1799 wpa_printf(MSG_ERROR,
1800 "KaY: I can't support the Cipher Suite advised by key server");
1801 return -1;
1802 }
1803 sak_len = cs->sak_len;
1804 wrap_sak = body->sak + CS_ID_LEN;
1805 kay->macsec_csindex = idx;
1806 }
1807
1808 unwrap_sak = os_zalloc(sak_len);
1809 if (!unwrap_sak) {
1810 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
1811 return -1;
1812 }
1813 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
1814 if (aidl_psk_aes_unwrap(participant->kek.key, participant->kek.len,
1815 sak_len >> 3, wrap_sak, unwrap_sak)) {
1816 #else
1817 if (aes_unwrap(participant->kek.key, participant->kek.len,
1818 sak_len >> 3, wrap_sak, unwrap_sak)) {
1819 #endif
1820 wpa_printf(MSG_ERROR, "KaY: AES unwrap failed");
1821 os_free(unwrap_sak);
1822 return -1;
1823 }
1824 wpa_hexdump_key(MSG_DEBUG, "\tAES Key Unwrap of SAK.:",
1825 unwrap_sak, sak_len);
1826
1827 sa_key = os_zalloc(sizeof(*sa_key));
1828 if (!sa_key) {
1829 os_free(unwrap_sak);
1830 return -1;
1831 }
1832
1833 os_memcpy(&sa_key->key_identifier.mi, &participant->current_peer_id.mi,
1834 MI_LEN);
1835 sa_key->key_identifier.kn = be_to_host32(body->kn);
1836
1837 sa_key->key = unwrap_sak;
1838 sa_key->key_len = sak_len;
1839
1840 sa_key->confidentiality_offset = body->confid_offset;
1841 sa_key->an = body->dan;
1842 ieee802_1x_kay_init_data_key(sa_key);
1843
1844 ieee802_1x_kay_use_data_key(sa_key);
1845 dl_list_add(&participant->sak_list, &sa_key->list);
1846
1847 ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id);
1848 ieee802_1x_cp_sm_step(kay->cp);
1849 ieee802_1x_cp_set_offset(kay->cp, body->confid_offset);
1850 ieee802_1x_cp_sm_step(kay->cp);
1851 ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier);
1852 ieee802_1x_cp_set_distributedan(kay->cp, body->dan);
1853 ieee802_1x_cp_signal_newsak(kay->cp);
1854 ieee802_1x_cp_sm_step(kay->cp);
1855
1856 kay->rcvd_keys++;
1857 participant->to_use_sak = true;
1858
1859 /*
1860 * The key server may not include dist sak and use sak in one packet.
1861 * Meanwhile, after dist sak, the current participant (non-key server)
1862 * will install SC or SA(s) after decoding the dist sak which may take
1863 * few seconds in real physical platforms. Meanwhile, the peer expire
1864 * time is always initialized at adding the key server to peer list.
1865 * The gap between adding the key server to peer list and processing
1866 * next use sak packet may exceed the threshold of MKA_LIFE_TIME (6 s).
1867 * It will cause an unexpected cleanup (delete SC and SA(s)), so,
1868 * update the expire timeout at dist sak also. */
1869 peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
1870
1871 return 0;
1872 }
1873
1874
1875 /**
1876 * ieee802_1x_mka_icv_body_present
1877 */
1878 static bool
1879 ieee802_1x_mka_icv_body_present(struct ieee802_1x_mka_participant *participant)
1880 {
1881 return true;
1882 }
1883
1884
1885 /**
1886 * ieee802_1x_kay_get_icv_length
1887 */
1888 static int
1889 ieee802_1x_mka_get_icv_length(struct ieee802_1x_mka_participant *participant)
1890 {
1891 int length;
1892
1893 /* Determine if we need space for the ICV Indicator */
1894 if (mka_alg_tbl[participant->kay->mka_algindex].icv_len !=
1895 DEFAULT_ICV_LEN)
1896 length = sizeof(struct ieee802_1x_mka_icv_body);
1897 else
1898 length = 0;
1899 length += mka_alg_tbl[participant->kay->mka_algindex].icv_len;
1900
1901 return MKA_ALIGN_LENGTH(length);
1902 }
1903
1904
1905 /**
1906 * ieee802_1x_mka_encode_icv_body -
1907 */
1908 static int
1909 ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant,
1910 struct wpabuf *buf)
1911 {
1912 struct ieee802_1x_mka_icv_body *body;
1913 unsigned int length;
1914 u8 cmac[MAX_ICV_LEN];
1915
1916 length = ieee802_1x_mka_get_icv_length(participant);
1917 if (mka_alg_tbl[participant->kay->mka_algindex].icv_len !=
1918 DEFAULT_ICV_LEN) {
1919 wpa_printf(MSG_DEBUG, "KaY: ICV Indicator");
1920 body = wpabuf_put(buf, MKA_HDR_LEN);
1921 body->type = MKA_ICV_INDICATOR;
1922 length -= MKA_HDR_LEN;
1923 set_mka_param_body_len(body, length);
1924 }
1925
1926 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
1927 if (aidl_psk_icv_hash(
1928 #else
1929 if (mka_alg_tbl[participant->kay->mka_algindex].icv_hash(
1930 #endif
1931 participant->ick.key, participant->ick.len,
1932 wpabuf_head(buf), wpabuf_len(buf), cmac)) {
1933 wpa_printf(MSG_ERROR, "KaY: failed to calculate ICV");
1934 return -1;
1935 }
1936 wpa_hexdump(MSG_DEBUG, "KaY: ICV", cmac, length);
1937
1938 os_memcpy(wpabuf_put(buf, length), cmac, length);
1939
1940 return 0;
1941 }
1942
1943 /**
1944 * ieee802_1x_mka_decode_icv_body -
1945 */
1946 static const u8 *
1947 ieee802_1x_mka_decode_icv_body(struct ieee802_1x_mka_participant *participant,
1948 const u8 *mka_msg, size_t msg_len)
1949 {
1950 const struct ieee802_1x_mka_hdr *hdr;
1951 const struct ieee802_1x_mka_icv_body *body;
1952 size_t body_len;
1953 size_t left_len;
1954 u8 body_type;
1955 const u8 *pos;
1956
1957 pos = mka_msg;
1958 left_len = msg_len;
1959 while (left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN) {
1960 hdr = (const struct ieee802_1x_mka_hdr *) pos;
1961 body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr));
1962 body_type = get_mka_param_body_type(hdr);
1963
1964 if (left_len < body_len + MKA_HDR_LEN)
1965 break;
1966
1967 if (body_type != MKA_ICV_INDICATOR) {
1968 left_len -= MKA_HDR_LEN + body_len;
1969 pos += MKA_HDR_LEN + body_len;
1970 continue;
1971 }
1972
1973 body = (const struct ieee802_1x_mka_icv_body *) pos;
1974 if (body_len
1975 < mka_alg_tbl[participant->kay->mka_algindex].icv_len)
1976 return NULL;
1977
1978 return body->icv;
1979 }
1980
1981 return mka_msg + msg_len - DEFAULT_ICV_LEN;
1982 }
1983
1984
1985 /**
1986 * ieee802_1x_mka_decode_dist_cak_body-
1987 */
1988 static int
1989 ieee802_1x_mka_decode_dist_cak_body(
1990 struct ieee802_1x_mka_participant *participant,
1991 const u8 *mka_msg, size_t msg_len)
1992 {
1993 struct ieee802_1x_mka_hdr *hdr;
1994 size_t body_len;
1995
1996 hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
1997 body_len = get_mka_param_body_len(hdr);
1998 if (body_len < 28) {
1999 wpa_printf(MSG_ERROR,
2000 "KaY: MKA Use CAK Packet Body Length (%zu bytes) should be 28 or more octets",
2001 body_len);
2002 return -1;
2003 }
2004
2005 return 0;
2006 }
2007
2008
2009 /**
2010 * ieee802_1x_mka_decode_kmd_body -
2011 */
2012 static int
2013 ieee802_1x_mka_decode_kmd_body(
2014 struct ieee802_1x_mka_participant *participant,
2015 const u8 *mka_msg, size_t msg_len)
2016 {
2017 struct ieee802_1x_mka_hdr *hdr;
2018 size_t body_len;
2019
2020 hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
2021 body_len = get_mka_param_body_len(hdr);
2022 if (body_len < 5) {
2023 wpa_printf(MSG_ERROR,
2024 "KaY: MKA Use KMD Packet Body Length (%zu bytes) should be 5 or more octets",
2025 body_len);
2026 return -1;
2027 }
2028
2029 return 0;
2030 }
2031
2032
2033 /**
2034 * ieee802_1x_mka_decode_announce_body -
2035 */
2036 static int ieee802_1x_mka_decode_announce_body(
2037 struct ieee802_1x_mka_participant *participant,
2038 const u8 *mka_msg, size_t msg_len)
2039 {
2040 return 0;
2041 }
2042
2043
2044 struct mka_param_body_handler {
2045 int (*body_tx)(struct ieee802_1x_mka_participant *participant,
2046 struct wpabuf *buf);
2047 int (*body_rx)(struct ieee802_1x_mka_participant *participant,
2048 const u8 *mka_msg, size_t msg_len);
2049 int (*body_length)(struct ieee802_1x_mka_participant *participant);
2050 bool (*body_present)(struct ieee802_1x_mka_participant *participant);
2051 };
2052
2053
2054 static struct mka_param_body_handler mka_body_handler[] = {
2055 /* Basic parameter set */
2056 {
2057 .body_tx = ieee802_1x_mka_encode_basic_body,
2058 .body_rx = NULL,
2059 .body_length = ieee802_1x_mka_basic_body_length,
2060 .body_present = ieee802_1x_mka_basic_body_present
2061 },
2062
2063 /* Live Peer List parameter set */
2064 {
2065 .body_tx = ieee802_1x_mka_encode_live_peer_body,
2066 .body_rx = ieee802_1x_mka_decode_live_peer_body,
2067 .body_length = ieee802_1x_mka_get_live_peer_length,
2068 .body_present = ieee802_1x_mka_live_peer_body_present
2069 },
2070
2071 /* Potential Peer List parameter set */
2072 {
2073 .body_tx = ieee802_1x_mka_encode_potential_peer_body,
2074 .body_rx = ieee802_1x_mka_decode_potential_peer_body,
2075 .body_length = ieee802_1x_mka_get_potential_peer_length,
2076 .body_present = ieee802_1x_mka_potential_peer_body_present
2077 },
2078
2079 /* MACsec SAK Use parameter set */
2080 {
2081 .body_tx = ieee802_1x_mka_encode_sak_use_body,
2082 .body_rx = ieee802_1x_mka_decode_sak_use_body,
2083 .body_length = ieee802_1x_mka_get_sak_use_length,
2084 .body_present = ieee802_1x_mka_sak_use_body_present
2085 },
2086
2087 /* Distributed SAK parameter set */
2088 {
2089 .body_tx = ieee802_1x_mka_encode_dist_sak_body,
2090 .body_rx = ieee802_1x_mka_decode_dist_sak_body,
2091 .body_length = ieee802_1x_mka_get_dist_sak_length,
2092 .body_present = ieee802_1x_mka_dist_sak_body_present
2093 },
2094
2095 /* Distribute CAK parameter set */
2096 {
2097 .body_tx = NULL,
2098 .body_rx = ieee802_1x_mka_decode_dist_cak_body,
2099 .body_length = NULL,
2100 .body_present = NULL
2101 },
2102
2103 /* KMD parameter set */
2104 {
2105 .body_tx = NULL,
2106 .body_rx = ieee802_1x_mka_decode_kmd_body,
2107 .body_length = NULL,
2108 .body_present = NULL
2109 },
2110
2111 /* Announcement parameter set */
2112 {
2113 .body_tx = NULL,
2114 .body_rx = ieee802_1x_mka_decode_announce_body,
2115 .body_length = NULL,
2116 .body_present = NULL
2117 },
2118
2119 /* ICV Indicator parameter set */
2120 {
2121 .body_tx = ieee802_1x_mka_encode_icv_body,
2122 .body_rx = NULL,
2123 .body_length = ieee802_1x_mka_get_icv_length,
2124 .body_present = ieee802_1x_mka_icv_body_present
2125 },
2126 };
2127
2128
2129 /**
2130 * ieee802_1x_kay_use_data_key - Take reference on a key
2131 */
2132 static void ieee802_1x_kay_use_data_key(struct data_key *pkey)
2133 {
2134 pkey->user++;
2135 }
2136
2137
2138 /**
2139 * ieee802_1x_kay_deinit_data_key - Release reference on a key and
2140 * free if there are no remaining users
2141 */
2142 static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey)
2143 {
2144 if (!pkey)
2145 return;
2146
2147 pkey->user--;
2148 if (pkey->user > 1)
2149 return;
2150
2151 os_free(pkey->key);
2152 os_free(pkey);
2153 }
2154
2155
2156 /**
2157 * ieee802_1x_kay_generate_new_sak -
2158 */
2159 static int
2160 ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
2161 {
2162 struct data_key *sa_key = NULL;
2163 struct ieee802_1x_kay_peer *peer;
2164 struct ieee802_1x_kay *kay = participant->kay;
2165 int ctx_len, ctx_offset;
2166 u8 *context;
2167 unsigned int key_len;
2168 u8 *key;
2169 struct macsec_ciphersuite *cs;
2170 struct os_reltime now;
2171
2172 /* check condition for generating a fresh SAK:
2173 * must have one live peer
2174 * and MKA life time elapse since last distribution
2175 * or potential peer is empty
2176 */
2177 if (dl_list_empty(&participant->live_peers)) {
2178 wpa_printf(MSG_ERROR,
2179 "KaY: Live peers list must not be empty when generating fresh SAK");
2180 return -1;
2181 }
2182
2183 /* FIXME: A fresh SAK not generated until
2184 * the live peer list contains at least one peer and
2185 * MKA life time has elapsed since the prior SAK was first distributed,
2186 * or the Key server's potential peer is empty
2187 * but I can't understand the second item, so
2188 * here only check first item and ingore
2189 * && (!dl_list_empty(&participant->potential_peers))) {
2190 */
2191 os_get_reltime(&now);
2192 if ((now.sec - kay->dist_time) < MKA_LIFE_TIME / 1000) {
2193 wpa_printf(MSG_ERROR,
2194 "KaY: Life time has not elapsed since prior SAK distributed");
2195 return -1;
2196 }
2197
2198 cs = &cipher_suite_tbl[kay->macsec_csindex];
2199 key_len = cs->sak_len;
2200 key = os_zalloc(key_len);
2201 if (!key) {
2202 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
2203 return -1;
2204 }
2205
2206 ctx_len = key_len + sizeof(kay->dist_kn);
2207 dl_list_for_each(peer, &participant->live_peers,
2208 struct ieee802_1x_kay_peer, list)
2209 ctx_len += sizeof(peer->mi);
2210 ctx_len += sizeof(participant->mi);
2211
2212 context = os_zalloc(ctx_len);
2213 if (!context)
2214 goto fail;
2215
2216 ctx_offset = 0;
2217 if (os_get_random(context + ctx_offset, key_len) < 0)
2218 goto fail;
2219
2220 ctx_offset += key_len;
2221 dl_list_for_each(peer, &participant->live_peers,
2222 struct ieee802_1x_kay_peer, list) {
2223 os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi));
2224 ctx_offset += sizeof(peer->mi);
2225 }
2226 os_memcpy(context + ctx_offset, participant->mi,
2227 sizeof(participant->mi));
2228 ctx_offset += sizeof(participant->mi);
2229 os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn));
2230
2231 if (key_len == 16 || key_len == 32) {
2232 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
2233 if (aidl_psk_sak_aes_cmac(participant->cak.key,
2234 participant->cak.len,
2235 context, ctx_len,
2236 key, key_len)) {
2237 #else
2238 if (ieee802_1x_sak_aes_cmac(participant->cak.key,
2239 participant->cak.len,
2240 context, ctx_len,
2241 key, key_len)) {
2242 #endif
2243 wpa_printf(MSG_ERROR, "KaY: Failed to generate SAK");
2244 goto fail;
2245 }
2246 } else {
2247 wpa_printf(MSG_ERROR, "KaY: SAK Length(%u) not supported",
2248 key_len);
2249 goto fail;
2250 }
2251 wpa_hexdump_key(MSG_DEBUG, "KaY: generated new SAK", key, key_len);
2252 os_free(context);
2253 context = NULL;
2254
2255 sa_key = os_zalloc(sizeof(*sa_key));
2256 if (!sa_key) {
2257 wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
2258 goto fail;
2259 }
2260
2261 sa_key->key = key;
2262 sa_key->key_len = key_len;
2263 os_memcpy(sa_key->key_identifier.mi, participant->mi, MI_LEN);
2264 sa_key->key_identifier.kn = kay->dist_kn;
2265
2266 sa_key->confidentiality_offset = kay->macsec_confidentiality;
2267 sa_key->an = kay->dist_an;
2268 ieee802_1x_kay_init_data_key(sa_key);
2269
2270 participant->new_key = sa_key;
2271
2272 ieee802_1x_kay_use_data_key(sa_key);
2273 dl_list_add(&participant->sak_list, &sa_key->list);
2274
2275 ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id);
2276 ieee802_1x_cp_sm_step(kay->cp);
2277 ieee802_1x_cp_set_offset(kay->cp, kay->macsec_confidentiality);
2278 ieee802_1x_cp_sm_step(kay->cp);
2279 ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier);
2280 ieee802_1x_cp_set_distributedan(kay->cp, sa_key->an);
2281 ieee802_1x_cp_signal_newsak(kay->cp);
2282 ieee802_1x_cp_sm_step(kay->cp);
2283
2284 dl_list_for_each(peer, &participant->live_peers,
2285 struct ieee802_1x_kay_peer, list)
2286 peer->sak_used = false;
2287
2288 kay->dist_kn++;
2289 kay->dist_an++;
2290 if (kay->dist_an > 3)
2291 kay->dist_an = 0;
2292
2293 kay->dist_time = now.sec;
2294
2295 return 0;
2296
2297 fail:
2298 os_free(key);
2299 os_free(context);
2300 return -1;
2301 }
2302
2303
2304 static int compare_priorities(const struct ieee802_1x_kay_peer *peer,
2305 const struct ieee802_1x_kay_peer *other)
2306 {
2307 if (peer->key_server_priority < other->key_server_priority)
2308 return -1;
2309 if (other->key_server_priority < peer->key_server_priority)
2310 return 1;
2311
2312 return os_memcmp(peer->sci.addr, other->sci.addr, ETH_ALEN);
2313 }
2314
2315
2316 /**
2317 * ieee802_1x_kay_elect_key_server - elect the key server
2318 * when to elect: whenever the live peers list changes
2319 */
2320 static int
2321 ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
2322 {
2323 struct ieee802_1x_kay_peer *peer;
2324 struct ieee802_1x_kay_peer *key_server = NULL;
2325 struct ieee802_1x_kay *kay = participant->kay;
2326 bool i_is_key_server;
2327 int priority_comparison;
2328
2329 if (participant->is_obliged_key_server) {
2330 participant->new_sak = true;
2331 participant->to_dist_sak = false;
2332 ieee802_1x_cp_set_electedself(kay->cp, true);
2333 return 0;
2334 }
2335
2336 /* elect the key server among the peers */
2337 dl_list_for_each(peer, &participant->live_peers,
2338 struct ieee802_1x_kay_peer, list) {
2339 if (!peer->is_key_server)
2340 continue;
2341
2342 if (!key_server) {
2343 key_server = peer;
2344 continue;
2345 }
2346
2347 if (compare_priorities(peer, key_server) < 0)
2348 key_server = peer;
2349 }
2350
2351 /* elect the key server between me and the above elected peer */
2352 i_is_key_server = false;
2353 if (key_server && participant->can_be_key_server) {
2354 struct ieee802_1x_kay_peer tmp;
2355
2356 tmp.key_server_priority = kay->actor_priority;
2357 os_memcpy(&tmp.sci, &kay->actor_sci, sizeof(tmp.sci));
2358 priority_comparison = compare_priorities(&tmp, key_server);
2359 if (priority_comparison < 0) {
2360 i_is_key_server = true;
2361 } else if (priority_comparison == 0) {
2362 wpa_printf(MSG_WARNING,
2363 "KaY: Cannot elect key server between me and peer, duplicate MAC detected");
2364 key_server = NULL;
2365 }
2366 } else if (participant->can_be_key_server) {
2367 i_is_key_server = true;
2368 }
2369
2370 if (i_is_key_server) {
2371 ieee802_1x_cp_set_electedself(kay->cp, true);
2372 if (!sci_equal(&kay->key_server_sci, &kay->actor_sci)) {
2373 ieee802_1x_cp_signal_chgdserver(kay->cp);
2374 ieee802_1x_cp_sm_step(kay->cp);
2375 }
2376
2377 participant->is_key_server = true;
2378 participant->principal = true;
2379 participant->new_sak = true;
2380 wpa_printf(MSG_DEBUG, "KaY: I am elected as key server");
2381 participant->to_dist_sak = false;
2382 participant->is_elected = true;
2383
2384 os_memcpy(&kay->key_server_sci, &kay->actor_sci,
2385 sizeof(kay->key_server_sci));
2386 kay->key_server_priority = kay->actor_priority;
2387 } else if (key_server) {
2388 wpa_printf(MSG_DEBUG,
2389 "KaY: Peer %s was elected as the key server",
2390 mi_txt(key_server->mi));
2391 ieee802_1x_cp_set_electedself(kay->cp, false);
2392 if (!sci_equal(&kay->key_server_sci, &key_server->sci)) {
2393 ieee802_1x_cp_signal_chgdserver(kay->cp);
2394 ieee802_1x_cp_sm_step(kay->cp);
2395 }
2396
2397 participant->is_key_server = false;
2398 participant->principal = true;
2399 participant->is_elected = true;
2400
2401 os_memcpy(&kay->key_server_sci, &key_server->sci,
2402 sizeof(kay->key_server_sci));
2403 kay->key_server_priority = key_server->key_server_priority;
2404 } else {
2405 participant->principal = false;
2406 participant->is_key_server = false;
2407 participant->is_elected = false;
2408 }
2409
2410 return 0;
2411 }
2412
2413
2414 /**
2415 * ieee802_1x_kay_decide_macsec_use - the key server determinate
2416 * how to use MACsec: whether use MACsec and its capability
2417 * protectFrames will be advised if the key server and one of its live peers are
2418 * MACsec capable and one of those request MACsec protection
2419 */
2420 static int
2421 ieee802_1x_kay_decide_macsec_use(
2422 struct ieee802_1x_mka_participant *participant)
2423 {
2424 struct ieee802_1x_kay *kay = participant->kay;
2425 struct ieee802_1x_kay_peer *peer;
2426 enum macsec_cap less_capability;
2427 bool has_peer;
2428
2429 if (!participant->is_key_server)
2430 return -1;
2431
2432 /* key server self is MACsec-desired and requesting MACsec */
2433 if (!kay->macsec_desired) {
2434 participant->advised_desired = false;
2435 return -1;
2436 }
2437 if (kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
2438 participant->advised_desired = false;
2439 return -1;
2440 }
2441 less_capability = kay->macsec_capable;
2442
2443 /* at least one of peers is MACsec-desired and requesting MACsec */
2444 has_peer = false;
2445 dl_list_for_each(peer, &participant->live_peers,
2446 struct ieee802_1x_kay_peer, list) {
2447 if (!peer->macsec_desired)
2448 continue;
2449
2450 if (peer->macsec_capability == MACSEC_CAP_NOT_IMPLEMENTED)
2451 continue;
2452
2453 less_capability = (less_capability < peer->macsec_capability) ?
2454 less_capability : peer->macsec_capability;
2455 has_peer = true;
2456 }
2457
2458 if (has_peer) {
2459 participant->advised_desired = true;
2460 participant->advised_capability = less_capability;
2461 kay->authenticated = false;
2462 kay->secured = true;
2463 kay->failed = false;
2464 ieee802_1x_cp_connect_secure(kay->cp);
2465 ieee802_1x_cp_sm_step(kay->cp);
2466 } else {
2467 participant->advised_desired = false;
2468 participant->advised_capability = MACSEC_CAP_NOT_IMPLEMENTED;
2469 participant->to_use_sak = false;
2470 kay->authenticated = true;
2471 kay->secured = false;
2472 kay->failed = false;
2473 kay->ltx_kn = 0;
2474 kay->ltx_an = 0;
2475 kay->lrx_kn = 0;
2476 kay->lrx_an = 0;
2477 kay->otx_kn = 0;
2478 kay->otx_an = 0;
2479 kay->orx_kn = 0;
2480 kay->orx_an = 0;
2481 ieee802_1x_cp_connect_authenticated(kay->cp);
2482 ieee802_1x_cp_sm_step(kay->cp);
2483 }
2484
2485 return 0;
2486 }
2487
2488 static const u8 pae_group_addr[ETH_ALEN] = {
2489 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03
2490 };
2491
2492
2493 /**
2494 * ieee802_1x_kay_encode_mkpdu -
2495 */
2496 static int
2497 ieee802_1x_kay_encode_mkpdu(struct ieee802_1x_mka_participant *participant,
2498 struct wpabuf *pbuf)
2499 {
2500 unsigned int i;
2501 struct ieee8023_hdr *ether_hdr;
2502 struct ieee802_1x_hdr *eapol_hdr;
2503
2504 ether_hdr = wpabuf_put(pbuf, sizeof(*ether_hdr));
2505 os_memcpy(ether_hdr->dest, pae_group_addr, sizeof(ether_hdr->dest));
2506 os_memcpy(ether_hdr->src, participant->kay->actor_sci.addr,
2507 sizeof(ether_hdr->dest));
2508 ether_hdr->ethertype = host_to_be16(ETH_P_EAPOL);
2509 wpa_printf(MSG_DEBUG, "KaY: Ethernet header: DA=" MACSTR " SA=" MACSTR
2510 " Ethertype=0x%x",
2511 MAC2STR(ether_hdr->dest), MAC2STR(ether_hdr->src),
2512 be_to_host16(ether_hdr->ethertype));
2513
2514 eapol_hdr = wpabuf_put(pbuf, sizeof(*eapol_hdr));
2515 eapol_hdr->version = EAPOL_VERSION;
2516 eapol_hdr->type = IEEE802_1X_TYPE_EAPOL_MKA;
2517 eapol_hdr->length = host_to_be16(wpabuf_tailroom(pbuf));
2518 wpa_printf(MSG_DEBUG,
2519 "KaY: Common EAPOL PDU structure: Protocol Version=%u Packet Type=%u Packet Body Length=%u",
2520 eapol_hdr->version, eapol_hdr->type,
2521 be_to_host16(eapol_hdr->length));
2522
2523 for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
2524 if (mka_body_handler[i].body_present &&
2525 mka_body_handler[i].body_present(participant)) {
2526 if (mka_body_handler[i].body_tx(participant, pbuf))
2527 return -1;
2528 }
2529 }
2530
2531 return 0;
2532 }
2533
2534
2535 /**
2536 * ieee802_1x_participant_send_mkpdu -
2537 */
2538 static int
2539 ieee802_1x_participant_send_mkpdu(
2540 struct ieee802_1x_mka_participant *participant)
2541 {
2542 struct wpabuf *buf;
2543 struct ieee802_1x_kay *kay = participant->kay;
2544 size_t length = 0;
2545 unsigned int i;
2546
2547 wpa_printf(MSG_DEBUG, "KaY: Encode and send an MKPDU (ifname=%s)",
2548 kay->if_name);
2549 length += sizeof(struct ieee802_1x_hdr) + sizeof(struct ieee8023_hdr);
2550 for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
2551 if (mka_body_handler[i].body_present &&
2552 mka_body_handler[i].body_present(participant))
2553 length += mka_body_handler[i].body_length(participant);
2554 }
2555
2556 buf = wpabuf_alloc(length);
2557 if (!buf) {
2558 wpa_printf(MSG_ERROR, "KaY: out of memory");
2559 return -1;
2560 }
2561
2562 if (ieee802_1x_kay_encode_mkpdu(participant, buf)) {
2563 wpa_printf(MSG_ERROR, "KaY: encode MKPDU fail");
2564 return -1;
2565 }
2566
2567 wpa_hexdump_buf(MSG_MSGDUMP, "KaY: Outgoing MKPDU", buf);
2568 l2_packet_send(kay->l2_mka, NULL, 0, wpabuf_head(buf), wpabuf_len(buf));
2569 wpabuf_free(buf);
2570
2571 kay->active = true;
2572 participant->active = true;
2573
2574 return 0;
2575 }
2576
2577
2578 static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa);
2579
2580 static void ieee802_1x_delete_transmit_sa(struct ieee802_1x_kay *kay,
2581 struct transmit_sa *sa)
2582 {
2583 secy_disable_transmit_sa(kay, sa);
2584 secy_delete_transmit_sa(kay, sa);
2585 ieee802_1x_kay_deinit_transmit_sa(sa);
2586 }
2587
2588
2589 /**
2590 * ieee802_1x_participant_timer -
2591 */
2592 static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
2593 {
2594 struct ieee802_1x_mka_participant *participant;
2595 struct ieee802_1x_kay *kay;
2596 struct ieee802_1x_kay_peer *peer, *pre_peer;
2597 struct os_reltime now;
2598 bool lp_changed;
2599 bool key_server_removed;
2600 struct receive_sc *rxsc, *pre_rxsc;
2601 struct transmit_sa *txsa, *pre_txsa;
2602
2603 os_get_reltime(&now);
2604
2605 participant = (struct ieee802_1x_mka_participant *)eloop_ctx;
2606 kay = participant->kay;
2607 wpa_printf(MSG_DEBUG, "KaY: Participant timer (ifname=%s)",
2608 kay->if_name);
2609 if (participant->cak_life) {
2610 if (now.sec > participant->cak_life)
2611 goto delete_mka;
2612 }
2613
2614 /* should delete MKA instance if there are not live peers
2615 * when the MKA life elapsed since its creating */
2616 if (participant->mka_life) {
2617 if (dl_list_empty(&participant->live_peers)) {
2618 if (now.sec > participant->mka_life)
2619 goto delete_mka;
2620 } else {
2621 participant->mka_life = 0;
2622 }
2623 }
2624
2625 lp_changed = false;
2626 key_server_removed = false;
2627 dl_list_for_each_safe(peer, pre_peer, &participant->live_peers,
2628 struct ieee802_1x_kay_peer, list) {
2629 if (now.sec > peer->expire) {
2630 wpa_printf(MSG_DEBUG, "KaY: Live peer removed");
2631 ieee802_1x_kay_dump_peer(peer);
2632 dl_list_for_each_safe(rxsc, pre_rxsc,
2633 &participant->rxsc_list,
2634 struct receive_sc, list) {
2635 if (sci_equal(&rxsc->sci, &peer->sci)) {
2636 ieee802_1x_kay_deinit_receive_sc(
2637 participant, rxsc);
2638 }
2639 }
2640 key_server_removed |= peer->is_key_server;
2641 dl_list_del(&peer->list);
2642 os_free(peer);
2643 lp_changed = true;
2644 }
2645 }
2646
2647 /* The key server may be removed due to the ingress packets delay.
2648 * In this situation, the endpoint of the key server may not be aware
2649 * of this participant who has removed the key server from the peer
2650 * list. Because the egress traffic is normal, the key server will not
2651 * remove this participant from the peer list of the key server. So in
2652 * the next MKA message, the key server will not dispatch a new SAK to
2653 * this participant. And this participant cannot be aware that that is
2654 * a new round of communication so it will not update its MI at
2655 * re-adding the key server to its peer list. So we need to update MI
2656 * to avoid the failure of the re-establishment MKA session. */
2657 if (key_server_removed) {
2658 if (!reset_participant_mi(participant))
2659 wpa_printf(MSG_WARNING,
2660 "KaY: Could not update MI on key server removal");
2661 else
2662 wpa_printf(MSG_DEBUG,
2663 "KaY: Update MI on key server removal");
2664 }
2665
2666 if (lp_changed) {
2667 if (dl_list_empty(&participant->live_peers)) {
2668 participant->advised_desired = false;
2669 participant->advised_capability =
2670 MACSEC_CAP_NOT_IMPLEMENTED;
2671 participant->to_use_sak = false;
2672 participant->ltx = false;
2673 participant->lrx = false;
2674 participant->otx = false;
2675 participant->orx = false;
2676 participant->is_key_server = false;
2677 participant->is_elected = false;
2678 kay->authenticated = false;
2679 kay->secured = false;
2680 kay->failed = false;
2681 kay->ltx_kn = 0;
2682 kay->ltx_an = 0;
2683 kay->lrx_kn = 0;
2684 kay->lrx_an = 0;
2685 kay->otx_kn = 0;
2686 kay->otx_an = 0;
2687 kay->orx_kn = 0;
2688 kay->orx_an = 0;
2689 dl_list_for_each_safe(txsa, pre_txsa,
2690 &participant->txsc->sa_list,
2691 struct transmit_sa, list) {
2692 ieee802_1x_delete_transmit_sa(kay, txsa);
2693 }
2694
2695 ieee802_1x_cp_connect_pending(kay->cp);
2696 ieee802_1x_cp_sm_step(kay->cp);
2697 } else {
2698 ieee802_1x_kay_elect_key_server(participant);
2699 ieee802_1x_kay_decide_macsec_use(participant);
2700 }
2701 }
2702
2703 dl_list_for_each_safe(peer, pre_peer, &participant->potential_peers,
2704 struct ieee802_1x_kay_peer, list) {
2705 if (now.sec > peer->expire) {
2706 wpa_printf(MSG_DEBUG, "KaY: Potential peer removed");
2707 ieee802_1x_kay_dump_peer(peer);
2708 dl_list_del(&peer->list);
2709 os_free(peer);
2710 }
2711 }
2712
2713 if (participant->new_sak && participant->is_key_server) {
2714 if (!ieee802_1x_kay_generate_new_sak(participant))
2715 participant->to_dist_sak = true;
2716
2717 participant->new_sak = false;
2718 }
2719
2720 if (participant->retry_count < MAX_RETRY_CNT ||
2721 participant->mode == PSK) {
2722 ieee802_1x_participant_send_mkpdu(participant);
2723 participant->retry_count++;
2724 }
2725
2726 eloop_register_timeout(kay->mka_hello_time / 1000, 0,
2727 ieee802_1x_participant_timer,
2728 participant, NULL);
2729
2730 return;
2731
2732 delete_mka:
2733 kay->authenticated = false;
2734 kay->secured = false;
2735 kay->failed = true;
2736 ieee802_1x_kay_delete_mka(kay, &participant->ckn);
2737 }
2738
2739
2740 /**
2741 * ieee802_1x_kay_init_transmit_sa -
2742 */
2743 static struct transmit_sa *
2744 ieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN,
2745 struct data_key *key)
2746 {
2747 struct transmit_sa *psa;
2748
2749 key->tx_latest = true;
2750 key->rx_latest = true;
2751
2752 psa = os_zalloc(sizeof(*psa));
2753 if (!psa) {
2754 wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
2755 return NULL;
2756 }
2757
2758 if (key->confidentiality_offset >= CONFIDENTIALITY_OFFSET_0 &&
2759 key->confidentiality_offset <= CONFIDENTIALITY_OFFSET_50)
2760 psa->confidentiality = true;
2761 else
2762 psa->confidentiality = false;
2763
2764 psa->an = an;
2765 ieee802_1x_kay_use_data_key(key);
2766 psa->pkey = key;
2767 psa->next_pn = next_PN;
2768 psa->sc = psc;
2769
2770 os_get_time(&psa->created_time);
2771 psa->in_use = false;
2772
2773 dl_list_add(&psc->sa_list, &psa->list);
2774 wpa_printf(MSG_DEBUG,
2775 "KaY: Create transmit SA(an: %hhu, next_pn: %u) of SC",
2776 an, next_PN);
2777
2778 return psa;
2779 }
2780
2781
2782 /**
2783 * ieee802_1x_kay_deinit_transmit_sa -
2784 */
2785 static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa)
2786 {
2787 ieee802_1x_kay_deinit_data_key(psa->pkey);
2788 psa->pkey = NULL;
2789 wpa_printf(MSG_DEBUG,
2790 "KaY: Delete transmit SA(an: %hhu) of SC",
2791 psa->an);
2792 dl_list_del(&psa->list);
2793 os_free(psa);
2794 }
2795
2796
2797 /**
2798 * init_transmit_sc -
2799 */
2800 static struct transmit_sc *
2801 ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci)
2802 {
2803 struct transmit_sc *psc;
2804
2805 psc = os_zalloc(sizeof(*psc));
2806 if (!psc) {
2807 wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
2808 return NULL;
2809 }
2810 os_memcpy(&psc->sci, sci, sizeof(psc->sci));
2811
2812 os_get_time(&psc->created_time);
2813 psc->transmitting = false;
2814 psc->encoding_sa = false;
2815 psc->enciphering_sa = false;
2816
2817 dl_list_init(&psc->sa_list);
2818 wpa_printf(MSG_DEBUG, "KaY: Create transmit SC - SCI: %s",
2819 sci_txt(&psc->sci));
2820
2821 return psc;
2822 }
2823
2824
2825 /**
2826 * ieee802_1x_kay_deinit_transmit_sc -
2827 */
2828 static void
2829 ieee802_1x_kay_deinit_transmit_sc(
2830 struct ieee802_1x_mka_participant *participant, struct transmit_sc *psc)
2831 {
2832 struct transmit_sa *psa, *tmp;
2833
2834 wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC");
2835 dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, list)
2836 ieee802_1x_delete_transmit_sa(participant->kay, psa);
2837
2838 secy_delete_transmit_sc(participant->kay, psc);
2839 os_free(psc);
2840 }
2841
2842
2843 /****************** Interface between CP and KAY *********************/
2844 /**
2845 * ieee802_1x_kay_set_latest_sa_attr -
2846 */
2847 int ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay,
2848 struct ieee802_1x_mka_ki *lki, u8 lan,
2849 bool ltx, bool lrx)
2850 {
2851 struct ieee802_1x_mka_participant *principal;
2852
2853 principal = ieee802_1x_kay_get_principal_participant(kay);
2854 if (!principal)
2855 return -1;
2856
2857 if (!lki)
2858 os_memset(&principal->lki, 0, sizeof(principal->lki));
2859 else
2860 os_memcpy(&principal->lki, lki, sizeof(principal->lki));
2861
2862 principal->lan = lan;
2863 principal->ltx = ltx;
2864 principal->lrx = lrx;
2865 if (!lki) {
2866 kay->ltx_kn = 0;
2867 kay->lrx_kn = 0;
2868 } else {
2869 kay->ltx_kn = lki->kn;
2870 kay->lrx_kn = lki->kn;
2871 }
2872 kay->ltx_an = lan;
2873 kay->lrx_an = lan;
2874
2875 return 0;
2876 }
2877
2878
2879 /**
2880 * ieee802_1x_kay_set_old_sa_attr -
2881 */
2882 int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay,
2883 struct ieee802_1x_mka_ki *oki,
2884 u8 oan, bool otx, bool orx)
2885 {
2886 struct ieee802_1x_mka_participant *principal;
2887
2888 principal = ieee802_1x_kay_get_principal_participant(kay);
2889 if (!principal)
2890 return -1;
2891
2892 if (!oki)
2893 os_memset(&principal->oki, 0, sizeof(principal->oki));
2894 else
2895 os_memcpy(&principal->oki, oki, sizeof(principal->oki));
2896
2897 principal->oan = oan;
2898 principal->otx = otx;
2899 principal->orx = orx;
2900
2901 if (!oki) {
2902 kay->otx_kn = 0;
2903 kay->orx_kn = 0;
2904 } else {
2905 kay->otx_kn = oki->kn;
2906 kay->orx_kn = oki->kn;
2907 }
2908 kay->otx_an = oan;
2909 kay->orx_an = oan;
2910
2911 return 0;
2912 }
2913
2914
2915 static struct transmit_sa * lookup_txsa_by_an(struct transmit_sc *txsc, u8 an)
2916 {
2917 struct transmit_sa *txsa;
2918
2919 dl_list_for_each(txsa, &txsc->sa_list, struct transmit_sa, list) {
2920 if (txsa->an == an)
2921 return txsa;
2922 }
2923
2924 return NULL;
2925 }
2926
2927
2928 static struct receive_sa * lookup_rxsa_by_an(struct receive_sc *rxsc, u8 an)
2929 {
2930 struct receive_sa *rxsa;
2931
2932 dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) {
2933 if (rxsa->an == an)
2934 return rxsa;
2935 }
2936
2937 return NULL;
2938 }
2939
2940
2941 /**
2942 * ieee802_1x_kay_create_sas -
2943 */
2944 int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay,
2945 struct ieee802_1x_mka_ki *lki)
2946 {
2947 struct data_key *sa_key, *latest_sak;
2948 struct ieee802_1x_mka_participant *principal;
2949 struct receive_sc *rxsc;
2950 struct receive_sa *rxsa;
2951 struct transmit_sa *txsa;
2952
2953 principal = ieee802_1x_kay_get_principal_participant(kay);
2954 if (!principal)
2955 return -1;
2956
2957 latest_sak = NULL;
2958 dl_list_for_each(sa_key, &principal->sak_list, struct data_key, list) {
2959 if (is_ki_equal(&sa_key->key_identifier, lki)) {
2960 sa_key->rx_latest = true;
2961 sa_key->tx_latest = true;
2962 latest_sak = sa_key;
2963 principal->to_use_sak = true;
2964 } else {
2965 sa_key->rx_latest = false;
2966 sa_key->tx_latest = false;
2967 }
2968 }
2969 if (!latest_sak) {
2970 wpa_printf(MSG_ERROR, "KaY: lki related sak not found");
2971 return -1;
2972 }
2973
2974 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
2975 while ((rxsa = lookup_rxsa_by_an(rxsc, latest_sak->an)) != NULL)
2976 ieee802_1x_delete_receive_sa(kay, rxsa);
2977
2978 rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1,
2979 latest_sak);
2980 if (!rxsa)
2981 return -1;
2982
2983 secy_create_receive_sa(kay, rxsa);
2984 }
2985
2986 while ((txsa = lookup_txsa_by_an(principal->txsc, latest_sak->an)) !=
2987 NULL)
2988 ieee802_1x_delete_transmit_sa(kay, txsa);
2989
2990 txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an,
2991 latest_sak->next_pn ?
2992 latest_sak->next_pn : 1,
2993 latest_sak);
2994 if (!txsa)
2995 return -1;
2996
2997 secy_create_transmit_sa(kay, txsa);
2998
2999
3000
3001 return 0;
3002 }
3003
3004
3005 /**
3006 * ieee802_1x_kay_delete_sas -
3007 */
3008 int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay,
3009 struct ieee802_1x_mka_ki *ki)
3010 {
3011 struct data_key *sa_key, *pre_key;
3012 struct transmit_sa *txsa, *pre_txsa;
3013 struct receive_sa *rxsa, *pre_rxsa;
3014 struct receive_sc *rxsc;
3015 struct ieee802_1x_mka_participant *principal;
3016
3017 wpa_printf(MSG_DEBUG, "KaY: Entry into %s", __func__);
3018 principal = ieee802_1x_kay_get_principal_participant(kay);
3019 if (!principal)
3020 return -1;
3021
3022 /* remove the transmit sa */
3023 dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list,
3024 struct transmit_sa, list) {
3025 if (is_ki_equal(&txsa->pkey->key_identifier, ki))
3026 ieee802_1x_delete_transmit_sa(kay, txsa);
3027 }
3028
3029 /* remove the receive sa */
3030 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
3031 dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list,
3032 struct receive_sa, list) {
3033 if (is_ki_equal(&rxsa->pkey->key_identifier, ki))
3034 ieee802_1x_delete_receive_sa(kay, rxsa);
3035 }
3036 }
3037
3038 /* remove the sak */
3039 dl_list_for_each_safe(sa_key, pre_key, &principal->sak_list,
3040 struct data_key, list) {
3041 if (is_ki_equal(&sa_key->key_identifier, ki)) {
3042 if (principal->new_key == sa_key)
3043 principal->new_key = NULL;
3044 dl_list_del(&sa_key->list);
3045 ieee802_1x_kay_deinit_data_key(sa_key);
3046 break;
3047 }
3048 }
3049
3050 return 0;
3051 }
3052
3053
3054 /**
3055 * ieee802_1x_kay_enable_tx_sas -
3056 */
3057 int ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay,
3058 struct ieee802_1x_mka_ki *lki)
3059 {
3060 struct ieee802_1x_mka_participant *principal;
3061 struct transmit_sa *txsa;
3062
3063 principal = ieee802_1x_kay_get_principal_participant(kay);
3064 if (!principal)
3065 return -1;
3066
3067 dl_list_for_each(txsa, &principal->txsc->sa_list, struct transmit_sa,
3068 list) {
3069 if (is_ki_equal(&txsa->pkey->key_identifier, lki)) {
3070 txsa->in_use = true;
3071 secy_enable_transmit_sa(kay, txsa);
3072 ieee802_1x_cp_set_usingtransmitas(
3073 principal->kay->cp, true);
3074 ieee802_1x_cp_sm_step(principal->kay->cp);
3075 }
3076 }
3077
3078 return 0;
3079 }
3080
3081
3082 /**
3083 * ieee802_1x_kay_enable_rx_sas -
3084 */
3085 int ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay,
3086 struct ieee802_1x_mka_ki *lki)
3087 {
3088 struct ieee802_1x_mka_participant *principal;
3089 struct receive_sa *rxsa;
3090 struct receive_sc *rxsc;
3091
3092 principal = ieee802_1x_kay_get_principal_participant(kay);
3093 if (!principal)
3094 return -1;
3095
3096 dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
3097 dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list)
3098 {
3099 if (is_ki_equal(&rxsa->pkey->key_identifier, lki)) {
3100 rxsa->in_use = true;
3101 secy_enable_receive_sa(kay, rxsa);
3102 ieee802_1x_cp_set_usingreceivesas(
3103 principal->kay->cp, true);
3104 ieee802_1x_cp_sm_step(principal->kay->cp);
3105 }
3106 }
3107 }
3108
3109 return 0;
3110 }
3111
3112
3113 /**
3114 * ieee802_1x_kay_enable_new_info -
3115 */
3116 int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay)
3117 {
3118 struct ieee802_1x_mka_participant *principal;
3119
3120 principal = ieee802_1x_kay_get_principal_participant(kay);
3121 if (!principal)
3122 return -1;
3123
3124 if (principal->retry_count < MAX_RETRY_CNT || principal->mode == PSK) {
3125 ieee802_1x_participant_send_mkpdu(principal);
3126 principal->retry_count++;
3127 }
3128
3129 return 0;
3130 }
3131
3132
3133 /**
3134 * ieee802_1x_kay_mkpdu_validity_check -
3135 * Validity checks specified in IEEE Std 802.1X-2010, 11.11.2 (Validation of
3136 * MKPDUs)
3137 */
3138 static int ieee802_1x_kay_mkpdu_validity_check(struct ieee802_1x_kay *kay,
3139 const u8 *buf, size_t len)
3140 {
3141 struct ieee8023_hdr *eth_hdr;
3142 struct ieee802_1x_hdr *eapol_hdr;
3143 struct ieee802_1x_mka_hdr *mka_hdr;
3144 struct ieee802_1x_mka_basic_body *body;
3145 size_t mka_msg_len;
3146 struct ieee802_1x_mka_participant *participant;
3147 size_t body_len;
3148 size_t ckn_len;
3149 u8 icv[MAX_ICV_LEN];
3150 const u8 *msg_icv;
3151
3152 /* len > eth+eapol header already verified in kay_l2_receive();
3153 * likewise, eapol_hdr->length validated there */
3154 eth_hdr = (struct ieee8023_hdr *) buf;
3155 eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1);
3156 mka_hdr = (struct ieee802_1x_mka_hdr *) (eapol_hdr + 1);
3157
3158 wpa_printf(MSG_DEBUG, "KaY: Ethernet header: DA=" MACSTR " SA=" MACSTR
3159 " Ethertype=0x%x",
3160 MAC2STR(eth_hdr->dest), MAC2STR(eth_hdr->src),
3161 be_to_host16(eth_hdr->ethertype));
3162
3163 /* the destination address shall not be an individual address */
3164 if (!ether_addr_equal(eth_hdr->dest, pae_group_addr)) {
3165 wpa_printf(MSG_DEBUG,
3166 "KaY: ethernet destination address is not PAE group address");
3167 return -1;
3168 }
3169
3170 wpa_printf(MSG_DEBUG,
3171 "KaY: Common EAPOL PDU structure: Protocol Version=%u Packet Type=%u Packet Body Length=%u",
3172 eapol_hdr->version, eapol_hdr->type,
3173 be_to_host16(eapol_hdr->length));
3174
3175 /* MKPDU shall not be less than 32 octets */
3176 mka_msg_len = be_to_host16(eapol_hdr->length);
3177 if (mka_msg_len < 32) {
3178 wpa_printf(MSG_DEBUG, "KaY: MKPDU is less than 32 octets");
3179 return -1;
3180 }
3181 /* MKPDU shall be a multiple of 4 octets */
3182 if ((mka_msg_len % 4) != 0) {
3183 wpa_printf(MSG_DEBUG,
3184 "KaY: MKPDU is not multiple of 4 octets");
3185 return -1;
3186 }
3187
3188 wpa_hexdump(MSG_MSGDUMP, "KaY: EAPOL-MKA Packet Body (MKPDU)",
3189 mka_hdr, mka_msg_len);
3190
3191 /* Room for body_len already verified in kay_l2_receive() */
3192 body = (struct ieee802_1x_mka_basic_body *) mka_hdr;
3193 body_len = get_mka_param_body_len(body);
3194 /* EAPOL-MKA body should comprise basic parameter set and ICV */
3195 if (mka_msg_len < MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN) {
3196 wpa_printf(MSG_ERROR,
3197 "KaY: Received EAPOL-MKA Packet Body Length (%zu bytes) is less than the Basic Parameter Set Header Length (%zu bytes) + the Basic Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
3198 mka_msg_len, MKA_HDR_LEN,
3199 body_len, DEFAULT_ICV_LEN);
3200 return -1;
3201 }
3202
3203 if (body_len < sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN) {
3204 wpa_printf(MSG_DEBUG, "KaY: Too small body length %zu",
3205 body_len);
3206 return -1;
3207 }
3208 ckn_len = body_len -
3209 (sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN);
3210 if (ckn_len < 1 || ckn_len > MAX_CKN_LEN) {
3211 wpa_printf(MSG_WARNING,
3212 "KaY: Received EAPOL-MKA CKN Length (%zu bytes) is out of range (<= %u bytes)",
3213 ckn_len, MAX_CKN_LEN);
3214 return -1;
3215 }
3216
3217 ieee802_1x_mka_dump_basic_body(body);
3218
3219 /* CKN should be owned by I */
3220 participant = ieee802_1x_kay_get_participant(kay, body->ckn, ckn_len);
3221 if (!participant) {
3222 wpa_printf(MSG_DEBUG, "KaY: CKN is not included in my CA");
3223 return -1;
3224 }
3225
3226 /* algorithm agility check */
3227 if (os_memcmp(body->algo_agility, mka_algo_agility,
3228 sizeof(body->algo_agility)) != 0) {
3229 wpa_printf(MSG_INFO,
3230 "KaY: Peer's algorithm agility (%s) not supported",
3231 algo_agility_txt(body->algo_agility));
3232 return -1;
3233 }
3234
3235 /* ICV check */
3236 /*
3237 * The ICV will comprise the final octets of the packet body, whatever
3238 * its size, not the fixed length 16 octets, indicated by the EAPOL
3239 * packet body length.
3240 */
3241 if (len < mka_alg_tbl[kay->mka_algindex].icv_len ||
3242 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
3243 aidl_psk_icv_hash(
3244 #else
3245 mka_alg_tbl[kay->mka_algindex].icv_hash(
3246 #endif
3247 participant->ick.key, participant->ick.len,
3248 buf, len - mka_alg_tbl[kay->mka_algindex].icv_len, icv)) {
3249 wpa_printf(MSG_ERROR, "KaY: Failed to calculate ICV");
3250 return -1;
3251 }
3252
3253 msg_icv = ieee802_1x_mka_decode_icv_body(participant,
3254 (const u8 *) mka_hdr,
3255 mka_msg_len);
3256 if (!msg_icv) {
3257 wpa_printf(MSG_WARNING, "KaY: No ICV in MKPDU - ignore it");
3258 return -1;
3259 }
3260 wpa_hexdump(MSG_DEBUG, "KaY: Received ICV",
3261 msg_icv, mka_alg_tbl[kay->mka_algindex].icv_len);
3262 if (os_memcmp_const(msg_icv, icv,
3263 mka_alg_tbl[kay->mka_algindex].icv_len) != 0) {
3264 wpa_printf(MSG_WARNING,
3265 "KaY: Computed ICV is not equal to Received ICV");
3266 wpa_hexdump(MSG_DEBUG, "KaY: Calculated ICV",
3267 icv, mka_alg_tbl[kay->mka_algindex].icv_len);
3268 return -1;
3269 }
3270
3271 return 0;
3272 }
3273
3274
3275 /**
3276 * ieee802_1x_kay_decode_mkpdu -
3277 */
3278 static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
3279 const u8 *buf, size_t len)
3280 {
3281 struct ieee802_1x_mka_participant *participant;
3282 struct ieee802_1x_mka_hdr *hdr;
3283 struct ieee802_1x_kay_peer *peer;
3284 size_t body_len;
3285 size_t left_len;
3286 u8 body_type;
3287 int i;
3288 const u8 *pos;
3289 bool handled[256];
3290 bool bad_sak_use = false; /* Error detected while processing SAK Use
3291 * parameter set */
3292 bool i_in_peerlist, is_in_live_peer, is_in_potential_peer;
3293
3294 wpa_printf(MSG_DEBUG, "KaY: Decode received MKPDU (ifname=%s)",
3295 kay->if_name);
3296 if (ieee802_1x_kay_mkpdu_validity_check(kay, buf, len))
3297 return -1;
3298
3299 /* handle basic parameter set */
3300 pos = buf + sizeof(struct ieee8023_hdr) + sizeof(struct ieee802_1x_hdr);
3301 left_len = len - sizeof(struct ieee8023_hdr) -
3302 sizeof(struct ieee802_1x_hdr);
3303 participant = ieee802_1x_mka_decode_basic_body(kay, pos, left_len);
3304 if (!participant)
3305 return -1;
3306
3307 /* to skip basic parameter set */
3308 hdr = (struct ieee802_1x_mka_hdr *) pos;
3309 body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr));
3310 if (left_len < body_len + MKA_HDR_LEN)
3311 return -1;
3312 pos += body_len + MKA_HDR_LEN;
3313 left_len -= body_len + MKA_HDR_LEN;
3314
3315 /* check i am in the peer's peer list */
3316 i_in_peerlist = ieee802_1x_mka_i_in_peerlist(participant, pos,
3317 left_len);
3318 is_in_live_peer = ieee802_1x_kay_is_in_live_peer(
3319 participant, participant->current_peer_id.mi);
3320 wpa_printf(MSG_DEBUG, "KaY: i_in_peerlist=%s is_in_live_peer=%s",
3321 yes_no(i_in_peerlist), yes_no(is_in_live_peer));
3322 if (i_in_peerlist && !is_in_live_peer) {
3323 /* accept the peer as live peer */
3324 is_in_potential_peer = ieee802_1x_kay_is_in_potential_peer(
3325 participant, participant->current_peer_id.mi);
3326 if (is_in_potential_peer) {
3327 if (!ieee802_1x_kay_move_live_peer(
3328 participant,
3329 participant->current_peer_id.mi,
3330 be_to_host32(participant->
3331 current_peer_id.mn)))
3332 return -1;
3333 } else if (!ieee802_1x_kay_create_live_peer(
3334 participant, participant->current_peer_id.mi,
3335 be_to_host32(participant->
3336 current_peer_id.mn))) {
3337 return -1;
3338 }
3339
3340 ieee802_1x_kay_elect_key_server(participant);
3341 ieee802_1x_kay_decide_macsec_use(participant);
3342 }
3343
3344 /*
3345 * Handle other parameter set than basic parameter set.
3346 * Each parameter set should be present only once.
3347 */
3348 for (i = 0; i < 256; i++)
3349 handled[i] = false;
3350
3351 handled[0] = true;
3352 for (; left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN;
3353 pos += body_len + MKA_HDR_LEN,
3354 left_len -= body_len + MKA_HDR_LEN) {
3355 hdr = (struct ieee802_1x_mka_hdr *) pos;
3356 body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr));
3357 body_type = get_mka_param_body_type(hdr);
3358
3359 if (body_type == MKA_ICV_INDICATOR)
3360 return 0;
3361
3362 if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) {
3363 wpa_printf(MSG_ERROR,
3364 "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
3365 left_len, MKA_HDR_LEN,
3366 body_len, DEFAULT_ICV_LEN);
3367 return -1;
3368 }
3369
3370 if (handled[body_type]) {
3371 wpa_printf(MSG_DEBUG,
3372 "KaY: Ignore duplicated body type %u",
3373 body_type);
3374 continue;
3375 }
3376
3377 handled[body_type] = true;
3378 if (body_type < ARRAY_SIZE(mka_body_handler) &&
3379 mka_body_handler[body_type].body_rx) {
3380 if (mka_body_handler[body_type].body_rx
3381 (participant, pos, left_len) != 0) {
3382 /* Handle parameter set failure */
3383 if (body_type != MKA_SAK_USE) {
3384 wpa_printf(MSG_INFO,
3385 "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed",
3386 body_type);
3387 return -1;
3388 }
3389
3390 /* Ideally DIST-SAK should be processed before
3391 * SAK-USE. Unfortunately IEEE Std 802.1X-2010,
3392 * 11.11.3 (Encoding MKPDUs) states SAK-USE(3)
3393 * must always be encoded before DIST-SAK(4).
3394 * Rather than redesigning mka_body_handler so
3395 * that it somehow processes DIST-SAK before
3396 * SAK-USE, just ignore SAK-USE failures if
3397 * DIST-SAK is also present in this MKPDU. */
3398 bad_sak_use = true;
3399 }
3400 } else {
3401 wpa_printf(MSG_ERROR,
3402 "KaY: The body type %d is not supported in this MKA version %d",
3403 body_type, MKA_VERSION_ID);
3404 }
3405 }
3406
3407 if (bad_sak_use && !handled[MKA_DISTRIBUTED_SAK]) {
3408 wpa_printf(MSG_INFO,
3409 "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed",
3410 MKA_SAK_USE);
3411 if (!reset_participant_mi(participant))
3412 wpa_printf(MSG_DEBUG, "KaY: Could not update MI");
3413 else
3414 wpa_printf(MSG_DEBUG,
3415 "KaY: Selected a new random MI: %s",
3416 mi_txt(participant->mi));
3417 return -1;
3418 }
3419
3420 /* Detect missing parameter sets */
3421 peer = ieee802_1x_kay_get_live_peer(participant,
3422 participant->current_peer_id.mi);
3423 if (peer) {
3424 /* MKPDU is from live peer */
3425 if (!handled[MKA_SAK_USE]) {
3426 /* Once a live peer starts sending SAK-USE, it should be
3427 * sent every time. */
3428 if (peer->sak_used) {
3429 wpa_printf(MSG_INFO,
3430 "KaY: Discarding Rx MKPDU: Live Peer stopped sending SAK-USE");
3431 return -1;
3432 }
3433
3434 /* Live peer is probably hung if it hasn't sent SAK-USE
3435 * after a reasonable number of MKPDUs. Drop the MKPDU,
3436 * which will eventually force an timeout. */
3437 if (++peer->missing_sak_use_count >
3438 MAX_MISSING_SAK_USE) {
3439 wpa_printf(MSG_INFO,
3440 "KaY: Discarding Rx MKPDU: Live Peer not sending SAK-USE");
3441 return -1;
3442 }
3443 } else {
3444 struct os_reltime now;
3445
3446 os_get_reltime(&now);
3447 peer->missing_sak_use_count = 0;
3448
3449 /* Only update live peer watchdog after successful
3450 * decode of all parameter sets */
3451 peer->expire = now.sec + MKA_LIFE_TIME / 1000;
3452 }
3453 } else {
3454 /* MKPDU is from new or potential peer */
3455 peer = ieee802_1x_kay_get_peer(participant,
3456 participant->current_peer_id.mi);
3457 if (!peer) {
3458 wpa_printf(MSG_DEBUG, "KaY: No peer entry found");
3459 return -1;
3460 }
3461
3462 /* Do not update potential peer watchdog. Per IEEE Std
3463 * 802.1X-2010, 9.4.3, potential peers need to show liveness by
3464 * including our MI/MN in their transmitted MKPDU (within
3465 * potential or live parameter sets). Whena potential peer does
3466 * include our MI/MN in an MKPDU, we respond by moving the peer
3467 * from 'potential_peers' to 'live_peers'. */
3468 }
3469
3470 kay->active = true;
3471 participant->retry_count = 0;
3472 participant->active = true;
3473
3474 return 0;
3475 }
3476
3477
3478
3479 static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf,
3480 size_t len)
3481 {
3482 struct ieee802_1x_kay *kay = ctx;
3483 struct ieee8023_hdr *eth_hdr;
3484 struct ieee802_1x_hdr *eapol_hdr;
3485 size_t calc_len;
3486
3487 /* IEEE Std 802.1X-2010, 11.4 (Validation of received EAPOL PDUs) */
3488
3489 /* must contain at least ieee8023_hdr + ieee802_1x_hdr */
3490 if (len < sizeof(*eth_hdr) + sizeof(*eapol_hdr)) {
3491 wpa_printf(MSG_MSGDUMP, "KaY: EAPOL frame too short (%lu)",
3492 (unsigned long) len);
3493 return;
3494 }
3495
3496 eth_hdr = (struct ieee8023_hdr *) buf;
3497 eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1);
3498 calc_len = sizeof(*eth_hdr) + sizeof(*eapol_hdr) +
3499 be_to_host16(eapol_hdr->length);
3500 if (len < calc_len) {
3501 wpa_printf(MSG_MSGDUMP, "KaY: EAPOL MPDU is invalid: (received len %lu, calculated len %lu, EAPOL length %u)",
3502 (unsigned long) len,
3503 (unsigned long) calc_len,
3504 be_to_host16(eapol_hdr->length));
3505 return;
3506 }
3507 if (len > calc_len) {
3508 wpa_hexdump(MSG_DEBUG,
3509 "KaY: Ignore extra octets following the Packey Body field",
3510 &buf[calc_len], len - calc_len);
3511 len = calc_len;
3512 }
3513
3514 if (eapol_hdr->version < EAPOL_VERSION) {
3515 wpa_printf(MSG_MSGDUMP, "KaY: version %d does not support MKA",
3516 eapol_hdr->version);
3517 return;
3518 }
3519 if (be_to_host16(eth_hdr->ethertype) != ETH_P_PAE ||
3520 eapol_hdr->type != IEEE802_1X_TYPE_EAPOL_MKA)
3521 return; /* ignore other EAPOL types silently here */
3522
3523 wpa_hexdump(MSG_DEBUG, "KaY: RX EAPOL-MKA", buf, len);
3524 if (dl_list_empty(&kay->participant_list)) {
3525 wpa_printf(MSG_ERROR,
3526 "KaY: No MKA participant instance - ignore EAPOL-MKA");
3527 return;
3528 }
3529
3530 ieee802_1x_kay_decode_mkpdu(kay, buf, len);
3531 }
3532
3533
3534 /**
3535 * ieee802_1x_kay_init -
3536 */
3537 struct ieee802_1x_kay *
3538 ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
3539 bool macsec_replay_protect, u32 macsec_replay_window,
3540 u8 macsec_offload, u16 port, u8 priority,
3541 u32 macsec_csindex, const char *ifname, const u8 *addr)
3542 {
3543 struct ieee802_1x_kay *kay;
3544
3545 wpa_printf(MSG_DEBUG, "KaY: Initialize - ifname=%s addr=" MACSTR
3546 " port=%u priority=%u",
3547 ifname, MAC2STR(addr), port, priority);
3548 kay = os_zalloc(sizeof(*kay));
3549 if (!kay) {
3550 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
3551 os_free(ctx);
3552 return NULL;
3553 }
3554
3555 kay->ctx = ctx;
3556
3557 kay->enable = true;
3558 kay->active = false;
3559
3560 kay->authenticated = false;
3561 kay->secured = false;
3562 kay->failed = false;
3563 kay->policy = policy;
3564
3565 os_strlcpy(kay->if_name, ifname, IFNAMSIZ);
3566 os_memcpy(kay->actor_sci.addr, addr, ETH_ALEN);
3567 kay->actor_sci.port = host_to_be16(port ? port : 0x0001);
3568 wpa_printf(MSG_DEBUG, "KaY: Generated SCI: %s",
3569 sci_txt(&kay->actor_sci));
3570 kay->actor_priority = priority;
3571
3572 /* While actor acts as a key server, shall distribute sakey */
3573 kay->dist_kn = 1;
3574 kay->dist_an = 0;
3575 kay->dist_time = 0;
3576
3577 kay->pn_exhaustion = PENDING_PN_EXHAUSTION;
3578 kay->macsec_csindex = macsec_csindex;
3579 kay->mka_algindex = DEFAULT_MKA_ALG_INDEX;
3580 kay->mka_version = MKA_VERSION_ID;
3581
3582 os_memcpy(kay->algo_agility, mka_algo_agility,
3583 sizeof(kay->algo_agility));
3584
3585 dl_list_init(&kay->participant_list);
3586
3587 if (policy != DO_NOT_SECURE &&
3588 secy_get_capability(kay, &kay->macsec_capable) < 0)
3589 goto error;
3590
3591 if (policy == DO_NOT_SECURE ||
3592 kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
3593 kay->macsec_capable = MACSEC_CAP_NOT_IMPLEMENTED;
3594 kay->macsec_desired = false;
3595 kay->macsec_protect = false;
3596 kay->macsec_encrypt = false;
3597 kay->macsec_validate = Disabled;
3598 kay->macsec_replay_protect = false;
3599 kay->macsec_replay_window = 0;
3600 kay->macsec_offload = 0;
3601 kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
3602 kay->mka_hello_time = MKA_HELLO_TIME;
3603 } else {
3604 kay->macsec_desired = true;
3605 kay->macsec_protect = true;
3606 if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF &&
3607 policy == SHOULD_ENCRYPT) {
3608 kay->macsec_encrypt = true;
3609 kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
3610 } else { /* SHOULD_SECURE */
3611 kay->macsec_encrypt = false;
3612 kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
3613 }
3614 kay->macsec_validate = Strict;
3615 kay->macsec_replay_protect = macsec_replay_protect;
3616 kay->macsec_replay_window = macsec_replay_window;
3617 kay->macsec_offload = macsec_offload;
3618 kay->mka_hello_time = MKA_HELLO_TIME;
3619 }
3620
3621 wpa_printf(MSG_DEBUG, "KaY: state machine created");
3622
3623 /* Initialize the SecY must be prio to CP, as CP will control SecY */
3624 if (secy_init_macsec(kay) < 0) {
3625 wpa_printf(MSG_DEBUG, "KaY: Could not initialize MACsec");
3626 goto error;
3627 }
3628
3629 wpa_printf(MSG_DEBUG, "KaY: SecY init MACsec done");
3630
3631 /* init CP */
3632 kay->cp = ieee802_1x_cp_sm_init(kay);
3633 if (kay->cp == NULL)
3634 goto error;
3635
3636 if (policy == DO_NOT_SECURE) {
3637 ieee802_1x_cp_connect_authenticated(kay->cp);
3638 ieee802_1x_cp_sm_step(kay->cp);
3639 } else {
3640 kay->l2_mka = l2_packet_init(kay->if_name, NULL, ETH_P_PAE,
3641 kay_l2_receive, kay, 1);
3642 if (kay->l2_mka == NULL) {
3643 wpa_printf(MSG_WARNING,
3644 "KaY: Failed to initialize L2 packet processing for MKA packet");
3645 goto error;
3646 }
3647 }
3648
3649 return kay;
3650
3651 error:
3652 ieee802_1x_kay_deinit(kay);
3653 return NULL;
3654 }
3655
3656
3657 /**
3658 * ieee802_1x_kay_deinit -
3659 */
3660 void
3661 ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay)
3662 {
3663 struct ieee802_1x_mka_participant *participant;
3664
3665 if (!kay)
3666 return;
3667
3668 wpa_printf(MSG_DEBUG, "KaY: state machine removed");
3669
3670 while (!dl_list_empty(&kay->participant_list)) {
3671 participant = dl_list_entry(kay->participant_list.next,
3672 struct ieee802_1x_mka_participant,
3673 list);
3674 ieee802_1x_kay_delete_mka(kay, &participant->ckn);
3675 }
3676
3677 ieee802_1x_cp_sm_deinit(kay->cp);
3678 secy_deinit_macsec(kay);
3679
3680 if (kay->l2_mka) {
3681 l2_packet_deinit(kay->l2_mka);
3682 kay->l2_mka = NULL;
3683 }
3684
3685 os_free(kay->ctx);
3686 os_free(kay);
3687 }
3688
3689
3690 static const char * mode_txt(enum mka_created_mode mode)
3691 {
3692 switch (mode) {
3693 case PSK:
3694 return "PSK";
3695 case EAP_EXCHANGE:
3696 return "EAP";
3697 }
3698
3699 return "?";
3700 }
3701
3702
3703 /**
3704 * ieee802_1x_kay_create_mka -
3705 */
3706 struct ieee802_1x_mka_participant *
3707 ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay,
3708 const struct mka_key_name *ckn,
3709 const struct mka_key *cak, u32 life,
3710 enum mka_created_mode mode, bool is_authenticator)
3711 {
3712 struct ieee802_1x_mka_participant *participant;
3713 unsigned int usecs;
3714
3715 wpa_printf(MSG_DEBUG,
3716 "KaY: Create MKA (ifname=%s mode=%s authenticator=%s)",
3717 kay->if_name, mode_txt(mode), yes_no(is_authenticator));
3718
3719 if (!kay || !ckn || !cak) {
3720 wpa_printf(MSG_ERROR, "KaY: CKN or CAK is null");
3721 return NULL;
3722 }
3723
3724 if (cak->len != 16 && cak->len != 32) {
3725 wpa_printf(MSG_ERROR, "KaY: Unexpected CAK length %u",
3726 (unsigned int) cak->len);
3727 return NULL;
3728 }
3729 if (ckn->len > MAX_CKN_LEN) {
3730 wpa_printf(MSG_ERROR, "KaY: CKN is out of range (>32 bytes)");
3731 return NULL;
3732 }
3733 if (!kay->enable) {
3734 wpa_printf(MSG_ERROR, "KaY: Now is at disable state");
3735 return NULL;
3736 }
3737
3738 participant = os_zalloc(sizeof(*participant));
3739 if (!participant) {
3740 wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
3741 return NULL;
3742 }
3743
3744 participant->ckn.len = ckn->len;
3745 os_memcpy(participant->ckn.name, ckn->name, ckn->len);
3746 wpa_hexdump(MSG_DEBUG, "KaY: CKN", participant->ckn.name,
3747 participant->ckn.len);
3748 participant->cak.len = cak->len;
3749 os_memcpy(participant->cak.key, cak->key, cak->len);
3750 wpa_hexdump_key(MSG_DEBUG, "KaY: CAK", participant->cak.key,
3751 participant->cak.len);
3752 if (life) {
3753 struct os_reltime now;
3754 os_get_reltime(&now);
3755
3756 participant->cak_life = life + now.sec;
3757 }
3758
3759 switch (mode) {
3760 case EAP_EXCHANGE:
3761 if (is_authenticator) {
3762 participant->is_obliged_key_server = true;
3763 participant->can_be_key_server = true;
3764 participant->is_key_server = true;
3765 participant->principal = true;
3766
3767 os_memcpy(&kay->key_server_sci, &kay->actor_sci,
3768 sizeof(kay->key_server_sci));
3769 kay->key_server_priority = kay->actor_priority;
3770 participant->is_elected = true;
3771 } else {
3772 participant->is_obliged_key_server = false;
3773 participant->can_be_key_server = false;
3774 participant->is_key_server = false;
3775 participant->is_elected = true;
3776 }
3777 break;
3778
3779 default:
3780 participant->is_obliged_key_server = false;
3781 participant->can_be_key_server = true;
3782 participant->is_key_server = true;
3783 participant->is_elected = false;
3784 break;
3785 }
3786
3787 participant->cached = false;
3788
3789 participant->active = false;
3790 participant->participant = false;
3791 participant->retain = false;
3792 participant->activate = DEFAULT;
3793
3794 if (participant->is_key_server)
3795 participant->principal = true;
3796
3797 dl_list_init(&participant->live_peers);
3798 dl_list_init(&participant->potential_peers);
3799
3800 participant->retry_count = 0;
3801 participant->kay = kay;
3802
3803 if (!reset_participant_mi(participant))
3804 goto fail;
3805 wpa_printf(MSG_DEBUG, "KaY: Selected random MI: %s",
3806 mi_txt(participant->mi));
3807
3808 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
3809 if (mode != PSK) {
3810 wpa_printf(MSG_ERROR, "CONFIG_AIDL_MACSEC_PSK_METHODS only support PSK");
3811 goto fail;
3812 }
3813 wpa_printf(MSG_INFO, "Init macsec PSK HAL");
3814 if (aidl_psk_init()) {
3815 wpa_printf(MSG_ERROR, "Cannot init aidl macsec psk HAL");
3816 goto fail;
3817 }
3818 #endif
3819
3820 participant->lrx = false;
3821 participant->ltx = false;
3822 participant->orx = false;
3823 participant->otx = false;
3824 participant->to_dist_sak = false;
3825 participant->to_use_sak = false;
3826 participant->new_sak = false;
3827 dl_list_init(&participant->sak_list);
3828 participant->new_key = NULL;
3829 dl_list_init(&participant->rxsc_list);
3830 participant->txsc = ieee802_1x_kay_init_transmit_sc(&kay->actor_sci);
3831 secy_cp_control_protect_frames(kay, kay->macsec_protect);
3832 secy_cp_control_replay(kay, kay->macsec_replay_protect,
3833 kay->macsec_replay_window);
3834 secy_cp_control_offload(kay, kay->macsec_offload);
3835 if (secy_create_transmit_sc(kay, participant->txsc))
3836 goto fail;
3837
3838 #ifdef CONFIG_AIDL_MACSEC_PSK_METHODS
3839 /* If using external PSK methods, we don't need to generate kek and ick
3840 * key here and cak.key is actually a reference index */
3841 participant->kek.len = participant->cak.len;
3842 participant->ick.len = participant->cak.len;
3843 memcpy(participant->kek.key, participant->cak.key, participant->cak.len);
3844 memcpy(participant->ick.key, participant->cak.key, participant->cak.len);
3845 #else
3846 /* to derive KEK from CAK and CKN */
3847 participant->kek.len = participant->cak.len;
3848 if (mka_alg_tbl[kay->mka_algindex].kek_trfm(participant->cak.key,
3849 participant->cak.len,
3850 participant->ckn.name,
3851 participant->ckn.len,
3852 participant->kek.key,
3853 participant->kek.len)) {
3854 wpa_printf(MSG_ERROR, "KaY: KEK derivation failed");
3855 goto fail;
3856 }
3857 wpa_hexdump_key(MSG_DEBUG, "KaY: Derived KEK",
3858 participant->kek.key, participant->kek.len);
3859
3860 /* to derive ICK from CAK and CKN */
3861 participant->ick.len = participant->cak.len;
3862 if (mka_alg_tbl[kay->mka_algindex].ick_trfm(participant->cak.key,
3863 participant->cak.len,
3864 participant->ckn.name,
3865 participant->ckn.len,
3866 participant->ick.key,
3867 participant->ick.len)) {
3868 wpa_printf(MSG_ERROR, "KaY: ICK derivation failed");
3869 goto fail;
3870 }
3871 wpa_hexdump_key(MSG_DEBUG, "KaY: Derived ICK",
3872 participant->ick.key, participant->ick.len);
3873 #endif
3874
3875 dl_list_add(&kay->participant_list, &participant->list);
3876
3877 usecs = os_random() % (kay->mka_hello_time * 1000);
3878 eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
3879 participant, NULL);
3880
3881 /* Disable MKA lifetime for PSK mode.
3882 * The peer(s) can take a long time to come up, because we
3883 * create a "standby" MKA, and we need it to remain live until
3884 * some peer appears.
3885 */
3886 if (mode != PSK) {
3887 struct os_reltime now;
3888 os_get_reltime(&now);
3889
3890 participant->mka_life = MKA_LIFE_TIME / 1000 + now.sec +
3891 usecs / 1000000;
3892 }
3893 participant->mode = mode;
3894
3895 return participant;
3896
3897 fail:
3898 os_free(participant->txsc);
3899 os_free(participant);
3900 return NULL;
3901 }
3902
3903
3904 /**
3905 * ieee802_1x_kay_delete_mka -
3906 */
3907 void
3908 ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn)
3909 {
3910 struct ieee802_1x_mka_participant *participant;
3911 struct ieee802_1x_kay_peer *peer;
3912 struct data_key *sak;
3913 struct receive_sc *rxsc;
3914
3915 if (!kay || !ckn)
3916 return;
3917
3918 wpa_printf(MSG_DEBUG, "KaY: participant removed");
3919
3920 /* get the participant */
3921 participant = ieee802_1x_kay_get_participant(kay, ckn->name, ckn->len);
3922 if (!participant) {
3923 wpa_hexdump(MSG_DEBUG, "KaY: participant is not found",
3924 ckn->name, ckn->len);
3925 return;
3926 }
3927
3928 eloop_cancel_timeout(ieee802_1x_participant_timer, participant, NULL);
3929 dl_list_del(&participant->list);
3930
3931 /* remove live peer */
3932 while (!dl_list_empty(&participant->live_peers)) {
3933 peer = dl_list_entry(participant->live_peers.next,
3934 struct ieee802_1x_kay_peer, list);
3935 dl_list_del(&peer->list);
3936 os_free(peer);
3937 }
3938
3939 /* remove potential peer */
3940 while (!dl_list_empty(&participant->potential_peers)) {
3941 peer = dl_list_entry(participant->potential_peers.next,
3942 struct ieee802_1x_kay_peer, list);
3943 dl_list_del(&peer->list);
3944 os_free(peer);
3945 }
3946
3947 /* remove sak */
3948 while (!dl_list_empty(&participant->sak_list)) {
3949 sak = dl_list_entry(participant->sak_list.next,
3950 struct data_key, list);
3951 dl_list_del(&sak->list);
3952 ieee802_1x_kay_deinit_data_key(sak);
3953 }
3954 while (!dl_list_empty(&participant->rxsc_list)) {
3955 rxsc = dl_list_entry(participant->rxsc_list.next,
3956 struct receive_sc, list);
3957 ieee802_1x_kay_deinit_receive_sc(participant, rxsc);
3958 }
3959 ieee802_1x_kay_deinit_transmit_sc(participant, participant->txsc);
3960
3961 os_memset(&participant->cak, 0, sizeof(participant->cak));
3962 os_memset(&participant->kek, 0, sizeof(participant->kek));
3963 os_memset(&participant->ick, 0, sizeof(participant->ick));
3964 os_free(participant);
3965 }
3966
3967
3968 /**
3969 * ieee802_1x_kay_mka_participate -
3970 */
3971 void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay,
3972 struct mka_key_name *ckn, bool status)
3973 {
3974 struct ieee802_1x_mka_participant *participant;
3975
3976 if (!kay || !ckn)
3977 return;
3978
3979 participant = ieee802_1x_kay_get_participant(kay, ckn->name, ckn->len);
3980 if (!participant)
3981 return;
3982
3983 participant->active = status;
3984 }
3985
3986
3987 /**
3988 * ieee802_1x_kay_new_sak -
3989 */
3990 int
3991 ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay)
3992 {
3993 struct ieee802_1x_mka_participant *participant;
3994
3995 if (!kay)
3996 return -1;
3997
3998 participant = ieee802_1x_kay_get_principal_participant(kay);
3999 if (!participant)
4000 return -1;
4001
4002 participant->new_sak = true;
4003 wpa_printf(MSG_DEBUG, "KaY: new SAK signal");
4004
4005 return 0;
4006 }
4007
4008
4009 /**
4010 * ieee802_1x_kay_change_cipher_suite -
4011 */
4012 int
4013 ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
4014 unsigned int cs_index)
4015 {
4016 struct ieee802_1x_mka_participant *participant;
4017 enum macsec_cap secy_cap;
4018
4019 if (!kay)
4020 return -1;
4021
4022 if (cs_index >= CS_TABLE_SIZE) {
4023 wpa_printf(MSG_ERROR,
4024 "KaY: Configured cipher suite index is out of range");
4025 return -1;
4026 }
4027 if (kay->macsec_csindex == cs_index)
4028 return -2;
4029
4030 if (cs_index == 0)
4031 kay->macsec_desired = false;
4032
4033 kay->macsec_csindex = cs_index;
4034 kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable;
4035
4036 if (secy_get_capability(kay, &secy_cap) < 0)
4037 return -3;
4038
4039 if (kay->macsec_capable > secy_cap)
4040 kay->macsec_capable = secy_cap;
4041
4042 participant = ieee802_1x_kay_get_principal_participant(kay);
4043 if (participant) {
4044 wpa_printf(MSG_INFO, "KaY: Cipher Suite changed");
4045 participant->new_sak = true;
4046 }
4047
4048 return 0;
4049 }
4050
4051
4052 #ifdef CONFIG_CTRL_IFACE
4053
4054 /**
4055 * ieee802_1x_kay_get_status - Get IEEE 802.1X KaY status details
4056 * @sm: Pointer to KaY allocated with ieee802_1x_kay_init()
4057 * @buf: Buffer for status information
4058 * @buflen: Maximum buffer length
4059 * @verbose: Whether to include verbose status information
4060 * Returns: Number of bytes written to buf.
4061 *
4062 * Query KaY status information. This function fills in a text area with current
4063 * status information. If the buffer (buf) is not large enough, status
4064 * information will be truncated to fit the buffer.
4065 */
4066 int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
4067 size_t buflen)
4068 {
4069 char *pos, *end;
4070 int res, count;
4071 struct ieee802_1x_mka_participant *p;
4072
4073 if (!kay)
4074 return 0;
4075
4076 pos = buf;
4077 end = buf + buflen;
4078
4079 res = os_snprintf(pos, end - pos,
4080 "PAE KaY status=%s\n"
4081 "Authenticated=%s\n"
4082 "Secured=%s\n"
4083 "Failed=%s\n"
4084 "Actor Priority=%u\n"
4085 "Key Server Priority=%u\n"
4086 "Is Key Server=%s\n"
4087 "Number of Keys Distributed=%u\n"
4088 "Number of Keys Received=%u\n"
4089 "MKA Hello Time=%u\n",
4090 kay->active ? "Active" : "Not-Active",
4091 kay->authenticated ? "Yes" : "No",
4092 kay->secured ? "Yes" : "No",
4093 kay->failed ? "Yes" : "No",
4094 kay->actor_priority,
4095 kay->key_server_priority,
4096 kay->is_key_server ? "Yes" : "No",
4097 kay->dist_kn - 1,
4098 kay->rcvd_keys,
4099 kay->mka_hello_time);
4100 if (os_snprintf_error(buflen, res))
4101 return 0;
4102 pos += res;
4103
4104 res = os_snprintf(pos, end - pos,
4105 "actor_sci=%s\n", sci_txt(&kay->actor_sci));
4106 if (os_snprintf_error(buflen, res))
4107 return end - pos;
4108 pos += res;
4109
4110 res = os_snprintf(pos, end - pos,
4111 "key_server_sci=%s\n", sci_txt(&kay->key_server_sci));
4112 if (os_snprintf_error(buflen, res))
4113 return end - pos;
4114 pos += res;
4115
4116 count = 0;
4117 dl_list_for_each(p, &kay->participant_list,
4118 struct ieee802_1x_mka_participant, list) {
4119 char *pos2 = pos;
4120
4121 res = os_snprintf(pos2, end - pos2, "participant_idx=%d\nckn=",
4122 count);
4123 if (os_snprintf_error(buflen, res))
4124 return end - pos;
4125 pos2 += res;
4126 count++;
4127
4128 pos2 += wpa_snprintf_hex(pos2, end - pos2, p->ckn.name,
4129 p->ckn.len);
4130
4131 res = os_snprintf(pos2, end - pos2,
4132 "\nmi=%s\n"
4133 "mn=%u\n"
4134 "active=%s\n"
4135 "participant=%s\n"
4136 "retain=%s\n"
4137 "live_peers=%u\n"
4138 "potential_peers=%u\n"
4139 "is_key_server=%s\n"
4140 "is_elected=%s\n",
4141 mi_txt(p->mi), p->mn,
4142 yes_no(p->active),
4143 yes_no(p->participant),
4144 yes_no(p->retain),
4145 dl_list_len(&p->live_peers),
4146 dl_list_len(&p->potential_peers),
4147 yes_no(p->is_key_server),
4148 yes_no(p->is_elected));
4149 if (os_snprintf_error(buflen, res))
4150 return end - pos;
4151 pos2 += res;
4152 pos = pos2;
4153 }
4154
4155 return pos - buf;
4156 }
4157
4158
4159 static const char * true_false(bool val)
4160 {
4161 return val ? "true" : "false";
4162 }
4163
4164
4165 static const char * activate_control_txt(enum activate_ctrl activate)
4166 {
4167 switch (activate) {
4168 case DEFAULT:
4169 return "default";
4170 case DISABLED:
4171 return "disabled";
4172 case ON_OPER_UP:
4173 return "onOperUp";
4174 case ALWAYS:
4175 return "always";
4176 }
4177
4178 return "?";
4179 }
4180
4181
4182 static char * mka_mib_peer(struct dl_list *peers, bool live, char *buf,
4183 char *end)
4184 {
4185 char *pos = buf;
4186 struct ieee802_1x_kay_peer *p;
4187 int res;
4188
4189 dl_list_for_each(p, peers, struct ieee802_1x_kay_peer, list) {
4190 res = os_snprintf(pos, end - pos,
4191 "ieee8021XKayMkaPeerListMI=%s\n"
4192 "ieee8021XKayMkaPeerListMN=%u\n"
4193 "ieee8021XKayMkaPeerListType=%u\n"
4194 "ieee8021XKayMkaPeerListSCI=%s\n",
4195 mi_txt(p->mi),
4196 p->mn,
4197 live ? 1 : 2,
4198 sci_txt(&p->sci));
4199 if (os_snprintf_error(end - pos, res))
4200 return pos;
4201 pos += res;
4202 }
4203
4204 return pos;
4205 }
4206
4207
4208 int ieee802_1x_kay_get_mib(struct ieee802_1x_kay *kay, char *buf,
4209 size_t buflen)
4210 {
4211 char *pos, *end;
4212 int res;
4213 struct ieee802_1x_mka_participant *p;
4214
4215 if (!kay)
4216 return 0;
4217
4218 pos = buf;
4219 end = buf + buflen;
4220
4221 dl_list_for_each(p, &kay->participant_list,
4222 struct ieee802_1x_mka_participant, list) {
4223 char *pos2 = pos;
4224
4225 res = os_snprintf(pos2, end - pos2, "ieee8021XKayMkaPartCKN=");
4226 if (os_snprintf_error(buflen, res))
4227 return end - pos;
4228 pos2 += res;
4229
4230 pos2 += wpa_snprintf_hex(pos2, end - pos2, p->ckn.name,
4231 p->ckn.len);
4232
4233 res = os_snprintf(pos2, end - pos2,
4234 "\nieee8021XKayMkaPartCached=%s\n"
4235 "ieee8021XKayMkaPartActive=%s\n"
4236 "ieee8021XKayMkaPartRetain=%s\n"
4237 "ieee8021XKayMkaPartActivateControl=%s\n"
4238 "ieee8021XKayMkaPartPrincipal=%s\n",
4239 true_false(p->cached),
4240 true_false(p->active),
4241 true_false(p->retain),
4242 activate_control_txt(p->activate),
4243 true_false(p->principal));
4244 if (os_snprintf_error(buflen, res))
4245 return end - pos;
4246 pos2 += res;
4247 pos = pos2;
4248
4249 pos = mka_mib_peer(&p->live_peers, true, pos, end);
4250 pos = mka_mib_peer(&p->potential_peers, false, pos, end);
4251 }
4252
4253 return pos - buf;
4254 }
4255
4256 #endif /* CONFIG_CTRL_IFACE */
4257