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
35struct 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
44struct macsec_genl_ctx {
45	struct nl_sock *sk;
46	int macsec_genl_id;
47	struct cb_arg cb_arg;
48};
49
50struct 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
83static int dump_callback(struct nl_msg *msg, void *argp);
84
85
86static 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
107nla_put_failure:
108	nlmsg_free(msg);
109	return NULL;
110}
111
112
113static 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
126nla_put_failure:
127	return -1;
128}
129
130
131static 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
161out_free:
162	nl_socket_free(ctx->sk);
163	ctx->sk = NULL;
164	return -1;
165}
166
167
168static 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
247static 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
256static 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
281out_free:
282	nl_socket_free(sk);
283	return err;
284}
285
286
287static 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
307static 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
349cache:
350	nl_cache_free(drv->link_cache);
351	drv->link_cache = NULL;
352sock:
353	nl_socket_free(drv->sk);
354	drv->sk = NULL;
355	return -1;
356}
357
358
359static 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
380static 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 */
397static 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 */
417static 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 */
438static 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 */
461static 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 */
475static 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
488static 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
495static 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
501static 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
508static 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
609static 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
630static 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
665out_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 */
677static 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 */
699static 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
734nla_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 */
746static 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 */
766static 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
796nla_put_failure:
797	nlmsg_free(msg);
798	return ret;
799}
800
801
802#define SCISTR MACSTR "::%hx"
803#define SCI2STR(addr, port) MAC2STR(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 */
816static 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
844nla_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 */
856static 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
880nla_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 */
892static 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
939nla_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 */
951static 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
985nla_put_failure:
986	nlmsg_free(msg);
987	return ret;
988}
989
990
991static 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
1020nla_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 */
1032static 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 */
1052static 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
1066static 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 */
1092static 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 */
1174static 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 */
1209static 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
1252nla_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 */
1264static 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
1295nla_put_failure:
1296	nlmsg_free(msg);
1297	return ret;
1298}
1299
1300
1301static 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
1328nla_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 */
1340static 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 */
1369static 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
1382static 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
1408static 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
1448static 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
1466static 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
1535static 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
1561static 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
1574static 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
1614const 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