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