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