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 drv->created_link = false;
1204 return err;
1205 }
1206
1207 rtnl_link_put(link);
1208
1209 nl_cache_refill(drv->sk, drv->link_cache);
1210 link = lookup_sc(drv->link_cache, drv->parent_ifi, sci, cs);
1211 if (!link) {
1212 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't find link");
1213 return -1;
1214 }
1215
1216 drv->ifi = rtnl_link_get_ifindex(link);
1217 ifname = rtnl_link_get_name(link);
1218 wpa_printf(MSG_DEBUG,
1219 DRV_PREFIX "%s: create_transmit_sc: ifi=%d ifname=%s",
1220 drv->common.ifname, drv->ifi, ifname);
1221 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1222 rtnl_link_put(link);
1223
1224 drv->link = rtnl_link_macsec_alloc();
1225 if (!drv->link) {
1226 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
1227 drv->created_link = false;
1228 return -1;
1229 }
1230
1231 rtnl_link_set_name(drv->link, drv->ifname);
1232
1233 /* In case some settings have already been done but we couldn't apply
1234 * them. */
1235 return try_commit(drv);
1236 }
1237
1238
1239 /**
1240 * macsec_drv_delete_transmit_sc - Delete secure connection for transmit
1241 * @priv: private driver interface data from init()
1242 * @sc: secure channel
1243 * Returns: 0 on success, -1 on failure
1244 */
macsec_drv_delete_transmit_sc(void * priv,struct transmit_sc * sc)1245 static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc)
1246 {
1247 struct macsec_drv_data *drv = priv;
1248 int err;
1249
1250 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_transmit_sc -> " SCISTR,
1251 drv->ifname, SCI2STR(sc->sci.addr, sc->sci.port));
1252
1253 if (!drv->sk)
1254 return 0;
1255
1256 if (!drv->created_link) {
1257 rtnl_link_put(drv->link);
1258 drv->link = NULL;
1259 wpa_printf(MSG_DEBUG, DRV_PREFIX
1260 "we didn't create the link, leave it alone");
1261 return 0;
1262 }
1263
1264 if (!drv->link) {
1265 wpa_printf(MSG_ERROR, DRV_PREFIX "no link to delete");
1266 return -1;
1267 }
1268
1269 err = rtnl_link_delete(drv->sk, drv->link);
1270 if (err < 0)
1271 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't delete link");
1272 rtnl_link_put(drv->link);
1273 drv->link = NULL;
1274
1275 return err;
1276 }
1277
1278
1279 /**
1280 * macsec_drv_create_transmit_sa - Create secure association for transmit
1281 * @priv: private driver interface data from init()
1282 * @sa: secure association
1283 * Returns: 0 on success, -1 on failure
1284 */
macsec_drv_create_transmit_sa(void * priv,struct transmit_sa * sa)1285 static int macsec_drv_create_transmit_sa(void *priv, struct transmit_sa *sa)
1286 {
1287 struct macsec_drv_data *drv = priv;
1288 struct macsec_genl_ctx *ctx = &drv->ctx;
1289 struct nl_msg *msg;
1290 struct nlattr *nest;
1291 int ret = -1;
1292
1293 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: create_transmit_sa -> %d on "
1294 SCISTR " (enable_transmit=%d next_pn=%u)",
1295 drv->ifname, sa->an,
1296 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port),
1297 sa->enable_transmit, sa->next_pn);
1298 wpa_hexdump(MSG_DEBUG, DRV_PREFIX "SA keyid",
1299 &sa->pkey->key_identifier,
1300 sizeof(sa->pkey->key_identifier));
1301 wpa_hexdump_key(MSG_DEBUG, DRV_PREFIX "SA key",
1302 sa->pkey->key, sa->pkey->key_len);
1303
1304 msg = msg_prepare(MACSEC_CMD_ADD_TXSA, ctx, drv->ifi);
1305 if (!msg)
1306 return ret;
1307
1308 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1309 if (!nest)
1310 goto nla_put_failure;
1311
1312 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1313 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
1314 NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
1315 &sa->pkey->key_identifier);
1316 NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
1317 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_transmit);
1318
1319 nla_nest_end(msg, nest);
1320
1321 ret = nl_send_recv(ctx->sk, msg);
1322 if (ret < 0) {
1323 wpa_printf(MSG_ERROR,
1324 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1325 __func__, ret, nl_geterror(-ret));
1326 }
1327
1328 nla_put_failure:
1329 nlmsg_free(msg);
1330 return ret;
1331 }
1332
1333
1334 /**
1335 * macsec_drv_delete_transmit_sa - Delete secure association for transmit
1336 * @priv: private driver interface data from init()
1337 * @sa: secure association
1338 * Returns: 0 on success, -1 on failure
1339 */
macsec_drv_delete_transmit_sa(void * priv,struct transmit_sa * sa)1340 static int macsec_drv_delete_transmit_sa(void *priv, struct transmit_sa *sa)
1341 {
1342 struct macsec_drv_data *drv = priv;
1343 struct macsec_genl_ctx *ctx = &drv->ctx;
1344 struct nl_msg *msg;
1345 struct nlattr *nest;
1346 int ret = -1;
1347
1348 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: delete_transmit_sa -> %d on "
1349 SCISTR, drv->ifname, sa->an,
1350 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1351
1352 msg = msg_prepare(MACSEC_CMD_DEL_TXSA, ctx, drv->ifi);
1353 if (!msg)
1354 return ret;
1355
1356 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1357 if (!nest)
1358 goto nla_put_failure;
1359
1360 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1361
1362 nla_nest_end(msg, nest);
1363
1364 ret = nl_send_recv(ctx->sk, msg);
1365 if (ret < 0) {
1366 wpa_printf(MSG_ERROR,
1367 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1368 __func__, ret, nl_geterror(-ret));
1369 }
1370
1371 nla_put_failure:
1372 nlmsg_free(msg);
1373 return ret;
1374 }
1375
1376
set_active_tx_sa(const struct macsec_genl_ctx * ctx,int ifindex,unsigned char an,bool state)1377 static int set_active_tx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
1378 unsigned char an, bool state)
1379 {
1380 struct nl_msg *msg;
1381 struct nlattr *nest;
1382 int ret = -1;
1383
1384 msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, ifindex);
1385 if (!msg)
1386 return ret;
1387
1388 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1389 if (!nest)
1390 goto nla_put_failure;
1391
1392 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
1393 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
1394
1395 nla_nest_end(msg, nest);
1396
1397 ret = nl_send_recv(ctx->sk, msg);
1398 if (ret < 0) {
1399 wpa_printf(MSG_ERROR,
1400 DRV_PREFIX "%s: failed to communicate: %d (%s)",
1401 __func__, ret, nl_geterror(-ret));
1402 }
1403
1404 nla_put_failure:
1405 nlmsg_free(msg);
1406 return ret;
1407 }
1408
1409
1410 /**
1411 * macsec_drv_enable_transmit_sa - Enable SA for transmit
1412 * @priv: private driver interface data from init()
1413 * @sa: secure association
1414 * Returns: 0 on success, -1 on failure
1415 */
macsec_drv_enable_transmit_sa(void * priv,struct transmit_sa * sa)1416 static int macsec_drv_enable_transmit_sa(void *priv, struct transmit_sa *sa)
1417 {
1418 struct macsec_drv_data *drv = priv;
1419 struct macsec_genl_ctx *ctx = &drv->ctx;
1420 int ret;
1421
1422 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: enable_transmit_sa -> %d on "
1423 SCISTR, drv->ifname, sa->an,
1424 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1425
1426 ret = set_active_tx_sa(ctx, drv->ifi, sa->an, true);
1427 if (ret < 0) {
1428 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to enable txsa");
1429 return ret;
1430 }
1431
1432 drv->encoding_sa_set = true;
1433 drv->encoding_sa = sa->an;
1434
1435 return try_commit(drv);
1436 }
1437
1438
1439 /**
1440 * macsec_drv_disable_transmit_sa - Disable SA for transmit
1441 * @priv: private driver interface data from init()
1442 * @sa: secure association
1443 * Returns: 0 on success, -1 on failure
1444 */
macsec_drv_disable_transmit_sa(void * priv,struct transmit_sa * sa)1445 static int macsec_drv_disable_transmit_sa(void *priv, struct transmit_sa *sa)
1446 {
1447 struct macsec_drv_data *drv = priv;
1448 struct macsec_genl_ctx *ctx = &drv->ctx;
1449
1450 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: disable_transmit_sa -> %d on "
1451 SCISTR, drv->ifname, sa->an,
1452 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
1453
1454 return set_active_tx_sa(ctx, drv->ifi, sa->an, false);
1455 }
1456
1457
macsec_drv_status(void * priv,char * buf,size_t buflen)1458 static int macsec_drv_status(void *priv, char *buf, size_t buflen)
1459 {
1460 struct macsec_drv_data *drv = priv;
1461 int res;
1462 char *pos, *end;
1463
1464 pos = buf;
1465 end = buf + buflen;
1466
1467 res = os_snprintf(pos, end - pos,
1468 "ifname=%s\n"
1469 "ifi=%d\n"
1470 "parent_ifname=%s\n"
1471 "parent_ifi=%d\n",
1472 drv->common.ifname, drv->ifi,
1473 drv->ifname, drv->parent_ifi);
1474 if (os_snprintf_error(end - pos, res))
1475 return pos - buf;
1476 pos += res;
1477
1478 return pos - buf;
1479 }
1480
1481
1482 #ifdef __linux__
1483
macsec_drv_handle_data(void * ctx,unsigned char * buf,size_t len)1484 static void macsec_drv_handle_data(void *ctx, unsigned char *buf, size_t len)
1485 {
1486 #ifdef HOSTAPD
1487 struct ieee8023_hdr *hdr;
1488 u8 *pos, *sa;
1489 size_t left;
1490 union wpa_event_data event;
1491
1492 /* must contain at least ieee8023_hdr 6 byte source, 6 byte dest,
1493 * 2 byte ethertype */
1494 if (len < 14) {
1495 wpa_printf(MSG_MSGDUMP, "%s: too short (%lu)",
1496 __func__, (unsigned long) len);
1497 return;
1498 }
1499
1500 hdr = (struct ieee8023_hdr *) buf;
1501
1502 switch (ntohs(hdr->ethertype)) {
1503 case ETH_P_PAE:
1504 wpa_printf(MSG_MSGDUMP, "Received EAPOL packet");
1505 sa = hdr->src;
1506 os_memset(&event, 0, sizeof(event));
1507 event.new_sta.addr = sa;
1508 wpa_supplicant_event(ctx, EVENT_NEW_STA, &event);
1509
1510 pos = (u8 *) (hdr + 1);
1511 left = len - sizeof(*hdr);
1512 drv_event_eapol_rx(ctx, sa, pos, left);
1513 break;
1514
1515 default:
1516 wpa_printf(MSG_DEBUG, "Unknown ethertype 0x%04x in data frame",
1517 ntohs(hdr->ethertype));
1518 break;
1519 }
1520 #endif /* HOSTAPD */
1521 }
1522
1523
macsec_drv_handle_read(int sock,void * eloop_ctx,void * sock_ctx)1524 static void macsec_drv_handle_read(int sock, void *eloop_ctx, void *sock_ctx)
1525 {
1526 int len;
1527 unsigned char buf[3000];
1528
1529 len = recv(sock, buf, sizeof(buf), 0);
1530 if (len < 0) {
1531 wpa_printf(MSG_ERROR, "macsec_linux: recv: %s",
1532 strerror(errno));
1533 return;
1534 }
1535
1536 macsec_drv_handle_data(eloop_ctx, buf, len);
1537 }
1538
1539 #endif /* __linux__ */
1540
1541
macsec_drv_init_sockets(struct macsec_drv_data * drv,u8 * own_addr)1542 static int macsec_drv_init_sockets(struct macsec_drv_data *drv, u8 *own_addr)
1543 {
1544 #ifdef __linux__
1545 struct ifreq ifr;
1546 struct sockaddr_ll addr;
1547
1548 drv->common.sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));
1549 if (drv->common.sock < 0) {
1550 wpa_printf(MSG_ERROR, "socket[PF_PACKET,SOCK_RAW]: %s",
1551 strerror(errno));
1552 return -1;
1553 }
1554
1555 if (eloop_register_read_sock(drv->common.sock, macsec_drv_handle_read,
1556 drv->common.ctx, NULL)) {
1557 wpa_printf(MSG_INFO, "Could not register read socket");
1558 return -1;
1559 }
1560
1561 os_memset(&ifr, 0, sizeof(ifr));
1562 os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name));
1563 if (ioctl(drv->common.sock, SIOCGIFINDEX, &ifr) != 0) {
1564 wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s",
1565 strerror(errno));
1566 return -1;
1567 }
1568
1569 os_memset(&addr, 0, sizeof(addr));
1570 addr.sll_family = AF_PACKET;
1571 addr.sll_ifindex = ifr.ifr_ifindex;
1572 wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",
1573 addr.sll_ifindex);
1574
1575 if (bind(drv->common.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
1576 {
1577 wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
1578 return -1;
1579 }
1580
1581 /* filter multicast address */
1582 if (wired_multicast_membership(drv->common.sock, ifr.ifr_ifindex,
1583 pae_group_addr, 1) < 0) {
1584 wpa_printf(MSG_ERROR, "wired: Failed to add multicast group "
1585 "membership");
1586 return -1;
1587 }
1588
1589 os_memset(&ifr, 0, sizeof(ifr));
1590 os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name));
1591 if (ioctl(drv->common.sock, SIOCGIFHWADDR, &ifr) != 0) {
1592 wpa_printf(MSG_ERROR, "ioctl(SIOCGIFHWADDR): %s",
1593 strerror(errno));
1594 return -1;
1595 }
1596
1597 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
1598 wpa_printf(MSG_INFO, "Invalid HW-addr family 0x%04x",
1599 ifr.ifr_hwaddr.sa_family);
1600 return -1;
1601 }
1602 os_memcpy(own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
1603
1604 return 0;
1605 #else /* __linux__ */
1606 return -1;
1607 #endif /* __linux__ */
1608 }
1609
1610
macsec_drv_hapd_init(struct hostapd_data * hapd,struct wpa_init_params * params)1611 static void * macsec_drv_hapd_init(struct hostapd_data *hapd,
1612 struct wpa_init_params *params)
1613 {
1614 struct macsec_drv_data *drv;
1615
1616 drv = os_zalloc(sizeof(struct macsec_drv_data));
1617 if (drv == NULL) {
1618 wpa_printf(MSG_INFO,
1619 "Could not allocate memory for wired driver data");
1620 return NULL;
1621 }
1622
1623 drv->common.ctx = hapd;
1624 os_strlcpy(drv->common.ifname, params->ifname,
1625 sizeof(drv->common.ifname));
1626 drv->use_pae_group_addr = params->use_pae_group_addr;
1627
1628 if (macsec_drv_init_sockets(drv, params->own_addr)) {
1629 os_free(drv);
1630 return NULL;
1631 }
1632
1633 return drv;
1634 }
1635
1636
macsec_drv_hapd_deinit(void * priv)1637 static void macsec_drv_hapd_deinit(void *priv)
1638 {
1639 struct macsec_drv_data *drv = priv;
1640
1641 if (drv->common.sock >= 0) {
1642 eloop_unregister_read_sock(drv->common.sock);
1643 close(drv->common.sock);
1644 }
1645
1646 os_free(drv);
1647 }
1648
1649
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)1650 static int macsec_drv_send_eapol(void *priv, const u8 *addr,
1651 const u8 *data, size_t data_len, int encrypt,
1652 const u8 *own_addr, u32 flags, int link_id)
1653 {
1654 struct macsec_drv_data *drv = priv;
1655 struct ieee8023_hdr *hdr;
1656 size_t len;
1657 u8 *pos;
1658 int res;
1659
1660 len = sizeof(*hdr) + data_len;
1661 hdr = os_zalloc(len);
1662 if (hdr == NULL) {
1663 wpa_printf(MSG_INFO,
1664 "%s: malloc() failed (len=%lu)",
1665 __func__, (unsigned long) len);
1666 return -1;
1667 }
1668
1669 os_memcpy(hdr->dest, drv->use_pae_group_addr ? pae_group_addr : addr,
1670 ETH_ALEN);
1671 os_memcpy(hdr->src, own_addr, ETH_ALEN);
1672 hdr->ethertype = htons(ETH_P_PAE);
1673
1674 pos = (u8 *) (hdr + 1);
1675 os_memcpy(pos, data, data_len);
1676
1677 res = send(drv->common.sock, (u8 *) hdr, len, 0);
1678 os_free(hdr);
1679
1680 if (res < 0) {
1681 wpa_printf(MSG_ERROR,
1682 "%s: packet len: %lu - failed: send: %s",
1683 __func__, (unsigned long) len, strerror(errno));
1684 }
1685
1686 return res;
1687 }
1688
1689
1690 const struct wpa_driver_ops wpa_driver_macsec_linux_ops = {
1691 .name = "macsec_linux",
1692 .desc = "MACsec Ethernet driver for Linux",
1693 .get_ssid = driver_wired_get_ssid,
1694 .get_bssid = driver_wired_get_bssid,
1695 .get_capa = driver_wired_get_capa,
1696 .init = macsec_drv_wpa_init,
1697 .deinit = macsec_drv_wpa_deinit,
1698 .hapd_init = macsec_drv_hapd_init,
1699 .hapd_deinit = macsec_drv_hapd_deinit,
1700 .hapd_send_eapol = macsec_drv_send_eapol,
1701
1702 .macsec_init = macsec_drv_macsec_init,
1703 .macsec_deinit = macsec_drv_macsec_deinit,
1704 .macsec_get_capability = macsec_drv_get_capability,
1705 .enable_protect_frames = macsec_drv_enable_protect_frames,
1706 .enable_encrypt = macsec_drv_enable_encrypt,
1707 .set_replay_protect = macsec_drv_set_replay_protect,
1708 .set_offload = macsec_drv_set_offload,
1709 .set_current_cipher_suite = macsec_drv_set_current_cipher_suite,
1710 .enable_controlled_port = macsec_drv_enable_controlled_port,
1711 .get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn,
1712 .set_receive_lowest_pn = macsec_drv_set_receive_lowest_pn,
1713 .get_transmit_next_pn = macsec_drv_get_transmit_next_pn,
1714 .set_transmit_next_pn = macsec_drv_set_transmit_next_pn,
1715 .create_receive_sc = macsec_drv_create_receive_sc,
1716 .delete_receive_sc = macsec_drv_delete_receive_sc,
1717 .create_receive_sa = macsec_drv_create_receive_sa,
1718 .delete_receive_sa = macsec_drv_delete_receive_sa,
1719 .enable_receive_sa = macsec_drv_enable_receive_sa,
1720 .disable_receive_sa = macsec_drv_disable_receive_sa,
1721 .create_transmit_sc = macsec_drv_create_transmit_sc,
1722 .delete_transmit_sc = macsec_drv_delete_transmit_sc,
1723 .create_transmit_sa = macsec_drv_create_transmit_sa,
1724 .delete_transmit_sa = macsec_drv_delete_transmit_sa,
1725 .enable_transmit_sa = macsec_drv_enable_transmit_sa,
1726 .disable_transmit_sa = macsec_drv_disable_transmit_sa,
1727
1728 .status = macsec_drv_status,
1729 };
1730