]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/drivers/driver_macsec_linux.c
Import DTS includes from 4.19
[FreeBSD/FreeBSD.git] / contrib / wpa / src / drivers / driver_macsec_linux.c
1 /*
2  * Driver interaction with Linux MACsec kernel module
3  * Copyright (c) 2016, Sabrina Dubroca <sd@queasysnail.net> and Red Hat, Inc.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10 #include <sys/ioctl.h>
11 #include <net/if.h>
12 #include <netpacket/packet.h>
13 #include <net/if_arp.h>
14 #include <net/if.h>
15 #include <netlink/netlink.h>
16 #include <netlink/genl/genl.h>
17 #include <netlink/genl/ctrl.h>
18 #include <netlink/route/link.h>
19 #include <netlink/route/link/macsec.h>
20 #include <linux/if_macsec.h>
21 #include <inttypes.h>
22
23 #include "utils/common.h"
24 #include "utils/eloop.h"
25 #include "pae/ieee802_1x_kay.h"
26 #include "driver.h"
27 #include "driver_wired_common.h"
28
29 #define DRV_PREFIX "macsec_linux: "
30
31 #define UNUSED_SCI 0xffffffffffffffff
32
33 struct cb_arg {
34         struct macsec_drv_data *drv;
35         u32 *pn;
36         int ifindex;
37         u8 txsa;
38         u8 rxsa;
39         u64 rxsci;
40 };
41
42 struct macsec_genl_ctx {
43         struct nl_sock *sk;
44         int macsec_genl_id;
45         struct cb_arg cb_arg;
46 };
47
48 struct macsec_drv_data {
49         struct driver_wired_common_data common;
50         struct rtnl_link *link;
51         struct nl_cache *link_cache;
52         struct nl_sock *sk;
53         struct macsec_genl_ctx ctx;
54
55         struct netlink_data *netlink;
56         struct nl_handle *nl;
57         char ifname[IFNAMSIZ + 1];
58         int ifi;
59         int parent_ifi;
60
61         Boolean created_link;
62
63         Boolean controlled_port_enabled;
64         Boolean controlled_port_enabled_set;
65
66         Boolean protect_frames;
67         Boolean protect_frames_set;
68
69         Boolean encrypt;
70         Boolean encrypt_set;
71
72         Boolean replay_protect;
73         Boolean replay_protect_set;
74
75         u32 replay_window;
76
77         u8 encoding_sa;
78         Boolean encoding_sa_set;
79 };
80
81
82 static int dump_callback(struct nl_msg *msg, void *argp);
83
84
85 static struct nl_msg * msg_prepare(enum macsec_nl_commands cmd,
86                                    const struct macsec_genl_ctx *ctx,
87                                    unsigned int ifindex)
88 {
89         struct nl_msg *msg;
90
91         msg = nlmsg_alloc();
92         if (!msg) {
93                 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc message");
94                 return NULL;
95         }
96
97         if (!genlmsg_put(msg, 0, 0, ctx->macsec_genl_id, 0, 0, cmd, 0)) {
98                 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to put header");
99                 goto nla_put_failure;
100         }
101
102         NLA_PUT_U32(msg, MACSEC_ATTR_IFINDEX, ifindex);
103
104         return msg;
105
106 nla_put_failure:
107         nlmsg_free(msg);
108         return NULL;
109 }
110
111
112 static int nla_put_rxsc_config(struct nl_msg *msg, u64 sci)
113 {
114         struct nlattr *nest = nla_nest_start(msg, MACSEC_ATTR_RXSC_CONFIG);
115
116         if (!nest)
117                 return -1;
118
119         NLA_PUT_U64(msg, MACSEC_RXSC_ATTR_SCI, sci);
120
121         nla_nest_end(msg, nest);
122
123         return 0;
124
125 nla_put_failure:
126         return -1;
127 }
128
129
130 static int init_genl_ctx(struct macsec_drv_data *drv)
131 {
132         struct macsec_genl_ctx *ctx = &drv->ctx;
133
134         ctx->sk = nl_socket_alloc();
135         if (!ctx->sk) {
136                 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
137                 return -1;
138         }
139
140         if (genl_connect(ctx->sk) < 0) {
141                 wpa_printf(MSG_ERROR,
142                            DRV_PREFIX "connection to genl socket failed");
143                 goto out_free;
144         }
145
146         ctx->macsec_genl_id = genl_ctrl_resolve(ctx->sk, "macsec");
147         if (ctx->macsec_genl_id < 0) {
148                 wpa_printf(MSG_ERROR, DRV_PREFIX "genl resolve failed");
149                 goto out_free;
150         }
151
152         memset(&ctx->cb_arg, 0, sizeof(ctx->cb_arg));
153         ctx->cb_arg.drv = drv;
154
155         nl_socket_modify_cb(ctx->sk, NL_CB_VALID, NL_CB_CUSTOM, dump_callback,
156                             &ctx->cb_arg);
157
158         return 0;
159
160 out_free:
161         nl_socket_free(ctx->sk);
162         ctx->sk = NULL;
163         return -1;
164 }
165
166
167 static int try_commit(struct macsec_drv_data *drv)
168 {
169         int err;
170
171         if (!drv->sk)
172                 return 0;
173
174         if (!drv->link)
175                 return 0;
176
177         if (drv->controlled_port_enabled_set) {
178                 struct rtnl_link *change = rtnl_link_alloc();
179
180                 if (!change)
181                         return -1;
182
183                 rtnl_link_set_name(change, drv->ifname);
184
185                 if (drv->controlled_port_enabled)
186                         rtnl_link_set_flags(change, IFF_UP);
187                 else
188                         rtnl_link_unset_flags(change, IFF_UP);
189
190                 err = rtnl_link_change(drv->sk, change, change, 0);
191                 if (err < 0)
192                         return err;
193
194                 rtnl_link_put(change);
195
196                 drv->controlled_port_enabled_set = FALSE;
197         }
198
199         if (drv->protect_frames_set)
200                 rtnl_link_macsec_set_protect(drv->link, drv->protect_frames);
201
202         if (drv->encrypt_set)
203                 rtnl_link_macsec_set_encrypt(drv->link, drv->encrypt);
204
205         if (drv->replay_protect_set) {
206                 rtnl_link_macsec_set_replay_protect(drv->link,
207                                                     drv->replay_protect);
208                 if (drv->replay_protect)
209                         rtnl_link_macsec_set_window(drv->link,
210                                                     drv->replay_window);
211         }
212
213         if (drv->encoding_sa_set)
214                 rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa);
215
216         err = rtnl_link_add(drv->sk, drv->link, 0);
217         if (err < 0)
218                 return err;
219
220         drv->protect_frames_set = FALSE;
221         drv->encrypt_set = FALSE;
222         drv->replay_protect_set = FALSE;
223
224         return 0;
225 }
226
227
228 static void macsec_drv_wpa_deinit(void *priv)
229 {
230         struct macsec_drv_data *drv = priv;
231
232         driver_wired_deinit_common(&drv->common);
233         os_free(drv);
234 }
235
236
237 static int macsec_check_macsec(void)
238 {
239         struct nl_sock *sk;
240         int err = -1;
241
242         sk = nl_socket_alloc();
243         if (!sk) {
244                 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket");
245                 return -1;
246         }
247
248         if (genl_connect(sk) < 0) {
249                 wpa_printf(MSG_ERROR,
250                            DRV_PREFIX "connection to genl socket failed");
251                 goto out_free;
252         }
253
254         if (genl_ctrl_resolve(sk, "macsec") < 0) {
255                 wpa_printf(MSG_ERROR,
256                            DRV_PREFIX "genl resolve failed - macsec kernel module not present?");
257                 goto out_free;
258         }
259
260         err = 0;
261
262 out_free:
263         nl_socket_free(sk);
264         return err;
265 }
266
267
268 static void * macsec_drv_wpa_init(void *ctx, const char *ifname)
269 {
270         struct macsec_drv_data *drv;
271
272         if (macsec_check_macsec() < 0)
273                 return NULL;
274
275         drv = os_zalloc(sizeof(*drv));
276         if (!drv)
277                 return NULL;
278
279         if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
280                 os_free(drv);
281                 return NULL;
282         }
283
284         return drv;
285 }
286
287
288 static int macsec_drv_macsec_init(void *priv, struct macsec_init_params *params)
289 {
290         struct macsec_drv_data *drv = priv;
291         int err;
292
293         wpa_printf(MSG_DEBUG, "%s", __func__);
294
295         drv->sk = nl_socket_alloc();
296         if (!drv->sk)
297                 return -1;
298
299         err = nl_connect(drv->sk, NETLINK_ROUTE);
300         if (err < 0) {
301                 wpa_printf(MSG_ERROR, DRV_PREFIX
302                            "Unable to connect NETLINK_ROUTE socket: %s",
303                            strerror(errno));
304                 goto sock;
305         }
306
307         err = rtnl_link_alloc_cache(drv->sk, AF_UNSPEC, &drv->link_cache);
308         if (err < 0) {
309                 wpa_printf(MSG_ERROR, DRV_PREFIX "Unable to get link cache: %s",
310                            strerror(errno));
311                 goto sock;
312         }
313
314         drv->parent_ifi = rtnl_link_name2i(drv->link_cache, drv->common.ifname);
315         if (drv->parent_ifi == 0) {
316                 wpa_printf(MSG_ERROR, DRV_PREFIX
317                            "couldn't find ifindex for interface %s",
318                            drv->common.ifname);
319                 goto cache;
320         }
321
322         err = init_genl_ctx(drv);
323         if (err < 0)
324                 goto cache;
325
326         return 0;
327
328 cache:
329         nl_cache_free(drv->link_cache);
330         drv->link_cache = NULL;
331 sock:
332         nl_socket_free(drv->sk);
333         drv->sk = NULL;
334         return -1;
335 }
336
337
338 static int macsec_drv_macsec_deinit(void *priv)
339 {
340         struct macsec_drv_data *drv = priv;
341
342         wpa_printf(MSG_DEBUG, "%s", __func__);
343
344         if (drv->sk)
345                 nl_socket_free(drv->sk);
346         drv->sk = NULL;
347
348         if (drv->link_cache)
349                 nl_cache_free(drv->link_cache);
350         drv->link_cache = NULL;
351
352         if (drv->ctx.sk)
353                 nl_socket_free(drv->ctx.sk);
354
355         return 0;
356 }
357
358
359 static int macsec_drv_get_capability(void *priv, enum macsec_cap *cap)
360 {
361         wpa_printf(MSG_DEBUG, "%s", __func__);
362
363         *cap = MACSEC_CAP_INTEG_AND_CONF;
364
365         return 0;
366 }
367
368
369 /**
370  * macsec_drv_enable_protect_frames - Set protect frames status
371  * @priv: Private driver interface data
372  * @enabled: TRUE = protect frames enabled
373  *           FALSE = protect frames disabled
374  * Returns: 0 on success, -1 on failure (or if not supported)
375  */
376 static int macsec_drv_enable_protect_frames(void *priv, Boolean enabled)
377 {
378         struct macsec_drv_data *drv = priv;
379
380         wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
381
382         drv->protect_frames_set = TRUE;
383         drv->protect_frames = enabled;
384
385         return try_commit(drv);
386 }
387
388
389 /**
390  * macsec_drv_enable_encrypt - Set protect frames status
391  * @priv: Private driver interface data
392  * @enabled: TRUE = protect frames enabled
393  *           FALSE = protect frames disabled
394  * Returns: 0 on success, -1 on failure (or if not supported)
395  */
396 static int macsec_drv_enable_encrypt(void *priv, Boolean enabled)
397 {
398         struct macsec_drv_data *drv = priv;
399
400         wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
401
402         drv->encrypt_set = TRUE;
403         drv->encrypt = enabled;
404
405         return try_commit(drv);
406 }
407
408
409 /**
410  * macsec_drv_set_replay_protect - Set replay protect status and window size
411  * @priv: Private driver interface data
412  * @enabled: TRUE = replay protect enabled
413  *           FALSE = replay protect disabled
414  * @window: replay window size, valid only when replay protect enabled
415  * Returns: 0 on success, -1 on failure (or if not supported)
416  */
417 static int macsec_drv_set_replay_protect(void *priv, Boolean enabled,
418                                          u32 window)
419 {
420         struct macsec_drv_data *drv = priv;
421
422         wpa_printf(MSG_DEBUG, "%s -> %s, %u", __func__,
423                    enabled ? "TRUE" : "FALSE", window);
424
425         drv->replay_protect_set = TRUE;
426         drv->replay_protect = enabled;
427         if (enabled)
428                 drv->replay_window = window;
429
430         return try_commit(drv);
431 }
432
433
434 /**
435  * macsec_drv_set_current_cipher_suite - Set current cipher suite
436  * @priv: Private driver interface data
437  * @cs: EUI64 identifier
438  * Returns: 0 on success, -1 on failure (or if not supported)
439  */
440 static int macsec_drv_set_current_cipher_suite(void *priv, u64 cs)
441 {
442         wpa_printf(MSG_DEBUG, "%s -> %016" PRIx64, __func__, cs);
443         return 0;
444 }
445
446
447 /**
448  * macsec_drv_enable_controlled_port - Set controlled port status
449  * @priv: Private driver interface data
450  * @enabled: TRUE = controlled port enabled
451  *           FALSE = controlled port disabled
452  * Returns: 0 on success, -1 on failure (or if not supported)
453  */
454 static int macsec_drv_enable_controlled_port(void *priv, Boolean enabled)
455 {
456         struct macsec_drv_data *drv = priv;
457
458         wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE");
459
460         drv->controlled_port_enabled = enabled;
461         drv->controlled_port_enabled_set = TRUE;
462
463         return try_commit(drv);
464 }
465
466
467 static struct nla_policy sa_policy[MACSEC_SA_ATTR_MAX + 1] = {
468         [MACSEC_SA_ATTR_AN] = { .type = NLA_U8 },
469         [MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 },
470         [MACSEC_SA_ATTR_PN] = { .type = NLA_U32 },
471         [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY },
472 };
473
474 static struct nla_policy sc_policy[MACSEC_RXSC_ATTR_MAX + 1] = {
475         [MACSEC_RXSC_ATTR_SCI] = { .type = NLA_U64 },
476         [MACSEC_RXSC_ATTR_ACTIVE] = { .type = NLA_U8 },
477         [MACSEC_RXSC_ATTR_SA_LIST] = { .type = NLA_NESTED },
478 };
479
480 static struct nla_policy main_policy[MACSEC_ATTR_MAX + 1] = {
481         [MACSEC_ATTR_IFINDEX] = { .type = NLA_U32 },
482         [MACSEC_ATTR_SECY] = { .type = NLA_NESTED },
483         [MACSEC_ATTR_TXSA_LIST] = { .type = NLA_NESTED },
484         [MACSEC_ATTR_RXSC_LIST] = { .type = NLA_NESTED },
485 };
486
487 static int dump_callback(struct nl_msg *msg, void *argp)
488 {
489         struct nlmsghdr *ret_hdr = nlmsg_hdr(msg);
490         struct nlattr *tb_msg[MACSEC_ATTR_MAX + 1];
491         struct cb_arg *arg = (struct cb_arg *) argp;
492         struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(ret_hdr);
493         int err;
494
495         if (ret_hdr->nlmsg_type != arg->drv->ctx.macsec_genl_id)
496                 return 0;
497
498         err = nla_parse(tb_msg, MACSEC_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
499                         genlmsg_attrlen(gnlh, 0), main_policy);
500         if (err < 0)
501                 return 0;
502
503         if (!tb_msg[MACSEC_ATTR_IFINDEX])
504                 return 0;
505
506         if (nla_get_u32(tb_msg[MACSEC_ATTR_IFINDEX]) != (u32) arg->ifindex)
507                 return 0;
508
509         if (arg->txsa < 4 && !tb_msg[MACSEC_ATTR_TXSA_LIST]) {
510                 return 0;
511         } else if (arg->txsa < 4) {
512                 struct nlattr *nla;
513                 int rem;
514
515                 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_TXSA_LIST], rem) {
516                         struct nlattr *tb[MACSEC_SA_ATTR_MAX + 1];
517
518                         err = nla_parse_nested(tb, MACSEC_SA_ATTR_MAX, nla,
519                                                sa_policy);
520                         if (err < 0)
521                                 continue;
522                         if (!tb[MACSEC_SA_ATTR_AN])
523                                 continue;
524                         if (nla_get_u8(tb[MACSEC_SA_ATTR_AN]) != arg->txsa)
525                                 continue;
526                         if (!tb[MACSEC_SA_ATTR_PN])
527                                 return 0;
528                         *arg->pn = nla_get_u32(tb[MACSEC_SA_ATTR_PN]);
529                         return 0;
530                 }
531
532                 return 0;
533         }
534
535         if (arg->rxsci == UNUSED_SCI)
536                 return 0;
537
538         if (tb_msg[MACSEC_ATTR_RXSC_LIST]) {
539                 struct nlattr *nla;
540                 int rem;
541
542                 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_RXSC_LIST], rem) {
543                         struct nlattr *tb[MACSEC_RXSC_ATTR_MAX + 1];
544
545                         err = nla_parse_nested(tb, MACSEC_RXSC_ATTR_MAX, nla,
546                                                sc_policy);
547                         if (err < 0)
548                                 return 0;
549                         if (!tb[MACSEC_RXSC_ATTR_SCI])
550                                 continue;
551                         if (nla_get_u64(tb[MACSEC_RXSC_ATTR_SCI]) != arg->rxsci)
552                                 continue;
553                         if (!tb[MACSEC_RXSC_ATTR_SA_LIST])
554                                 return 0;
555
556                         nla_for_each_nested(nla, tb[MACSEC_RXSC_ATTR_SA_LIST],
557                                             rem) {
558                                 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1];
559
560                                 err = nla_parse_nested(tb_sa,
561                                                        MACSEC_SA_ATTR_MAX, nla,
562                                                        sa_policy);
563                                 if (err < 0)
564                                         continue;
565                                 if (!tb_sa[MACSEC_SA_ATTR_AN])
566                                         continue;
567                                 if (nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]) !=
568                                     arg->rxsa)
569                                         continue;
570                                 if (!tb_sa[MACSEC_SA_ATTR_PN])
571                                         return 0;
572                                 *arg->pn =
573                                         nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
574
575                                 return 0;
576                         }
577
578                         return 0;
579                 }
580
581                 return 0;
582         }
583
584         return 0;
585 }
586
587
588 static int nl_send_recv(struct nl_sock *sk, struct nl_msg *msg)
589 {
590         int ret;
591
592         ret = nl_send_auto_complete(sk, msg);
593         if (ret < 0) {
594                 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to send: %d (%s)",
595                            __func__, ret, nl_geterror(-ret));
596                 return ret;
597         }
598
599         ret = nl_recvmsgs_default(sk);
600         if (ret < 0) {
601                 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to recv: %d (%s)",
602                            __func__, ret, nl_geterror(-ret));
603         }
604
605         return ret;
606 }
607
608
609 static int do_dump(struct macsec_drv_data *drv, u8 txsa, u64 rxsci, u8 rxsa,
610                    u32 *pn)
611 {
612         struct macsec_genl_ctx *ctx = &drv->ctx;
613         struct nl_msg *msg;
614         int ret = 1;
615
616         ctx->cb_arg.ifindex = drv->ifi;
617         ctx->cb_arg.rxsci = rxsci;
618         ctx->cb_arg.rxsa = rxsa;
619         ctx->cb_arg.txsa = txsa;
620         ctx->cb_arg.pn = pn;
621
622         msg = nlmsg_alloc();
623         if (!msg) {
624                 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to alloc message",
625                            __func__);
626                 return 1;
627         }
628
629         if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ctx->macsec_genl_id, 0,
630                          NLM_F_DUMP, MACSEC_CMD_GET_TXSC, 0)) {
631                 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to put header",
632                            __func__);
633                 goto out_free_msg;
634         }
635
636         ret = nl_send_recv(ctx->sk, msg);
637         if (ret < 0)
638                 wpa_printf(MSG_ERROR,
639                            DRV_PREFIX "failed to communicate: %d (%s)",
640                            ret, nl_geterror(-ret));
641
642         ctx->cb_arg.pn = NULL;
643
644 out_free_msg:
645         nlmsg_free(msg);
646         return ret;
647 }
648
649
650 /**
651  * macsec_drv_get_receive_lowest_pn - Get receive lowest PN
652  * @priv: Private driver interface data
653  * @sa: secure association
654  * Returns: 0 on success, -1 on failure (or if not supported)
655  */
656 static int macsec_drv_get_receive_lowest_pn(void *priv, struct receive_sa *sa)
657 {
658         struct macsec_drv_data *drv = priv;
659         int err;
660
661         wpa_printf(MSG_DEBUG, DRV_PREFIX "%s", __func__);
662
663         err = do_dump(drv, 0xff, mka_sci_u64(&sa->sc->sci), sa->an,
664                       &sa->lowest_pn);
665         wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: result %d", __func__,
666                    sa->lowest_pn);
667
668         return err;
669 }
670
671
672 /**
673  * macsec_drv_get_transmit_next_pn - Get transmit next PN
674  * @priv: Private driver interface data
675  * @sa: secure association
676  * Returns: 0 on success, -1 on failure (or if not supported)
677  */
678 static int macsec_drv_get_transmit_next_pn(void *priv, struct transmit_sa *sa)
679 {
680         struct macsec_drv_data *drv = priv;
681         int err;
682
683         wpa_printf(MSG_DEBUG, "%s", __func__);
684
685         err = do_dump(drv, sa->an, UNUSED_SCI, 0xff, &sa->next_pn);
686         wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: err %d result %d", __func__, err,
687                    sa->next_pn);
688         return err;
689 }
690
691
692 /**
693  * macsec_drv_set_transmit_next_pn - Set transmit next pn
694  * @priv: Private driver interface data
695  * @sa: secure association
696  * Returns: 0 on success, -1 on failure (or if not supported)
697  */
698 static int macsec_drv_set_transmit_next_pn(void *priv, struct transmit_sa *sa)
699 {
700         struct macsec_drv_data *drv = priv;
701         struct macsec_genl_ctx *ctx = &drv->ctx;
702         struct nl_msg *msg;
703         struct nlattr *nest;
704         int ret = -1;
705
706         wpa_printf(MSG_DEBUG, "%s -> %d: %d", __func__, sa->an, sa->next_pn);
707
708         msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, drv->ifi);
709         if (!msg)
710                 return ret;
711
712         nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
713         if (!nest)
714                 goto nla_put_failure;
715
716         NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
717         NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
718
719         nla_nest_end(msg, nest);
720
721         ret = nl_send_recv(ctx->sk, msg);
722         if (ret < 0) {
723                 wpa_printf(MSG_ERROR,
724                            DRV_PREFIX "failed to communicate: %d (%s)",
725                            ret, nl_geterror(-ret));
726         }
727
728 nla_put_failure:
729         nlmsg_free(msg);
730         return ret;
731 }
732
733
734 #define SCISTR MACSTR "::%hx"
735 #define SCI2STR(addr, port) MAC2STR(addr), htons(port)
736
737 /**
738  * macsec_drv_create_receive_sc - Create secure channel for receiving
739  * @priv: Private driver interface data
740  * @sc: secure channel
741  * @sci_addr: secure channel identifier - address
742  * @sci_port: secure channel identifier - port
743  * @conf_offset: confidentiality offset (0, 30, or 50)
744  * @validation: frame validation policy (0 = Disabled, 1 = Checked,
745  *      2 = Strict)
746  * Returns: 0 on success, -1 on failure (or if not supported)
747  */
748 static int macsec_drv_create_receive_sc(void *priv, struct receive_sc *sc,
749                                         unsigned int conf_offset,
750                                         int validation)
751 {
752         struct macsec_drv_data *drv = priv;
753         struct macsec_genl_ctx *ctx = &drv->ctx;
754         struct nl_msg *msg;
755         int ret = -1;
756
757         wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__,
758                    SCI2STR(sc->sci.addr, sc->sci.port));
759
760         msg = msg_prepare(MACSEC_CMD_ADD_RXSC, ctx, drv->ifi);
761         if (!msg)
762                 return ret;
763
764         if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
765                 goto nla_put_failure;
766
767         ret = nl_send_recv(ctx->sk, msg);
768         if (ret < 0) {
769                 wpa_printf(MSG_ERROR,
770                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
771                            __func__, ret, nl_geterror(-ret));
772         }
773
774 nla_put_failure:
775         nlmsg_free(msg);
776         return ret;
777 }
778
779
780 /**
781  * macsec_drv_delete_receive_sc - Delete secure connection for receiving
782  * @priv: private driver interface data from init()
783  * @sc: secure channel
784  * Returns: 0 on success, -1 on failure
785  */
786 static int macsec_drv_delete_receive_sc(void *priv, struct receive_sc *sc)
787 {
788         struct macsec_drv_data *drv = priv;
789         struct macsec_genl_ctx *ctx = &drv->ctx;
790         struct nl_msg *msg;
791         int ret = -1;
792
793         wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__,
794                    SCI2STR(sc->sci.addr, sc->sci.port));
795
796         msg = msg_prepare(MACSEC_CMD_DEL_RXSC, ctx, drv->ifi);
797         if (!msg)
798                 return ret;
799
800         if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci)))
801                 goto nla_put_failure;
802
803         ret = nl_send_recv(ctx->sk, msg);
804         if (ret < 0) {
805                 wpa_printf(MSG_ERROR,
806                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
807                            __func__, ret, nl_geterror(-ret));
808         }
809
810 nla_put_failure:
811         nlmsg_free(msg);
812         return ret;
813 }
814
815
816 /**
817  * macsec_drv_create_receive_sa - Create secure association for receive
818  * @priv: private driver interface data from init()
819  * @sa: secure association
820  * Returns: 0 on success, -1 on failure
821  */
822 static int macsec_drv_create_receive_sa(void *priv, struct receive_sa *sa)
823 {
824         struct macsec_drv_data *drv = priv;
825         struct macsec_genl_ctx *ctx = &drv->ctx;
826         struct nl_msg *msg;
827         struct nlattr *nest;
828         int ret = -1;
829
830         wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
831                    SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
832
833         msg = msg_prepare(MACSEC_CMD_ADD_RXSA, ctx, drv->ifi);
834         if (!msg)
835                 return ret;
836
837         if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
838                 goto nla_put_failure;
839
840         nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
841         if (!nest)
842                 goto nla_put_failure;
843
844         NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
845         NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_receive);
846         NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
847         NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
848                 &sa->pkey->key_identifier);
849         NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
850
851         nla_nest_end(msg, nest);
852
853         ret = nl_send_recv(ctx->sk, msg);
854         if (ret < 0) {
855                 wpa_printf(MSG_ERROR,
856                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
857                            __func__, ret, nl_geterror(-ret));
858         }
859
860 nla_put_failure:
861         nlmsg_free(msg);
862         return ret;
863 }
864
865
866 /**
867  * macsec_drv_delete_receive_sa - Delete secure association for receive
868  * @priv: private driver interface data from init()
869  * @sa: secure association
870  * Returns: 0 on success, -1 on failure
871  */
872 static int macsec_drv_delete_receive_sa(void *priv, struct receive_sa *sa)
873 {
874         struct macsec_drv_data *drv = priv;
875         struct macsec_genl_ctx *ctx = &drv->ctx;
876         struct nl_msg *msg;
877         struct nlattr *nest;
878         int ret = -1;
879
880         wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
881                    SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
882
883         msg = msg_prepare(MACSEC_CMD_DEL_RXSA, ctx, drv->ifi);
884         if (!msg)
885                 return ret;
886
887         if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci)))
888                 goto nla_put_failure;
889
890         nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
891         if (!nest)
892                 goto nla_put_failure;
893
894         NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
895
896         nla_nest_end(msg, nest);
897
898         ret = nl_send_recv(ctx->sk, msg);
899         if (ret < 0) {
900                 wpa_printf(MSG_ERROR,
901                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
902                            __func__, ret, nl_geterror(-ret));
903         }
904
905 nla_put_failure:
906         nlmsg_free(msg);
907         return ret;
908 }
909
910
911 static int set_active_rx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
912                             u64 sci, unsigned char an, Boolean state)
913 {
914         struct nl_msg *msg;
915         struct nlattr *nest;
916         int ret = -1;
917
918         msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, ifindex);
919         if (!msg)
920                 return ret;
921
922         if (nla_put_rxsc_config(msg, sci))
923                 goto nla_put_failure;
924
925         nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
926         if (!nest)
927                 goto nla_put_failure;
928
929         NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
930         NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
931
932         nla_nest_end(msg, nest);
933
934         ret = nl_send_recv(ctx->sk, msg);
935         if (ret < 0)
936                 wpa_printf(MSG_ERROR,
937                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
938                            __func__, ret, nl_geterror(-ret));
939
940 nla_put_failure:
941         nlmsg_free(msg);
942         return ret;
943 }
944
945
946 /**
947  * macsec_drv_enable_receive_sa - Enable the SA for receive
948  * @priv: private driver interface data from init()
949  * @sa: secure association
950  * Returns: 0 on success, -1 on failure
951  */
952 static int macsec_drv_enable_receive_sa(void *priv, struct receive_sa *sa)
953 {
954         struct macsec_drv_data *drv = priv;
955         struct macsec_genl_ctx *ctx = &drv->ctx;
956
957         wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
958                    SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
959
960         return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
961                                 sa->an, TRUE);
962 }
963
964
965 /**
966  * macsec_drv_disable_receive_sa - Disable SA for receive
967  * @priv: private driver interface data from init()
968  * @sa: secure association
969  * Returns: 0 on success, -1 on failure
970  */
971 static int macsec_drv_disable_receive_sa(void *priv, struct receive_sa *sa)
972 {
973         struct macsec_drv_data *drv = priv;
974         struct macsec_genl_ctx *ctx = &drv->ctx;
975
976         wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an,
977                    SCI2STR(sa->sc->sci.addr, sa->sc->sci.port));
978
979         return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci),
980                                 sa->an, FALSE);
981 }
982
983
984 static struct rtnl_link * lookup_sc(struct nl_cache *cache, int parent, u64 sci)
985 {
986         struct rtnl_link *needle;
987         void *match;
988
989         needle = rtnl_link_macsec_alloc();
990         if (!needle)
991                 return NULL;
992
993         rtnl_link_set_link(needle, parent);
994         rtnl_link_macsec_set_sci(needle, sci);
995
996         match = nl_cache_find(cache, (struct nl_object *) needle);
997         rtnl_link_put(needle);
998
999         return (struct rtnl_link *) match;
1000 }
1001
1002
1003 /**
1004  * macsec_drv_create_transmit_sc - Create secure connection for transmit
1005  * @priv: private driver interface data from init()
1006  * @sc: secure channel
1007  * @conf_offset: confidentiality offset
1008  * Returns: 0 on success, -1 on failure
1009  */
1010 static int macsec_drv_create_transmit_sc(
1011         void *priv, struct transmit_sc *sc,
1012         unsigned int conf_offset)
1013 {
1014         struct macsec_drv_data *drv = priv;
1015         struct rtnl_link *link;
1016         char *ifname;
1017         u64 sci;
1018         int err;
1019
1020         wpa_printf(MSG_DEBUG, "%s", __func__);
1021
1022         if (!drv->sk) {
1023                 wpa_printf(MSG_ERROR, DRV_PREFIX "NULL rtnl socket");
1024                 return -1;
1025         }
1026
1027         link = rtnl_link_macsec_alloc();
1028         if (!link) {
1029                 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
1030                 return -1;
1031         }
1032
1033         rtnl_link_set_link(link, drv->parent_ifi);
1034
1035         sci = mka_sci_u64(&sc->sci);
1036         rtnl_link_macsec_set_sci(link, sci);
1037
1038         drv->created_link = TRUE;
1039
1040         err = rtnl_link_add(drv->sk, link, NLM_F_CREATE);
1041         if (err == -NLE_BUSY) {
1042                 wpa_printf(MSG_INFO,
1043                            DRV_PREFIX "link already exists, using it");
1044                 drv->created_link = FALSE;
1045         } else if (err < 0) {
1046                 rtnl_link_put(link);
1047                 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't create link: err %d",
1048                            err);
1049                 return err;
1050         }
1051
1052         rtnl_link_put(link);
1053
1054         nl_cache_refill(drv->sk, drv->link_cache);
1055         link = lookup_sc(drv->link_cache, drv->parent_ifi, sci);
1056         if (!link) {
1057                 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't find link");
1058                 return -1;
1059         }
1060
1061         drv->ifi = rtnl_link_get_ifindex(link);
1062         ifname = rtnl_link_get_name(link);
1063         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1064         rtnl_link_put(link);
1065
1066         drv->link = rtnl_link_macsec_alloc();
1067         if (!drv->link) {
1068                 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link");
1069                 return -1;
1070         }
1071
1072         rtnl_link_set_name(drv->link, drv->ifname);
1073
1074         /* In case some settings have already been done but we couldn't apply
1075          * them. */
1076         return try_commit(drv);
1077 }
1078
1079
1080 /**
1081  * macsec_drv_delete_transmit_sc - Delete secure connection for transmit
1082  * @priv: private driver interface data from init()
1083  * @sc: secure channel
1084  * Returns: 0 on success, -1 on failure
1085  */
1086 static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc)
1087 {
1088         struct macsec_drv_data *drv = priv;
1089         int err;
1090
1091         wpa_printf(MSG_DEBUG, "%s", __func__);
1092
1093         if (!drv->sk)
1094                 return 0;
1095
1096         if (!drv->created_link) {
1097                 rtnl_link_put(drv->link);
1098                 drv->link = NULL;
1099                 wpa_printf(MSG_DEBUG, DRV_PREFIX
1100                            "we didn't create the link, leave it alone");
1101                 return 0;
1102         }
1103
1104         err = rtnl_link_delete(drv->sk, drv->link);
1105         if (err < 0)
1106                 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't delete link");
1107         rtnl_link_put(drv->link);
1108         drv->link = NULL;
1109
1110         return err;
1111 }
1112
1113
1114 /**
1115  * macsec_drv_create_transmit_sa - Create secure association for transmit
1116  * @priv: private driver interface data from init()
1117  * @sa: secure association
1118  * Returns: 0 on success, -1 on failure
1119  */
1120 static int macsec_drv_create_transmit_sa(void *priv, struct transmit_sa *sa)
1121 {
1122         struct macsec_drv_data *drv = priv;
1123         struct macsec_genl_ctx *ctx = &drv->ctx;
1124         struct nl_msg *msg;
1125         struct nlattr *nest;
1126         int ret = -1;
1127
1128         wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1129
1130         msg = msg_prepare(MACSEC_CMD_ADD_TXSA, ctx, drv->ifi);
1131         if (!msg)
1132                 return ret;
1133
1134         nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1135         if (!nest)
1136                 goto nla_put_failure;
1137
1138         NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1139         NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn);
1140         NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier),
1141                 &sa->pkey->key_identifier);
1142         NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key);
1143         NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_transmit);
1144
1145         nla_nest_end(msg, nest);
1146
1147         ret = nl_send_recv(ctx->sk, msg);
1148         if (ret < 0) {
1149                 wpa_printf(MSG_ERROR,
1150                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
1151                            __func__, ret, nl_geterror(-ret));
1152         }
1153
1154 nla_put_failure:
1155         nlmsg_free(msg);
1156         return ret;
1157 }
1158
1159
1160 /**
1161  * macsec_drv_delete_transmit_sa - Delete secure association for transmit
1162  * @priv: private driver interface data from init()
1163  * @sa: secure association
1164  * Returns: 0 on success, -1 on failure
1165  */
1166 static int macsec_drv_delete_transmit_sa(void *priv, struct transmit_sa *sa)
1167 {
1168         struct macsec_drv_data *drv = priv;
1169         struct macsec_genl_ctx *ctx = &drv->ctx;
1170         struct nl_msg *msg;
1171         struct nlattr *nest;
1172         int ret = -1;
1173
1174         wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1175
1176         msg = msg_prepare(MACSEC_CMD_DEL_TXSA, ctx, drv->ifi);
1177         if (!msg)
1178                 return ret;
1179
1180         nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1181         if (!nest)
1182                 goto nla_put_failure;
1183
1184         NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an);
1185
1186         nla_nest_end(msg, nest);
1187
1188         ret = nl_send_recv(ctx->sk, msg);
1189         if (ret < 0) {
1190                 wpa_printf(MSG_ERROR,
1191                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
1192                            __func__, ret, nl_geterror(-ret));
1193         }
1194
1195 nla_put_failure:
1196         nlmsg_free(msg);
1197         return ret;
1198 }
1199
1200
1201 static int set_active_tx_sa(const struct macsec_genl_ctx *ctx, int ifindex,
1202                             unsigned char an, Boolean state)
1203 {
1204         struct nl_msg *msg;
1205         struct nlattr *nest;
1206         int ret = -1;
1207
1208         msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, ifindex);
1209         if (!msg)
1210                 return ret;
1211
1212         nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG);
1213         if (!nest)
1214                 goto nla_put_failure;
1215
1216         NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an);
1217         NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state);
1218
1219         nla_nest_end(msg, nest);
1220
1221         ret = nl_send_recv(ctx->sk, msg);
1222         if (ret < 0) {
1223                 wpa_printf(MSG_ERROR,
1224                            DRV_PREFIX "%s: failed to communicate: %d (%s)",
1225                            __func__, ret, nl_geterror(-ret));
1226         }
1227
1228 nla_put_failure:
1229         nlmsg_free(msg);
1230         return ret;
1231 }
1232
1233
1234 /**
1235  * macsec_drv_enable_transmit_sa - Enable SA for transmit
1236  * @priv: private driver interface data from init()
1237  * @sa: secure association
1238  * Returns: 0 on success, -1 on failure
1239  */
1240 static int macsec_drv_enable_transmit_sa(void *priv, struct transmit_sa *sa)
1241 {
1242         struct macsec_drv_data *drv = priv;
1243         struct macsec_genl_ctx *ctx = &drv->ctx;
1244         int ret;
1245
1246         wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1247
1248         ret = set_active_tx_sa(ctx, drv->ifi, sa->an, TRUE);
1249         if (ret < 0) {
1250                 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to enable txsa");
1251                 return ret;
1252         }
1253
1254         drv->encoding_sa_set = TRUE;
1255         drv->encoding_sa = sa->an;
1256
1257         return try_commit(drv);
1258 }
1259
1260
1261 /**
1262  * macsec_drv_disable_transmit_sa - Disable SA for transmit
1263  * @priv: private driver interface data from init()
1264  * @sa: secure association
1265  * Returns: 0 on success, -1 on failure
1266  */
1267 static int macsec_drv_disable_transmit_sa(void *priv, struct transmit_sa *sa)
1268 {
1269         struct macsec_drv_data *drv = priv;
1270         struct macsec_genl_ctx *ctx = &drv->ctx;
1271
1272         wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an);
1273
1274         return set_active_tx_sa(ctx, drv->ifi, sa->an, FALSE);
1275 }
1276
1277
1278 const struct wpa_driver_ops wpa_driver_macsec_linux_ops = {
1279         .name = "macsec_linux",
1280         .desc = "MACsec Ethernet driver for Linux",
1281         .get_ssid = driver_wired_get_ssid,
1282         .get_bssid = driver_wired_get_bssid,
1283         .get_capa = driver_wired_get_capa,
1284         .init = macsec_drv_wpa_init,
1285         .deinit = macsec_drv_wpa_deinit,
1286
1287         .macsec_init = macsec_drv_macsec_init,
1288         .macsec_deinit = macsec_drv_macsec_deinit,
1289         .macsec_get_capability = macsec_drv_get_capability,
1290         .enable_protect_frames = macsec_drv_enable_protect_frames,
1291         .enable_encrypt = macsec_drv_enable_encrypt,
1292         .set_replay_protect = macsec_drv_set_replay_protect,
1293         .set_current_cipher_suite = macsec_drv_set_current_cipher_suite,
1294         .enable_controlled_port = macsec_drv_enable_controlled_port,
1295         .get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn,
1296         .get_transmit_next_pn = macsec_drv_get_transmit_next_pn,
1297         .set_transmit_next_pn = macsec_drv_set_transmit_next_pn,
1298         .create_receive_sc = macsec_drv_create_receive_sc,
1299         .delete_receive_sc = macsec_drv_delete_receive_sc,
1300         .create_receive_sa = macsec_drv_create_receive_sa,
1301         .delete_receive_sa = macsec_drv_delete_receive_sa,
1302         .enable_receive_sa = macsec_drv_enable_receive_sa,
1303         .disable_receive_sa = macsec_drv_disable_receive_sa,
1304         .create_transmit_sc = macsec_drv_create_transmit_sc,
1305         .delete_transmit_sc = macsec_drv_delete_transmit_sc,
1306         .create_transmit_sa = macsec_drv_create_transmit_sa,
1307         .delete_transmit_sa = macsec_drv_delete_transmit_sa,
1308         .enable_transmit_sa = macsec_drv_enable_transmit_sa,
1309         .disable_transmit_sa = macsec_drv_disable_transmit_sa,
1310 };