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