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