1 /*
2 * Driver interaction with Linux MACsec kernel module
3 * Copyright (c) 2016, Sabrina Dubroca <sd@queasysnail.net> and Red Hat, Inc.
4 * Copyright (c) 2019, The Linux Foundation
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10 #include "includes.h"
11 #include <sys/ioctl.h>
12 #include <net/if.h>
13 #include <netpacket/packet.h>
14 #include <net/if_arp.h>
15 #include <net/if.h>
16 #include <netlink/netlink.h>
17 #include <netlink/genl/genl.h>
18 #include <netlink/genl/ctrl.h>
19 #include <netlink/route/link.h>
20 #include <netlink/route/link/macsec.h>
21 #include <linux/if_macsec.h>
22 #include <inttypes.h>
23
24 #include "utils/common.h"
25 #include "utils/eloop.h"
26 #include "common/eapol_common.h"
27 #include "pae/ieee802_1x_kay.h"
28 #include "driver.h"
29 #include "driver_wired_common.h"
30
31 #define DRV_PREFIX "macsec_linux: "
32
33 #define UNUSED_SCI 0xffffffffffffffff
34
35 struct cb_arg {
36 struct macsec_drv_data *drv;
37 u32 *pn;
38 int ifindex;
39 u8 txsa;
40 u8 rxsa;
41 u64 rxsci;
42 };
43
44 struct macsec_genl_ctx {
45 struct nl_sock *sk;
46 int macsec_genl_id;
47 struct cb_arg cb_arg;
48 };
49
50 struct macsec_drv_data {
51 struct driver_wired_common_data common;
52 struct rtnl_link *link;
53 struct nl_cache *link_cache;
54 struct nl_sock *sk;
55 struct macsec_genl_ctx ctx;
56
57 char ifname[IFNAMSIZ + 1];
58 int ifi;
59 int parent_ifi;
60 int use_pae_group_addr;
61
62 bool created_link;
63
64 bool controlled_port_enabled;
65 bool controlled_port_enabled_set;
66
67 bool protect_frames;
68 bool protect_frames_set;
69
70 bool encrypt;
71 bool encrypt_set;
72
73 bool replay_protect;
74 bool replay_protect_set;
75
76 u32 replay_window;
77
78 u8 encoding_sa;
79 bool encoding_sa_set;
80
81 u64 cipher_suite;
82 bool cipher_suite_set;
83 };
84
85
86 static int dump_callback(struct nl_msg *msg, void *argp);
87
88
msg_prepare(enum macsec_nl_commands cmd,const struct macsec_genl_ctx * ctx,unsigned int ifindex)89 static struct nl_msg * msg_prepare(enum macsec_nl_commands cmd,
90 const struct macsec_genl_ctx *ctx,
91 unsigned int ifindex)
92 {
93 struct nl_msg *msg;
94
95 msg = nlmsg_alloc();
96 if (!msg) {
97 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc message");
98 return NULL;
99 }
100
101 if (!genlmsg_put(msg, 0, 0, ctx->macsec_genl_id, 0, 0, cmd, 0)) {
102 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to put header");
103 goto nla_put_failure;
104 }
105
106 NLA_PUT_U32(msg, MACSEC_ATTR_IFINDEX, ifindex);
107
108 return msg;
109
110 nla_put_failure:
111 nlmsg_free(msg);
112 return NULL;
113 }
114
115
nla_put_rxsc_config(struct nl_msg * msg,u64 sci)116 static int nla_put_rxsc_config(struct nl_msg *msg, u64 sci)
117 {
118 struct nlattr *nest = nla_nest_start(msg, MACSEC_ATTR_RXSC_CONFIG);
119
120 if (!nest)
121 return -1;
122
123 NLA_PUT_U64(msg, MACSEC_RXSC_ATTR_SCI, sci);
124
125 nla_nest_end(msg, nest);
126
127 return 0;
128
129 nla_put_failure:
130 return -1;
131 }
132
133
init_genl_ctx(struct macsec_drv_data * drv)134 static int init_genl_ctx(struct macsec_drv_data *drv)
135 {
136 struct macsec_genl_ctx *ctx = &drv->ctx;
137
138 ctx->sk = nl_socket_alloc();
139 if (!ctx->sk) {
140 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
141 return -1;
142 }
143
144 if (genl_connect(ctx->sk) < 0) {
145 wpa_printf(MSG_ERROR,
146 DRV_PREFIX "connection to genl socket failed");
147 goto out_free;
148 }
149
150 ctx->macsec_genl_id = genl_ctrl_resolve(ctx->sk, "macsec");
151 if (ctx->macsec_genl_id < 0) {
152 wpa_printf(MSG_ERROR, DRV_PREFIX "genl resolve failed");
153 goto out_free;
154 }
155
156 memset(&ctx->cb_arg, 0, sizeof(ctx->cb_arg));
157 ctx->cb_arg.drv = drv;
158
159 nl_socket_modify_cb(ctx->sk, NL_CB_VALID, NL_CB_CUSTOM, dump_callback,
160 &ctx->cb_arg);
161
162 return 0;
163
164 out_free:
165 nl_socket_free(ctx->sk);
166 ctx->sk = NULL;
167 return -1;
168 }
169
170
try_commit(struct macsec_drv_data * drv)171 static int try_commit(struct macsec_drv_data *drv)
172 {
173 int err;
174
175 if (!drv->sk)
176 return 0;
177
178 if (!drv->link)
179 return 0;
180
181 if (drv->controlled_port_enabled_set) {
182 struct rtnl_link *change = rtnl_link_alloc();
183
184 wpa_printf(MSG_DEBUG, DRV_PREFIX
185 "%s: try_commit controlled_port_enabled=%d",
186 drv->ifname, drv->controlled_port_enabled);
187 if (!change)
188 return -1;
189
190 rtnl_link_set_name(change, drv->ifname);
191
192 if (drv->controlled_port_enabled)
193 rtnl_link_set_flags(change, IFF_UP);
194 else
195 rtnl_link_unset_flags(change, IFF_UP);
196
197 err = rtnl_link_change(drv->sk, change, change, 0);
198 if (err < 0)
199 return err;
200
201 rtnl_link_put(change);
202
203 drv->controlled_port_enabled_set = false;
204 }
205
206 if (drv->protect_frames_set) {
207 wpa_printf(MSG_DEBUG, DRV_PREFIX
208 "%s: try_commit protect_frames=%d",
209 drv->ifname, drv->protect_frames);
210 rtnl_link_macsec_set_protect(drv->link, drv->protect_frames);
211 }
212
213 if (drv->encrypt_set) {
214 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: try_commit encrypt=%d",
215 drv->ifname, drv->encrypt);
216 rtnl_link_macsec_set_encrypt(drv->link, drv->encrypt);
217 }
218
219 if (drv->replay_protect_set) {
220 wpa_printf(MSG_DEBUG, DRV_PREFIX
221 "%s: try_commit replay_protect=%d replay_window=%d",
222 drv->ifname, drv->replay_protect,
223 drv->replay_window);
224 rtnl_link_macsec_set_replay_protect(drv->link,
225 drv->replay_protect);
226 if (drv->replay_protect)
227 rtnl_link_macsec_set_window(drv->link,
228 drv->replay_window);
229 }
230
231 if (drv->encoding_sa_set) {
232 wpa_printf(MSG_DEBUG, DRV_PREFIX
233 "%s: try_commit encoding_sa=%d",
234 drv->ifname, drv->encoding_sa);
235 rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa);
236 }
237
238 err = rtnl_link_add(drv->sk, drv->link, 0);
239 if (err < 0)
240 return err;
241
242 drv->protect_frames_set = false;
243 drv->encrypt_set = false;
244 drv->replay_protect_set = false;
245
246 return 0;
247 }
248
249
macsec_drv_wpa_deinit(void * priv)250 static void macsec_drv_wpa_deinit(void *priv)
251 {
252 struct macsec_drv_data *drv = priv;
253
254 driver_wired_deinit_common(&drv->common);
255 os_free(drv);
256 }
257
258
macsec_check_macsec(void)259 static int macsec_check_macsec(void)
260 {
261 struct nl_sock *sk;
262 int err = -1;
263
264 sk = nl_socket_alloc();
265 if (!sk) {
266 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
267 return -1;
268 }
269
270 if (genl_connect(sk) < 0) {
271 wpa_printf(MSG_ERROR,
272 DRV_PREFIX "connection to genl socket failed");
273 goto out_free;
274 }
275
276 if (genl_ctrl_resolve(sk, "macsec") < 0) {
277 wpa_printf(MSG_ERROR,
278 DRV_PREFIX "genl resolve failed - macsec kernel module not present?");
279 goto out_free;
280 }
281
282 err = 0;
283
284 out_free:
285 nl_socket_free(sk);
286 return err;
287 }
288
289
macsec_drv_wpa_init(void * ctx,const char * ifname)290 static void * macsec_drv_wpa_init(void *ctx, const char *ifname)
291 {
292 struct macsec_drv_data *drv;
293
294 if (macsec_check_macsec() < 0)
295 return NULL;
296
297 drv = os_zalloc(sizeof(*drv));
298 if (!drv)
299 return NULL;
300
301 if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
302 os_free(drv);
303 return NULL;
304 }
305
306 return drv;
307 }
308
309
macsec_drv_macsec_init(void * priv,struct macsec_init_params * params)310 static int macsec_drv_macsec_init(void *priv, struct macsec_init_params *params)
311 {
312 struct macsec_drv_data *drv = priv;
313 int err;
314
315 wpa_printf(MSG_DEBUG, "%s", __func__);
316
317 drv->sk = nl_socket_alloc();
318 if (!drv->sk)
319 return -1;
320
321 err = nl_connect(drv->sk, NETLINK_ROUTE);
322 if (err < 0) {
323 wpa_printf(MSG_ERROR, DRV_PREFIX
324 "Unable to connect NETLINK_ROUTE socket: %s",
325 nl_geterror(err));
326 goto sock;
327 }
328
329 err = rtnl_link_alloc_cache(drv->sk, AF_UNSPEC, &drv->link_cache);
330 if (err < 0) {
331 wpa_printf(MSG_ERROR, DRV_PREFIX "Unable to get link cache: %s",
332 nl_geterror(err));
333 goto sock;
334 }
335
336 drv->parent_ifi = rtnl_link_name2i(drv->link_cache, drv->common.ifname);
337 if (drv->parent_ifi == 0) {
338 wpa_printf(MSG_ERROR, DRV_PREFIX
339 "couldn't find ifindex for interface %s",
340 drv->common.ifname);
341 goto cache;
342 }
343 wpa_printf(MSG_DEBUG, DRV_PREFIX "ifname=%s parent_ifi=%d",
344 drv->common.ifname, drv->parent_ifi);
345
346 err = init_genl_ctx(drv);
347 if (err < 0)
348 goto cache;
349
350 return 0;
351
352 cache:
353 nl_cache_free(drv->link_cache);
354 drv->link_cache = NULL;
355 sock:
356 nl_socket_free(drv->sk);
357 drv->sk = NULL;
358 return -1;
359 }
360
361
macsec_drv_macsec_deinit(void * priv)362 static int macsec_drv_macsec_deinit(void *priv)
363 {
364 struct macsec_drv_data *drv = priv;
365
366 wpa_printf(MSG_DEBUG, "%s", __func__);
367
368 if (drv->sk)
369 nl_socket_free(drv->sk);
370 drv->sk = NULL;
371
372 if (drv->link_cache)
373 nl_cache_free(drv->link_cache);
374 drv->link_cache = NULL;
375
376 if (drv->ctx.sk)
377 nl_socket_free(drv->ctx.sk);
378
379 return 0;
380 }
381
382
macsec_drv_get_capability(void * priv,enum macsec_cap * cap)383 static int macsec_drv_get_capability(void *priv, enum macsec_cap *cap)
384 {
385 wpa_printf(MSG_DEBUG, "%s", __func__);
386
387 *cap = MACSEC_CAP_INTEG_AND_CONF;
388
389 return 0;
390 }
391
392
393 /**
394 * macsec_drv_enable_protect_frames - Set protect frames status
395 * @priv: Private driver interface data
396 * @enabled: true = protect frames enabled
397 * false = protect frames disabled
398 * Returns: 0 on success, -1 on failure (or if not supported)
399 */
macsec_drv_enable_protect_frames(void * priv,bool enabled)400 static int macsec_drv_enable_protect_frames(void *priv, bool enabled)
401 {
402 struct macsec_drv_data *drv = priv;
403
404 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
405
406 drv->protect_frames_set = true;
407 drv->protect_frames = enabled;
408
409 return try_commit(drv);
410 }
411
412
413 /**
414 * macsec_drv_enable_encrypt - Set protect frames status
415 * @priv: Private driver interface data
416 * @enabled: true = protect frames enabled
417 * false = protect frames disabled
418 * Returns: 0 on success, -1 on failure (or if not supported)
419 */
macsec_drv_enable_encrypt(void * priv,bool enabled)420 static int macsec_drv_enable_encrypt(void *priv, bool enabled)
421 {
422 struct macsec_drv_data *drv = priv;
423
424 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
425
426 drv->encrypt_set = true;
427 drv->encrypt = enabled;
428
429 return try_commit(drv);
430 }
431
432
433 /**
434 * macsec_drv_set_replay_protect - Set replay protect status and window size
435 * @priv: Private driver interface data
436 * @enabled: true = replay protect enabled
437 * false = replay protect disabled
438 * @window: replay window size, valid only when replay protect enabled
439 * Returns: 0 on success, -1 on failure (or if not supported)
440 */
macsec_drv_set_replay_protect(void * priv,bool enabled,u32 window)441 static int macsec_drv_set_replay_protect(void *priv, bool enabled,
442 u32 window)
443 {
444 struct macsec_drv_data *drv = priv;
445
446 wpa_printf(MSG_DEBUG, "%s -> %s, %u", __func__,
447 enabled ? "TRUE" : "FALSE", window);
448
449 drv->replay_protect_set = true;
450 drv->replay_protect = enabled;
451 if (enabled)
452 drv->replay_window = window;
453
454 return try_commit(drv);
455 }
456
457
458 /**
459 * macsec_drv_set_current_cipher_suite - Set current cipher suite
460 * @priv: Private driver interface data
461 * @cs: EUI64 identifier
462 * Returns: 0 on success, -1 on failure (or if not supported)
463 */
macsec_drv_set_current_cipher_suite(void * priv,u64 cs)464 static int macsec_drv_set_current_cipher_suite(void *priv, u64 cs)
465 {
466 struct macsec_drv_data *drv = priv;
467
468 wpa_printf(MSG_DEBUG, "%s -> %016" PRIx64, __func__, cs);
469
470 drv->cipher_suite_set = true;
471 drv->cipher_suite = cs;
472
473 return try_commit(drv);
474 }
475
476
477 /**
478 * macsec_drv_enable_controlled_port - Set controlled port status
479 * @priv: Private driver interface data
480 * @enabled: true = controlled port enabled
481 * false = controlled port disabled
482 * Returns: 0 on success, -1 on failure (or if not supported)
483 */
macsec_drv_enable_controlled_port(void * priv,bool enabled)484 static int macsec_drv_enable_controlled_port(void *priv, bool enabled)
485 {
486 struct macsec_drv_data *drv = priv;
487
488 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
489
490 drv->controlled_port_enabled = enabled;
491 drv->controlled_port_enabled_set = true;
492
493 return try_commit(drv);
494 }
495
496
497 static struct nla_policy sa_policy[MACSEC_SA_ATTR_MAX + 1] = {
498 [MACSEC_SA_ATTR_AN] = { .type = NLA_U8 },
499 [MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 },
500 [MACSEC_SA_ATTR_PN] = { .type = NLA_U32 },
501 [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY },
502 };
503
504 static struct nla_policy sc_policy[MACSEC_RXSC_ATTR_MAX + 1] = {
505 [MACSEC_RXSC_ATTR_SCI] = { .type = NLA_U64 },
506 [MACSEC_RXSC_ATTR_ACTIVE] = { .type = NLA_U8 },
507 [MACSEC_RXSC_ATTR_SA_LIST] = { .type = NLA_NESTED },
508 };
509
510 static struct nla_policy main_policy[MACSEC_ATTR_MAX + 1] = {
511 [MACSEC_ATTR_IFINDEX] = { .type = NLA_U32 },
512 [MACSEC_ATTR_SECY] = { .type = NLA_NESTED },
513 [MACSEC_ATTR_TXSA_LIST] = { .type = NLA_NESTED },
514 [MACSEC_ATTR_RXSC_LIST] = { .type = NLA_NESTED },
515 };
516
dump_callback(struct nl_msg * msg,void * argp)517 static int dump_callback(struct nl_msg *msg, void *argp)
518 {
519 struct nlmsghdr *ret_hdr = nlmsg_hdr(msg);
520 struct nlattr *tb_msg[MACSEC_ATTR_MAX + 1];
521 struct cb_arg *arg = (struct cb_arg *) argp;
522 struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(ret_hdr);
523 int err;
524
525 if (ret_hdr->nlmsg_type != arg->drv->ctx.macsec_genl_id)
526 return 0;
527
528 err = nla_parse(tb_msg, MACSEC_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
529 genlmsg_attrlen(gnlh, 0), main_policy);
530 if (err < 0)
531 return 0;
532
533 if (!tb_msg[MACSEC_ATTR_IFINDEX])
534 return 0;
535
536 if (nla_get_u32(tb_msg[MACSEC_ATTR_IFINDEX]) != (u32) arg->ifindex)
537 return 0;
538
539 if (arg->txsa < 4 && !tb_msg[MACSEC_ATTR_TXSA_LIST]) {
540 return 0;
541 } else if (arg->txsa < 4) {
542 struct nlattr *nla;
543 int rem;
544
545 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_TXSA_LIST], rem) {
546 struct nlattr *tb[MACSEC_SA_ATTR_MAX + 1];
547
548 err = nla_parse_nested(tb, MACSEC_SA_ATTR_MAX, nla,
549 sa_policy);
550 if (err < 0)
551 continue;
552 if (!tb[MACSEC_SA_ATTR_AN])
553 continue;
554 if (nla_get_u8(tb[MACSEC_SA_ATTR_AN]) != arg->txsa)
555 continue;
556 if (!tb[MACSEC_SA_ATTR_PN])
557 return 0;
558 *arg->pn = nla_get_u32(tb[MACSEC_SA_ATTR_PN]);
559 return 0;
560 }
561
562 return 0;
563 }
564
565 if (arg->rxsci == UNUSED_SCI)
566 return 0;
567
568 if (tb_msg[MACSEC_ATTR_RXSC_LIST]) {
569 struct nlattr *nla;
570 int rem;
571
572 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_RXSC_LIST], rem) {
573 struct nlattr *tb[MACSEC_RXSC_ATTR_MAX + 1];
574
575 err = nla_parse_nested(tb, MACSEC_RXSC_ATTR_MAX, nla,
576 sc_policy);
577 if (err < 0)
578 return 0;
579 if (!tb[MACSEC_RXSC_ATTR_SCI])
580 continue;
581 if (nla_get_u64(tb[MACSEC_RXSC_ATTR_SCI]) != arg->rxsci)
582 continue;
583 if (!tb[MACSEC_RXSC_ATTR_SA_LIST])
584 return 0;
585
586 nla_for_each_nested(nla, tb[MACSEC_RXSC_ATTR_SA_LIST],
587 rem) {
588 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
589
590 err = nla_parse_nested(tb_sa,
591 MACSEC_SA_ATTR_MAX, nla,
592 sa_policy);
593 if (err < 0)
594 continue;
595 if (!tb_sa[MACSEC_SA_ATTR_AN])
596 continue;
597 if (nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]) !=
598 arg->rxsa)
599 continue;
600 if (!tb_sa[MACSEC_SA_ATTR_PN])
601 return 0;
602 *arg->pn =
603 nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
604
605 return 0;
606 }
607
608 return 0;
609 }
610
611 return 0;
612 }
613
614 return 0;
615 }
616
617
nl_send_recv(struct nl_sock * sk,struct nl_msg * msg)618 static int nl_send_recv(struct nl_sock *sk, struct nl_msg *msg)
619 {
620 int ret;
621
622 ret = nl_send_auto_complete(sk, msg);
623 if (ret < 0) {
624 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to send: %d (%s)",
625 __func__, ret, nl_geterror(-ret));
626 return ret;
627 }
628
629 ret = nl_recvmsgs_default(sk);
630 if (ret < 0) {
631 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to recv: %d (%s)",
632 __func__, ret, nl_geterror(-ret));
633 }
634
635 return ret;
636 }
637
638
do_dump(struct macsec_drv_data * drv,u8 txsa,u64 rxsci,u8 rxsa,u32 * pn)639 static int do_dump(struct macsec_drv_data *drv, u8 txsa, u64 rxsci, u8 rxsa,
640 u32 *pn)
641 {
642 struct macsec_genl_ctx *ctx = &drv->ctx;
643 struct nl_msg *msg;
644 int ret = 1;
645
646 ctx->cb_arg.ifindex = drv->ifi;
647 ctx->cb_arg.rxsci = rxsci;
648 ctx->cb_arg.rxsa = rxsa;
649 ctx->cb_arg.txsa = txsa;
650 ctx->cb_arg.pn = pn;
651
652 msg = nlmsg_alloc();
653 if (!msg) {
654 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to alloc message",
655 __func__);
656 return 1;
657 }
658
659 if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ctx->macsec_genl_id, 0,
660 NLM_F_DUMP, MACSEC_CMD_GET_TXSC, 0)) {
661 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to put header",
662 __func__);
663 goto out_free_msg;
664 }
665
666 ret = nl_send_recv(ctx->sk, msg);
667 if (ret < 0)
668 wpa_printf(MSG_ERROR,
669 DRV_PREFIX "failed to communicate: %d (%s)",
670 ret, nl_geterror(-ret));
671
672 ctx->cb_arg.pn = NULL;
673
674 out_free_msg:
675 nlmsg_free(msg);
676 return ret;
677 }
678
679
680 /**
681 * macsec_drv_get_receive_lowest_pn - Get receive lowest PN
682 * @priv: Private driver interface data
683 * @sa: secure association
684 * Returns: 0 on success, -1 on failure (or if not supported)
685 */
macsec_drv_get_receive_lowest_pn(void * priv,struct receive_sa * sa)686 static int macsec_drv_get_receive_lowest_pn(void *priv, struct receive_sa *sa)
687 {
688 struct macsec_drv_data *drv = priv;
689 int err;
690
691 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s", __func__);
692
693 err = do_dump(drv, 0xff, mka_sci_u64(&sa->sc->sci), sa->an,
694 &sa->lowest_pn);
695 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: result %d", __func__,
696 sa->lowest_pn);
697
698 return err;
699 }
700
701
702 /**
703 * macsec_drv_set_receive_lowest_pn - Set receive lowest PN
704 * @priv: Private driver interface data
705 * @sa: secure association
706 * Returns: 0 on success, -1 on failure (or if not supported)
707 */
macsec_drv_set_receive_lowest_pn(void * priv,struct receive_sa * sa)708 static int macsec_drv_set_receive_lowest_pn(void *priv, struct receive_sa *sa)
709 {
710 struct macsec_drv_data *drv = priv;
711 struct macsec_genl_ctx *ctx = &drv->ctx;
712 struct nl_msg *msg;
713 struct nlattr *nest;
714 int ret = -1;
715
716 wpa_printf(MSG_DEBUG,
717 DRV_PREFIX "%s: set_receive_lowest_pn -> %d: %d",
718 drv->ifname, sa->an, sa->next_pn);
719
720 msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, drv->ifi);
721 if (!msg)
722 return ret;
723
724 if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
725 goto nla_put_failure;
726
727 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
728 if (!nest)
729 goto nla_put_failure;
730
731 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
732 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
733
734 nla_nest_end(msg, nest);
735
736 ret = nl_send_recv(ctx->sk, msg);
737 if (ret < 0) {
738 wpa_printf(MSG_ERROR,
739 DRV_PREFIX "failed to communicate: %d (%s)",
740 ret, nl_geterror(-ret));
741 }
742
743 nla_put_failure:
744 nlmsg_free(msg);
745 return ret;
746 }
747
748
749 /**
750 * macsec_drv_get_transmit_next_pn - Get transmit next PN
751 * @priv: Private driver interface data
752 * @sa: secure association
753 * Returns: 0 on success, -1 on failure (or if not supported)
754 */
macsec_drv_get_transmit_next_pn(void * priv,struct transmit_sa * sa)755 static int macsec_drv_get_transmit_next_pn(void *priv, struct transmit_sa *sa)
756 {
757 struct macsec_drv_data *drv = priv;
758 int err;
759
760 wpa_printf(MSG_DEBUG, "%s", __func__);
761
762 err = do_dump(drv, sa->an, UNUSED_SCI, 0xff, &sa->next_pn);
763 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: err %d result %d", __func__, err,
764 sa->next_pn);
765 return err;
766 }
767
768
769 /**
770 * macsec_drv_set_transmit_next_pn - Set transmit next pn
771 * @priv: Private driver interface data
772 * @sa: secure association
773 * Returns: 0 on success, -1 on failure (or if not supported)
774 */
macsec_drv_set_transmit_next_pn(void * priv,struct transmit_sa * sa)775 static int macsec_drv_set_transmit_next_pn(void *priv, struct transmit_sa *sa)
776 {
777 struct macsec_drv_data *drv = priv;
778 struct macsec_genl_ctx *ctx = &drv->ctx;
779 struct nl_msg *msg;
780 struct nlattr *nest;
781 int ret = -1;
782
783 wpa_printf(MSG_DEBUG, "%s -> %d: %d", __func__, sa->an, sa->next_pn);
784
785 msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, drv->ifi);
786 if (!msg)
787 return ret;
788
789 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
790 if (!nest)
791 goto nla_put_failure;
792
793 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
794 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
795
796 nla_nest_end(msg, nest);
797
798 ret = nl_send_recv(ctx->sk, msg);
799 if (ret < 0) {
800 wpa_printf(MSG_ERROR,
801 DRV_PREFIX "failed to communicate: %d (%s)",
802 ret, nl_geterror(-ret));
803 }
804
805 nla_put_failure:
806 nlmsg_free(msg);
807 return ret;
808 }
809
810
811 #define SCISTR MACSTR "::%hx"
812 #define SCI2STR(addr, port) MAC2STR(addr), htons(port)
813
814 /**
815 * macsec_drv_create_receive_sc - Create secure channel for receiving
816 * @priv: Private driver interface data
817 * @sc: secure channel
818 * @sci_addr: secure channel identifier - address
819 * @sci_port: secure channel identifier - port
820 * @conf_offset: confidentiality offset (0, 30, or 50)
821 * @validation: frame validation policy (0 = Disabled, 1 = Checked,
822 * 2 = Strict)
823 * Returns: 0 on success, -1 on failure (or if not supported)
824 */
macsec_drv_create_receive_sc(void * priv,struct receive_sc * sc,unsigned int conf_offset,int validation)825 static int macsec_drv_create_receive_sc(void *priv, struct receive_sc *sc,
826 unsigned int conf_offset,
827 int validation)
828 {
829 struct macsec_drv_data *drv = priv;
830 struct macsec_genl_ctx *ctx = &drv->ctx;
831 struct nl_msg *msg;
832 int ret = -1;
833
834 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: create_receive_sc -> " SCISTR
835 " (conf_offset=%u validation=%d)",
836 drv->ifname, SCI2STR(sc->sci.addr, sc->sci.port),
837 conf_offset, validation);
838
839 msg = msg_prepare(MACSEC_CMD_ADD_RXSC, ctx, drv->ifi);
840 if (!msg)
841 return ret;
842
843 if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
844 goto nla_put_failure;
845
846 ret = nl_send_recv(ctx->sk, msg);
847 if (ret < 0) {
848 wpa_printf(MSG_ERROR,
849 DRV_PREFIX "%s: failed to communicate: %d (%s)",
850 __func__, ret, nl_geterror(-ret));
851 }
852
853 nla_put_failure:
854 nlmsg_free(msg);
855 return ret;
856 }
857
858
859 /**
860 * macsec_drv_delete_receive_sc - Delete secure connection for receiving
861 * @priv: private driver interface data from init()
862 * @sc: secure channel
863 * Returns: 0 on success, -1 on failure
864 */
macsec_drv_delete_receive_sc(void * priv,struct receive_sc * sc)865 static int macsec_drv_delete_receive_sc(void *priv, struct receive_sc *sc)
866 {
867 struct macsec_drv_data *drv = priv;
868 struct macsec_genl_ctx *ctx = &drv->ctx;
869 struct nl_msg *msg;
870 int ret = -1;
871
872 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_receive_sc -> " SCISTR,
873 drv->ifname, SCI2STR(sc->sci.addr, sc->sci.port));
874
875 msg = msg_prepare(MACSEC_CMD_DEL_RXSC, ctx, drv->ifi);
876 if (!msg)
877 return ret;
878
879 if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
880 goto nla_put_failure;
881
882 ret = nl_send_recv(ctx->sk, msg);
883 if (ret < 0) {
884 wpa_printf(MSG_ERROR,
885 DRV_PREFIX "%s: failed to communicate: %d (%s)",
886 __func__, ret, nl_geterror(-ret));
887 }
888
889 nla_put_failure:
890 nlmsg_free(msg);
891 return ret;
892 }
893
894
895 /**
896 * macsec_drv_create_receive_sa - Create secure association for receive
897 * @priv: private driver interface data from init()
898 * @sa: secure association
899 * Returns: 0 on success, -1 on failure
900 */
macsec_drv_create_receive_sa(void * priv,struct receive_sa * sa)901 static int macsec_drv_create_receive_sa(void *priv, struct receive_sa *sa)
902 {
903 struct macsec_drv_data *drv = priv;
904 struct macsec_genl_ctx *ctx = &drv->ctx;
905 struct nl_msg *msg;
906 struct nlattr *nest;
907 int ret = -1;
908
909 wpa_printf(MSG_DEBUG,
910 DRV_PREFIX "%s: create_receive_sa -> %d on " SCISTR
911 " (enable_receive=%d next_pn=%u)",
912 drv->ifname, sa->an,
913 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port),
914 sa->enable_receive, sa->next_pn);
915 wpa_hexdump(MSG_DEBUG, DRV_PREFIX "SA keyid",
916 &sa->pkey->key_identifier,
917 sizeof(sa->pkey->key_identifier));
918 wpa_hexdump_key(MSG_DEBUG, DRV_PREFIX "SA key",
919 sa->pkey->key, sa->pkey->key_len);
920
921 msg = msg_prepare(MACSEC_CMD_ADD_RXSA, ctx, drv->ifi);
922 if (!msg)
923 return ret;
924
925 if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
926 goto nla_put_failure;
927
928 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
929 if (!nest)
930 goto nla_put_failure;
931
932 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
933 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_receive);
934 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
935 NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
936 &sa->pkey->key_identifier);
937 NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
938
939 nla_nest_end(msg, nest);
940
941 ret = nl_send_recv(ctx->sk, msg);
942 if (ret < 0) {
943 wpa_printf(MSG_ERROR,
944 DRV_PREFIX "%s: failed to communicate: %d (%s)",
945 __func__, ret, nl_geterror(-ret));
946 }
947
948 nla_put_failure:
949 nlmsg_free(msg);
950 return ret;
951 }
952
953
954 /**
955 * macsec_drv_delete_receive_sa - Delete secure association for receive
956 * @priv: private driver interface data from init()
957 * @sa: secure association
958 * Returns: 0 on success, -1 on failure
959 */
macsec_drv_delete_receive_sa(void * priv,struct receive_sa * sa)960 static int macsec_drv_delete_receive_sa(void *priv, struct receive_sa *sa)
961 {
962 struct macsec_drv_data *drv = priv;
963 struct macsec_genl_ctx *ctx = &drv->ctx;
964 struct nl_msg *msg;
965 struct nlattr *nest;
966 int ret = -1;
967
968 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_receive_sa -> %d on "
969 SCISTR, drv->ifname, sa->an,
970 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
971
972 msg = msg_prepare(MACSEC_CMD_DEL_RXSA, ctx, drv->ifi);
973 if (!msg)
974 return ret;
975
976 if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
977 goto nla_put_failure;
978
979 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
980 if (!nest)
981 goto nla_put_failure;
982
983 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
984
985 nla_nest_end(msg, nest);
986
987 ret = nl_send_recv(ctx->sk, msg);
988 if (ret < 0) {
989 wpa_printf(MSG_ERROR,
990 DRV_PREFIX "%s: failed to communicate: %d (%s)",
991 __func__, ret, nl_geterror(-ret));
992 }
993
994 nla_put_failure:
995 nlmsg_free(msg);
996 return ret;
997 }
998
999
set_active_rx_sa(const struct macsec_genl_ctx * ctx,int ifindex,u64 sci,unsigned char an,bool state)1000 static int set_active_rx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
1001 u64 sci, unsigned char an, bool state)
1002 {
1003 struct nl_msg *msg;
1004 struct nlattr *nest;
1005 int ret = -1;
1006
1007 msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, ifindex);
1008 if (!msg)
1009 return ret;
1010
1011 if (nla_put_rxsc_config(msg, sci))
1012 goto nla_put_failure;
1013
1014 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1015 if (!nest)
1016 goto nla_put_failure;
1017
1018 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
1019 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
1020
1021 nla_nest_end(msg, nest);
1022
1023 ret = nl_send_recv(ctx->sk, msg);
1024 if (ret < 0)
1025 wpa_printf(MSG_ERROR,
1026 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1027 __func__, ret, nl_geterror(-ret));
1028
1029 nla_put_failure:
1030 nlmsg_free(msg);
1031 return ret;
1032 }
1033
1034
1035 /**
1036 * macsec_drv_enable_receive_sa - Enable the SA for receive
1037 * @priv: private driver interface data from init()
1038 * @sa: secure association
1039 * Returns: 0 on success, -1 on failure
1040 */
macsec_drv_enable_receive_sa(void * priv,struct receive_sa * sa)1041 static int macsec_drv_enable_receive_sa(void *priv, struct receive_sa *sa)
1042 {
1043 struct macsec_drv_data *drv = priv;
1044 struct macsec_genl_ctx *ctx = &drv->ctx;
1045
1046 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: enable_receive_sa -> %d on "
1047 SCISTR, drv->ifname, sa->an,
1048 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1049
1050 return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
1051 sa->an, true);
1052 }
1053
1054
1055 /**
1056 * macsec_drv_disable_receive_sa - Disable SA for receive
1057 * @priv: private driver interface data from init()
1058 * @sa: secure association
1059 * Returns: 0 on success, -1 on failure
1060 */
macsec_drv_disable_receive_sa(void * priv,struct receive_sa * sa)1061 static int macsec_drv_disable_receive_sa(void *priv, struct receive_sa *sa)
1062 {
1063 struct macsec_drv_data *drv = priv;
1064 struct macsec_genl_ctx *ctx = &drv->ctx;
1065
1066 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: disable_receive_sa -> %d on "
1067 SCISTR, drv->ifname, sa->an,
1068 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1069
1070 return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
1071 sa->an, false);
1072 }
1073
1074
lookup_sc(struct nl_cache * cache,int parent,u64 sci,u64 cs)1075 static struct rtnl_link * lookup_sc(struct nl_cache *cache, int parent, u64 sci,
1076 u64 cs)
1077 {
1078 struct rtnl_link *needle;
1079 void *match;
1080
1081 needle = rtnl_link_macsec_alloc();
1082 if (!needle)
1083 return NULL;
1084
1085 rtnl_link_set_link(needle, parent);
1086 rtnl_link_macsec_set_sci(needle, sci);
1087 if (cs)
1088 rtnl_link_macsec_set_cipher_suite(needle, cs);
1089
1090 match = nl_cache_find(cache, (struct nl_object *) needle);
1091 rtnl_link_put(needle);
1092
1093 return (struct rtnl_link *) match;
1094 }
1095
1096
1097 /**
1098 * macsec_drv_create_transmit_sc - Create secure connection for transmit
1099 * @priv: private driver interface data from init()
1100 * @sc: secure channel
1101 * @conf_offset: confidentiality offset
1102 * Returns: 0 on success, -1 on failure
1103 */
macsec_drv_create_transmit_sc(void * priv,struct transmit_sc * sc,unsigned int conf_offset)1104 static int macsec_drv_create_transmit_sc(
1105 void *priv, struct transmit_sc *sc,
1106 unsigned int conf_offset)
1107 {
1108 struct macsec_drv_data *drv = priv;
1109 struct rtnl_link *link;
1110 char *ifname;
1111 u64 sci;
1112 int err;
1113 u64 cs = 0;
1114
1115 wpa_printf(MSG_DEBUG, DRV_PREFIX
1116 "%s: create_transmit_sc -> " SCISTR " (conf_offset=%d)",
1117 drv->common.ifname, SCI2STR(sc->sci.addr, sc->sci.port),
1118 conf_offset);
1119
1120 if (!drv->sk) {
1121 wpa_printf(MSG_ERROR, DRV_PREFIX "NULL rtnl socket");
1122 return -1;
1123 }
1124
1125 link = rtnl_link_macsec_alloc();
1126 if (!link) {
1127 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
1128 return -1;
1129 }
1130
1131 rtnl_link_set_link(link, drv->parent_ifi);
1132
1133 sci = mka_sci_u64(&sc->sci);
1134 rtnl_link_macsec_set_sci(link, sci);
1135
1136 drv->created_link = true;
1137
1138 if (drv->cipher_suite_set) {
1139 cs = drv->cipher_suite;
1140 drv->cipher_suite_set = false;
1141 rtnl_link_macsec_set_cipher_suite(link, cs);
1142 }
1143
1144 err = rtnl_link_add(drv->sk, link, NLM_F_CREATE);
1145 if (err == -NLE_BUSY) {
1146 wpa_printf(MSG_INFO,
1147 DRV_PREFIX "link already exists, using it");
1148 drv->created_link = false;
1149 } else if (err < 0) {
1150 rtnl_link_put(link);
1151 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't create link: err %d",
1152 err);
1153 return err;
1154 }
1155
1156 rtnl_link_put(link);
1157
1158 nl_cache_refill(drv->sk, drv->link_cache);
1159 link = lookup_sc(drv->link_cache, drv->parent_ifi, sci, cs);
1160 if (!link) {
1161 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't find link");
1162 return -1;
1163 }
1164
1165 drv->ifi = rtnl_link_get_ifindex(link);
1166 ifname = rtnl_link_get_name(link);
1167 wpa_printf(MSG_DEBUG,
1168 DRV_PREFIX "%s: create_transmit_sc: ifi=%d ifname=%s",
1169 drv->common.ifname, drv->ifi, ifname);
1170 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1171 rtnl_link_put(link);
1172
1173 drv->link = rtnl_link_macsec_alloc();
1174 if (!drv->link) {
1175 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
1176 return -1;
1177 }
1178
1179 rtnl_link_set_name(drv->link, drv->ifname);
1180
1181 /* In case some settings have already been done but we couldn't apply
1182 * them. */
1183 return try_commit(drv);
1184 }
1185
1186
1187 /**
1188 * macsec_drv_delete_transmit_sc - Delete secure connection for transmit
1189 * @priv: private driver interface data from init()
1190 * @sc: secure channel
1191 * Returns: 0 on success, -1 on failure
1192 */
macsec_drv_delete_transmit_sc(void * priv,struct transmit_sc * sc)1193 static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc)
1194 {
1195 struct macsec_drv_data *drv = priv;
1196 int err;
1197
1198 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_transmit_sc -> " SCISTR,
1199 drv->ifname, SCI2STR(sc->sci.addr, sc->sci.port));
1200
1201 if (!drv->sk)
1202 return 0;
1203
1204 if (!drv->created_link) {
1205 rtnl_link_put(drv->link);
1206 drv->link = NULL;
1207 wpa_printf(MSG_DEBUG, DRV_PREFIX
1208 "we didn't create the link, leave it alone");
1209 return 0;
1210 }
1211
1212 err = rtnl_link_delete(drv->sk, drv->link);
1213 if (err < 0)
1214 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't delete link");
1215 rtnl_link_put(drv->link);
1216 drv->link = NULL;
1217
1218 return err;
1219 }
1220
1221
1222 /**
1223 * macsec_drv_create_transmit_sa - Create secure association for transmit
1224 * @priv: private driver interface data from init()
1225 * @sa: secure association
1226 * Returns: 0 on success, -1 on failure
1227 */
macsec_drv_create_transmit_sa(void * priv,struct transmit_sa * sa)1228 static int macsec_drv_create_transmit_sa(void *priv, struct transmit_sa *sa)
1229 {
1230 struct macsec_drv_data *drv = priv;
1231 struct macsec_genl_ctx *ctx = &drv->ctx;
1232 struct nl_msg *msg;
1233 struct nlattr *nest;
1234 int ret = -1;
1235
1236 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: create_transmit_sa -> %d on "
1237 SCISTR " (enable_transmit=%d next_pn=%u)",
1238 drv->ifname, sa->an,
1239 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port),
1240 sa->enable_transmit, sa->next_pn);
1241 wpa_hexdump(MSG_DEBUG, DRV_PREFIX "SA keyid",
1242 &sa->pkey->key_identifier,
1243 sizeof(sa->pkey->key_identifier));
1244 wpa_hexdump_key(MSG_DEBUG, DRV_PREFIX "SA key",
1245 sa->pkey->key, sa->pkey->key_len);
1246
1247 msg = msg_prepare(MACSEC_CMD_ADD_TXSA, ctx, drv->ifi);
1248 if (!msg)
1249 return ret;
1250
1251 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1252 if (!nest)
1253 goto nla_put_failure;
1254
1255 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1256 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
1257 NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
1258 &sa->pkey->key_identifier);
1259 NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
1260 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_transmit);
1261
1262 nla_nest_end(msg, nest);
1263
1264 ret = nl_send_recv(ctx->sk, msg);
1265 if (ret < 0) {
1266 wpa_printf(MSG_ERROR,
1267 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1268 __func__, ret, nl_geterror(-ret));
1269 }
1270
1271 nla_put_failure:
1272 nlmsg_free(msg);
1273 return ret;
1274 }
1275
1276
1277 /**
1278 * macsec_drv_delete_transmit_sa - Delete secure association for transmit
1279 * @priv: private driver interface data from init()
1280 * @sa: secure association
1281 * Returns: 0 on success, -1 on failure
1282 */
macsec_drv_delete_transmit_sa(void * priv,struct transmit_sa * sa)1283 static int macsec_drv_delete_transmit_sa(void *priv, struct transmit_sa *sa)
1284 {
1285 struct macsec_drv_data *drv = priv;
1286 struct macsec_genl_ctx *ctx = &drv->ctx;
1287 struct nl_msg *msg;
1288 struct nlattr *nest;
1289 int ret = -1;
1290
1291 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_transmit_sa -> %d on "
1292 SCISTR, drv->ifname, sa->an,
1293 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1294
1295 msg = msg_prepare(MACSEC_CMD_DEL_TXSA, ctx, drv->ifi);
1296 if (!msg)
1297 return ret;
1298
1299 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1300 if (!nest)
1301 goto nla_put_failure;
1302
1303 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1304
1305 nla_nest_end(msg, nest);
1306
1307 ret = nl_send_recv(ctx->sk, msg);
1308 if (ret < 0) {
1309 wpa_printf(MSG_ERROR,
1310 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1311 __func__, ret, nl_geterror(-ret));
1312 }
1313
1314 nla_put_failure:
1315 nlmsg_free(msg);
1316 return ret;
1317 }
1318
1319
set_active_tx_sa(const struct macsec_genl_ctx * ctx,int ifindex,unsigned char an,bool state)1320 static int set_active_tx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
1321 unsigned char an, bool state)
1322 {
1323 struct nl_msg *msg;
1324 struct nlattr *nest;
1325 int ret = -1;
1326
1327 msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, ifindex);
1328 if (!msg)
1329 return ret;
1330
1331 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1332 if (!nest)
1333 goto nla_put_failure;
1334
1335 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
1336 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
1337
1338 nla_nest_end(msg, nest);
1339
1340 ret = nl_send_recv(ctx->sk, msg);
1341 if (ret < 0) {
1342 wpa_printf(MSG_ERROR,
1343 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1344 __func__, ret, nl_geterror(-ret));
1345 }
1346
1347 nla_put_failure:
1348 nlmsg_free(msg);
1349 return ret;
1350 }
1351
1352
1353 /**
1354 * macsec_drv_enable_transmit_sa - Enable SA for transmit
1355 * @priv: private driver interface data from init()
1356 * @sa: secure association
1357 * Returns: 0 on success, -1 on failure
1358 */
macsec_drv_enable_transmit_sa(void * priv,struct transmit_sa * sa)1359 static int macsec_drv_enable_transmit_sa(void *priv, struct transmit_sa *sa)
1360 {
1361 struct macsec_drv_data *drv = priv;
1362 struct macsec_genl_ctx *ctx = &drv->ctx;
1363 int ret;
1364
1365 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: enable_transmit_sa -> %d on "
1366 SCISTR, drv->ifname, sa->an,
1367 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1368
1369 ret = set_active_tx_sa(ctx, drv->ifi, sa->an, true);
1370 if (ret < 0) {
1371 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to enable txsa");
1372 return ret;
1373 }
1374
1375 drv->encoding_sa_set = true;
1376 drv->encoding_sa = sa->an;
1377
1378 return try_commit(drv);
1379 }
1380
1381
1382 /**
1383 * macsec_drv_disable_transmit_sa - Disable SA for transmit
1384 * @priv: private driver interface data from init()
1385 * @sa: secure association
1386 * Returns: 0 on success, -1 on failure
1387 */
macsec_drv_disable_transmit_sa(void * priv,struct transmit_sa * sa)1388 static int macsec_drv_disable_transmit_sa(void *priv, struct transmit_sa *sa)
1389 {
1390 struct macsec_drv_data *drv = priv;
1391 struct macsec_genl_ctx *ctx = &drv->ctx;
1392
1393 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: disable_transmit_sa -> %d on "
1394 SCISTR, drv->ifname, sa->an,
1395 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1396
1397 return set_active_tx_sa(ctx, drv->ifi, sa->an, false);
1398 }
1399
1400
macsec_drv_status(void * priv,char * buf,size_t buflen)1401 static int macsec_drv_status(void *priv, char *buf, size_t buflen)
1402 {
1403 struct macsec_drv_data *drv = priv;
1404 int res;
1405 char *pos, *end;
1406
1407 pos = buf;
1408 end = buf + buflen;
1409
1410 res = os_snprintf(pos, end - pos,
1411 "ifname=%s\n"
1412 "ifi=%d\n"
1413 "parent_ifname=%s\n"
1414 "parent_ifi=%d\n",
1415 drv->common.ifname, drv->ifi,
1416 drv->ifname, drv->parent_ifi);
1417 if (os_snprintf_error(end - pos, res))
1418 return pos - buf;
1419 pos += res;
1420
1421 return pos - buf;
1422 }
1423
1424
1425 #ifdef __linux__
1426
macsec_drv_handle_data(void * ctx,unsigned char * buf,size_t len)1427 static void macsec_drv_handle_data(void *ctx, unsigned char *buf, size_t len)
1428 {
1429 #ifdef HOSTAPD
1430 struct ieee8023_hdr *hdr;
1431 u8 *pos, *sa;
1432 size_t left;
1433 union wpa_event_data event;
1434
1435 /* must contain at least ieee8023_hdr 6 byte source, 6 byte dest,
1436 * 2 byte ethertype */
1437 if (len < 14) {
1438 wpa_printf(MSG_MSGDUMP, "%s: too short (%lu)",
1439 __func__, (unsigned long) len);
1440 return;
1441 }
1442
1443 hdr = (struct ieee8023_hdr *) buf;
1444
1445 switch (ntohs(hdr->ethertype)) {
1446 case ETH_P_PAE:
1447 wpa_printf(MSG_MSGDUMP, "Received EAPOL packet");
1448 sa = hdr->src;
1449 os_memset(&event, 0, sizeof(event));
1450 event.new_sta.addr = sa;
1451 wpa_supplicant_event(ctx, EVENT_NEW_STA, &event);
1452
1453 pos = (u8 *) (hdr + 1);
1454 left = len - sizeof(*hdr);
1455 drv_event_eapol_rx(ctx, sa, pos, left);
1456 break;
1457
1458 default:
1459 wpa_printf(MSG_DEBUG, "Unknown ethertype 0x%04x in data frame",
1460 ntohs(hdr->ethertype));
1461 break;
1462 }
1463 #endif /* HOSTAPD */
1464 }
1465
1466
macsec_drv_handle_read(int sock,void * eloop_ctx,void * sock_ctx)1467 static void macsec_drv_handle_read(int sock, void *eloop_ctx, void *sock_ctx)
1468 {
1469 int len;
1470 unsigned char buf[3000];
1471
1472 len = recv(sock, buf, sizeof(buf), 0);
1473 if (len < 0) {
1474 wpa_printf(MSG_ERROR, "macsec_linux: recv: %s",
1475 strerror(errno));
1476 return;
1477 }
1478
1479 macsec_drv_handle_data(eloop_ctx, buf, len);
1480 }
1481
1482 #endif /* __linux__ */
1483
1484
macsec_drv_init_sockets(struct macsec_drv_data * drv,u8 * own_addr)1485 static int macsec_drv_init_sockets(struct macsec_drv_data *drv, u8 *own_addr)
1486 {
1487 #ifdef __linux__
1488 struct ifreq ifr;
1489 struct sockaddr_ll addr;
1490
1491 drv->common.sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));
1492 if (drv->common.sock < 0) {
1493 wpa_printf(MSG_ERROR, "socket[PF_PACKET,SOCK_RAW]: %s",
1494 strerror(errno));
1495 return -1;
1496 }
1497
1498 if (eloop_register_read_sock(drv->common.sock, macsec_drv_handle_read,
1499 drv->common.ctx, NULL)) {
1500 wpa_printf(MSG_INFO, "Could not register read socket");
1501 return -1;
1502 }
1503
1504 os_memset(&ifr, 0, sizeof(ifr));
1505 os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name));
1506 if (ioctl(drv->common.sock, SIOCGIFINDEX, &ifr) != 0) {
1507 wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s",
1508 strerror(errno));
1509 return -1;
1510 }
1511
1512 os_memset(&addr, 0, sizeof(addr));
1513 addr.sll_family = AF_PACKET;
1514 addr.sll_ifindex = ifr.ifr_ifindex;
1515 wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",
1516 addr.sll_ifindex);
1517
1518 if (bind(drv->common.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
1519 {
1520 wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
1521 return -1;
1522 }
1523
1524 /* filter multicast address */
1525 if (wired_multicast_membership(drv->common.sock, ifr.ifr_ifindex,
1526 pae_group_addr, 1) < 0) {
1527 wpa_printf(MSG_ERROR, "wired: Failed to add multicast group "
1528 "membership");
1529 return -1;
1530 }
1531
1532 os_memset(&ifr, 0, sizeof(ifr));
1533 os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name));
1534 if (ioctl(drv->common.sock, SIOCGIFHWADDR, &ifr) != 0) {
1535 wpa_printf(MSG_ERROR, "ioctl(SIOCGIFHWADDR): %s",
1536 strerror(errno));
1537 return -1;
1538 }
1539
1540 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
1541 wpa_printf(MSG_INFO, "Invalid HW-addr family 0x%04x",
1542 ifr.ifr_hwaddr.sa_family);
1543 return -1;
1544 }
1545 os_memcpy(own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
1546
1547 return 0;
1548 #else /* __linux__ */
1549 return -1;
1550 #endif /* __linux__ */
1551 }
1552
1553
macsec_drv_hapd_init(struct hostapd_data * hapd,struct wpa_init_params * params)1554 static void * macsec_drv_hapd_init(struct hostapd_data *hapd,
1555 struct wpa_init_params *params)
1556 {
1557 struct macsec_drv_data *drv;
1558
1559 drv = os_zalloc(sizeof(struct macsec_drv_data));
1560 if (drv == NULL) {
1561 wpa_printf(MSG_INFO,
1562 "Could not allocate memory for wired driver data");
1563 return NULL;
1564 }
1565
1566 drv->common.ctx = hapd;
1567 os_strlcpy(drv->common.ifname, params->ifname,
1568 sizeof(drv->common.ifname));
1569 drv->use_pae_group_addr = params->use_pae_group_addr;
1570
1571 if (macsec_drv_init_sockets(drv, params->own_addr)) {
1572 os_free(drv);
1573 return NULL;
1574 }
1575
1576 return drv;
1577 }
1578
1579
macsec_drv_hapd_deinit(void * priv)1580 static void macsec_drv_hapd_deinit(void *priv)
1581 {
1582 struct macsec_drv_data *drv = priv;
1583
1584 if (drv->common.sock >= 0) {
1585 eloop_unregister_read_sock(drv->common.sock);
1586 close(drv->common.sock);
1587 }
1588
1589 os_free(drv);
1590 }
1591
1592
macsec_drv_send_eapol(void * priv,const u8 * addr,const u8 * data,size_t data_len,int encrypt,const u8 * own_addr,u32 flags)1593 static int macsec_drv_send_eapol(void *priv, const u8 *addr,
1594 const u8 *data, size_t data_len, int encrypt,
1595 const u8 *own_addr, u32 flags)
1596 {
1597 struct macsec_drv_data *drv = priv;
1598 struct ieee8023_hdr *hdr;
1599 size_t len;
1600 u8 *pos;
1601 int res;
1602
1603 len = sizeof(*hdr) + data_len;
1604 hdr = os_zalloc(len);
1605 if (hdr == NULL) {
1606 wpa_printf(MSG_INFO,
1607 "%s: malloc() failed (len=%lu)",
1608 __func__, (unsigned long) len);
1609 return -1;
1610 }
1611
1612 os_memcpy(hdr->dest, drv->use_pae_group_addr ? pae_group_addr : addr,
1613 ETH_ALEN);
1614 os_memcpy(hdr->src, own_addr, ETH_ALEN);
1615 hdr->ethertype = htons(ETH_P_PAE);
1616
1617 pos = (u8 *) (hdr + 1);
1618 os_memcpy(pos, data, data_len);
1619
1620 res = send(drv->common.sock, (u8 *) hdr, len, 0);
1621 os_free(hdr);
1622
1623 if (res < 0) {
1624 wpa_printf(MSG_ERROR,
1625 "%s: packet len: %lu - failed: send: %s",
1626 __func__, (unsigned long) len, strerror(errno));
1627 }
1628
1629 return res;
1630 }
1631
1632
1633 const struct wpa_driver_ops wpa_driver_macsec_linux_ops = {
1634 .name = "macsec_linux",
1635 .desc = "MACsec Ethernet driver for Linux",
1636 .get_ssid = driver_wired_get_ssid,
1637 .get_bssid = driver_wired_get_bssid,
1638 .get_capa = driver_wired_get_capa,
1639 .init = macsec_drv_wpa_init,
1640 .deinit = macsec_drv_wpa_deinit,
1641 .hapd_init = macsec_drv_hapd_init,
1642 .hapd_deinit = macsec_drv_hapd_deinit,
1643 .hapd_send_eapol = macsec_drv_send_eapol,
1644
1645 .macsec_init = macsec_drv_macsec_init,
1646 .macsec_deinit = macsec_drv_macsec_deinit,
1647 .macsec_get_capability = macsec_drv_get_capability,
1648 .enable_protect_frames = macsec_drv_enable_protect_frames,
1649 .enable_encrypt = macsec_drv_enable_encrypt,
1650 .set_replay_protect = macsec_drv_set_replay_protect,
1651 .set_current_cipher_suite = macsec_drv_set_current_cipher_suite,
1652 .enable_controlled_port = macsec_drv_enable_controlled_port,
1653 .get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn,
1654 .set_receive_lowest_pn = macsec_drv_set_receive_lowest_pn,
1655 .get_transmit_next_pn = macsec_drv_get_transmit_next_pn,
1656 .set_transmit_next_pn = macsec_drv_set_transmit_next_pn,
1657 .create_receive_sc = macsec_drv_create_receive_sc,
1658 .delete_receive_sc = macsec_drv_delete_receive_sc,
1659 .create_receive_sa = macsec_drv_create_receive_sa,
1660 .delete_receive_sa = macsec_drv_delete_receive_sa,
1661 .enable_receive_sa = macsec_drv_enable_receive_sa,
1662 .disable_receive_sa = macsec_drv_disable_receive_sa,
1663 .create_transmit_sc = macsec_drv_create_transmit_sc,
1664 .delete_transmit_sc = macsec_drv_delete_transmit_sc,
1665 .create_transmit_sa = macsec_drv_create_transmit_sa,
1666 .delete_transmit_sa = macsec_drv_delete_transmit_sa,
1667 .enable_transmit_sa = macsec_drv_enable_transmit_sa,
1668 .disable_transmit_sa = macsec_drv_disable_transmit_sa,
1669
1670 .status = macsec_drv_status,
1671 };
1672