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