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