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