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