1 /* 2 * Driver interaction with Linux MACsec kernel module 3 * Copyright (c) 2016, Sabrina Dubroca <sd@queasysnail.net> and Red Hat, Inc. 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 #include <sys/ioctl.h> 11 #include <net/if.h> 12 #include <netpacket/packet.h> 13 #include <net/if_arp.h> 14 #include <net/if.h> 15 #include <netlink/netlink.h> 16 #include <netlink/genl/genl.h> 17 #include <netlink/genl/ctrl.h> 18 #include <netlink/route/link.h> 19 #include <netlink/route/link/macsec.h> 20 #include <linux/if_macsec.h> 21 #include <inttypes.h> 22 23 #include "utils/common.h" 24 #include "utils/eloop.h" 25 #include "pae/ieee802_1x_kay.h" 26 #include "driver.h" 27 #include "driver_wired_common.h" 28 29 #define DRV_PREFIX "macsec_linux: " 30 31 #define UNUSED_SCI 0xffffffffffffffff 32 33 struct cb_arg { 34 struct macsec_drv_data *drv; 35 u32 *pn; 36 int ifindex; 37 u8 txsa; 38 u8 rxsa; 39 u64 rxsci; 40 }; 41 42 struct macsec_genl_ctx { 43 struct nl_sock *sk; 44 int macsec_genl_id; 45 struct cb_arg cb_arg; 46 }; 47 48 struct macsec_drv_data { 49 struct driver_wired_common_data common; 50 struct rtnl_link *link; 51 struct nl_cache *link_cache; 52 struct nl_sock *sk; 53 struct macsec_genl_ctx ctx; 54 55 struct netlink_data *netlink; 56 struct nl_handle *nl; 57 char ifname[IFNAMSIZ + 1]; 58 int ifi; 59 int parent_ifi; 60 61 Boolean created_link; 62 63 Boolean controlled_port_enabled; 64 Boolean controlled_port_enabled_set; 65 66 Boolean protect_frames; 67 Boolean protect_frames_set; 68 69 Boolean encrypt; 70 Boolean encrypt_set; 71 72 Boolean replay_protect; 73 Boolean replay_protect_set; 74 75 u32 replay_window; 76 77 u8 encoding_sa; 78 Boolean encoding_sa_set; 79 }; 80 81 82 static int dump_callback(struct nl_msg *msg, void *argp); 83 84 85 static struct nl_msg * msg_prepare(enum macsec_nl_commands cmd, 86 const struct macsec_genl_ctx *ctx, 87 unsigned int ifindex) 88 { 89 struct nl_msg *msg; 90 91 msg = nlmsg_alloc(); 92 if (!msg) { 93 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc message"); 94 return NULL; 95 } 96 97 if (!genlmsg_put(msg, 0, 0, ctx->macsec_genl_id, 0, 0, cmd, 0)) { 98 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to put header"); 99 goto nla_put_failure; 100 } 101 102 NLA_PUT_U32(msg, MACSEC_ATTR_IFINDEX, ifindex); 103 104 return msg; 105 106 nla_put_failure: 107 nlmsg_free(msg); 108 return NULL; 109 } 110 111 112 static int nla_put_rxsc_config(struct nl_msg *msg, u64 sci) 113 { 114 struct nlattr *nest = nla_nest_start(msg, MACSEC_ATTR_RXSC_CONFIG); 115 116 if (!nest) 117 return -1; 118 119 NLA_PUT_U64(msg, MACSEC_RXSC_ATTR_SCI, sci); 120 121 nla_nest_end(msg, nest); 122 123 return 0; 124 125 nla_put_failure: 126 return -1; 127 } 128 129 130 static int init_genl_ctx(struct macsec_drv_data *drv) 131 { 132 struct macsec_genl_ctx *ctx = &drv->ctx; 133 134 ctx->sk = nl_socket_alloc(); 135 if (!ctx->sk) { 136 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket"); 137 return -1; 138 } 139 140 if (genl_connect(ctx->sk) < 0) { 141 wpa_printf(MSG_ERROR, 142 DRV_PREFIX "connection to genl socket failed"); 143 goto out_free; 144 } 145 146 ctx->macsec_genl_id = genl_ctrl_resolve(ctx->sk, "macsec"); 147 if (ctx->macsec_genl_id < 0) { 148 wpa_printf(MSG_ERROR, DRV_PREFIX "genl resolve failed"); 149 goto out_free; 150 } 151 152 memset(&ctx->cb_arg, 0, sizeof(ctx->cb_arg)); 153 ctx->cb_arg.drv = drv; 154 155 nl_socket_modify_cb(ctx->sk, NL_CB_VALID, NL_CB_CUSTOM, dump_callback, 156 &ctx->cb_arg); 157 158 return 0; 159 160 out_free: 161 nl_socket_free(ctx->sk); 162 ctx->sk = NULL; 163 return -1; 164 } 165 166 167 static int try_commit(struct macsec_drv_data *drv) 168 { 169 int err; 170 171 if (!drv->sk) 172 return 0; 173 174 if (!drv->link) 175 return 0; 176 177 if (drv->controlled_port_enabled_set) { 178 struct rtnl_link *change = rtnl_link_alloc(); 179 180 if (!change) 181 return -1; 182 183 rtnl_link_set_name(change, drv->ifname); 184 185 if (drv->controlled_port_enabled) 186 rtnl_link_set_flags(change, IFF_UP); 187 else 188 rtnl_link_unset_flags(change, IFF_UP); 189 190 err = rtnl_link_change(drv->sk, change, change, 0); 191 if (err < 0) 192 return err; 193 194 rtnl_link_put(change); 195 196 drv->controlled_port_enabled_set = FALSE; 197 } 198 199 if (drv->protect_frames_set) 200 rtnl_link_macsec_set_protect(drv->link, drv->protect_frames); 201 202 if (drv->encrypt_set) 203 rtnl_link_macsec_set_encrypt(drv->link, drv->encrypt); 204 205 if (drv->replay_protect_set) { 206 rtnl_link_macsec_set_replay_protect(drv->link, 207 drv->replay_protect); 208 if (drv->replay_protect) 209 rtnl_link_macsec_set_window(drv->link, 210 drv->replay_window); 211 } 212 213 if (drv->encoding_sa_set) 214 rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa); 215 216 err = rtnl_link_add(drv->sk, drv->link, 0); 217 if (err < 0) 218 return err; 219 220 drv->protect_frames_set = FALSE; 221 drv->encrypt_set = FALSE; 222 drv->replay_protect_set = FALSE; 223 224 return 0; 225 } 226 227 228 static void macsec_drv_wpa_deinit(void *priv) 229 { 230 struct macsec_drv_data *drv = priv; 231 232 driver_wired_deinit_common(&drv->common); 233 os_free(drv); 234 } 235 236 237 static int macsec_check_macsec(void) 238 { 239 struct nl_sock *sk; 240 int err = -1; 241 242 sk = nl_socket_alloc(); 243 if (!sk) { 244 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket"); 245 return -1; 246 } 247 248 if (genl_connect(sk) < 0) { 249 wpa_printf(MSG_ERROR, 250 DRV_PREFIX "connection to genl socket failed"); 251 goto out_free; 252 } 253 254 if (genl_ctrl_resolve(sk, "macsec") < 0) { 255 wpa_printf(MSG_ERROR, 256 DRV_PREFIX "genl resolve failed - macsec kernel module not present?"); 257 goto out_free; 258 } 259 260 err = 0; 261 262 out_free: 263 nl_socket_free(sk); 264 return err; 265 } 266 267 268 static void * macsec_drv_wpa_init(void *ctx, const char *ifname) 269 { 270 struct macsec_drv_data *drv; 271 272 if (macsec_check_macsec() < 0) 273 return NULL; 274 275 drv = os_zalloc(sizeof(*drv)); 276 if (!drv) 277 return NULL; 278 279 if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) { 280 os_free(drv); 281 return NULL; 282 } 283 284 return drv; 285 } 286 287 288 static int macsec_drv_macsec_init(void *priv, struct macsec_init_params *params) 289 { 290 struct macsec_drv_data *drv = priv; 291 int err; 292 293 wpa_printf(MSG_DEBUG, "%s", __func__); 294 295 drv->sk = nl_socket_alloc(); 296 if (!drv->sk) 297 return -1; 298 299 err = nl_connect(drv->sk, NETLINK_ROUTE); 300 if (err < 0) { 301 wpa_printf(MSG_ERROR, DRV_PREFIX 302 "Unable to connect NETLINK_ROUTE socket: %s", 303 strerror(errno)); 304 goto sock; 305 } 306 307 err = rtnl_link_alloc_cache(drv->sk, AF_UNSPEC, &drv->link_cache); 308 if (err < 0) { 309 wpa_printf(MSG_ERROR, DRV_PREFIX "Unable to get link cache: %s", 310 strerror(errno)); 311 goto sock; 312 } 313 314 drv->parent_ifi = rtnl_link_name2i(drv->link_cache, drv->common.ifname); 315 if (drv->parent_ifi == 0) { 316 wpa_printf(MSG_ERROR, DRV_PREFIX 317 "couldn't find ifindex for interface %s", 318 drv->common.ifname); 319 goto cache; 320 } 321 322 err = init_genl_ctx(drv); 323 if (err < 0) 324 goto cache; 325 326 return 0; 327 328 cache: 329 nl_cache_free(drv->link_cache); 330 drv->link_cache = NULL; 331 sock: 332 nl_socket_free(drv->sk); 333 drv->sk = NULL; 334 return -1; 335 } 336 337 338 static int macsec_drv_macsec_deinit(void *priv) 339 { 340 struct macsec_drv_data *drv = priv; 341 342 wpa_printf(MSG_DEBUG, "%s", __func__); 343 344 if (drv->sk) 345 nl_socket_free(drv->sk); 346 drv->sk = NULL; 347 348 if (drv->link_cache) 349 nl_cache_free(drv->link_cache); 350 drv->link_cache = NULL; 351 352 if (drv->ctx.sk) 353 nl_socket_free(drv->ctx.sk); 354 355 return 0; 356 } 357 358 359 static int macsec_drv_get_capability(void *priv, enum macsec_cap *cap) 360 { 361 wpa_printf(MSG_DEBUG, "%s", __func__); 362 363 *cap = MACSEC_CAP_INTEG_AND_CONF; 364 365 return 0; 366 } 367 368 369 /** 370 * macsec_drv_enable_protect_frames - Set protect frames status 371 * @priv: Private driver interface data 372 * @enabled: TRUE = protect frames enabled 373 * FALSE = protect frames disabled 374 * Returns: 0 on success, -1 on failure (or if not supported) 375 */ 376 static int macsec_drv_enable_protect_frames(void *priv, Boolean enabled) 377 { 378 struct macsec_drv_data *drv = priv; 379 380 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE"); 381 382 drv->protect_frames_set = TRUE; 383 drv->protect_frames = enabled; 384 385 return try_commit(drv); 386 } 387 388 389 /** 390 * macsec_drv_enable_encrypt - Set protect frames status 391 * @priv: Private driver interface data 392 * @enabled: TRUE = protect frames enabled 393 * FALSE = protect frames disabled 394 * Returns: 0 on success, -1 on failure (or if not supported) 395 */ 396 static int macsec_drv_enable_encrypt(void *priv, Boolean enabled) 397 { 398 struct macsec_drv_data *drv = priv; 399 400 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE"); 401 402 drv->encrypt_set = TRUE; 403 drv->encrypt = enabled; 404 405 return try_commit(drv); 406 } 407 408 409 /** 410 * macsec_drv_set_replay_protect - Set replay protect status and window size 411 * @priv: Private driver interface data 412 * @enabled: TRUE = replay protect enabled 413 * FALSE = replay protect disabled 414 * @window: replay window size, valid only when replay protect enabled 415 * Returns: 0 on success, -1 on failure (or if not supported) 416 */ 417 static int macsec_drv_set_replay_protect(void *priv, Boolean enabled, 418 u32 window) 419 { 420 struct macsec_drv_data *drv = priv; 421 422 wpa_printf(MSG_DEBUG, "%s -> %s, %u", __func__, 423 enabled ? "TRUE" : "FALSE", window); 424 425 drv->replay_protect_set = TRUE; 426 drv->replay_protect = enabled; 427 if (enabled) 428 drv->replay_window = window; 429 430 return try_commit(drv); 431 } 432 433 434 /** 435 * macsec_drv_set_current_cipher_suite - Set current cipher suite 436 * @priv: Private driver interface data 437 * @cs: EUI64 identifier 438 * Returns: 0 on success, -1 on failure (or if not supported) 439 */ 440 static int macsec_drv_set_current_cipher_suite(void *priv, u64 cs) 441 { 442 wpa_printf(MSG_DEBUG, "%s -> %016" PRIx64, __func__, cs); 443 return 0; 444 } 445 446 447 /** 448 * macsec_drv_enable_controlled_port - Set controlled port status 449 * @priv: Private driver interface data 450 * @enabled: TRUE = controlled port enabled 451 * FALSE = controlled port disabled 452 * Returns: 0 on success, -1 on failure (or if not supported) 453 */ 454 static int macsec_drv_enable_controlled_port(void *priv, Boolean enabled) 455 { 456 struct macsec_drv_data *drv = priv; 457 458 wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE"); 459 460 drv->controlled_port_enabled = enabled; 461 drv->controlled_port_enabled_set = TRUE; 462 463 return try_commit(drv); 464 } 465 466 467 static struct nla_policy sa_policy[MACSEC_SA_ATTR_MAX + 1] = { 468 [MACSEC_SA_ATTR_AN] = { .type = NLA_U8 }, 469 [MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 }, 470 [MACSEC_SA_ATTR_PN] = { .type = NLA_U32 }, 471 [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY }, 472 }; 473 474 static struct nla_policy sc_policy[MACSEC_RXSC_ATTR_MAX + 1] = { 475 [MACSEC_RXSC_ATTR_SCI] = { .type = NLA_U64 }, 476 [MACSEC_RXSC_ATTR_ACTIVE] = { .type = NLA_U8 }, 477 [MACSEC_RXSC_ATTR_SA_LIST] = { .type = NLA_NESTED }, 478 }; 479 480 static struct nla_policy main_policy[MACSEC_ATTR_MAX + 1] = { 481 [MACSEC_ATTR_IFINDEX] = { .type = NLA_U32 }, 482 [MACSEC_ATTR_SECY] = { .type = NLA_NESTED }, 483 [MACSEC_ATTR_TXSA_LIST] = { .type = NLA_NESTED }, 484 [MACSEC_ATTR_RXSC_LIST] = { .type = NLA_NESTED }, 485 }; 486 487 static int dump_callback(struct nl_msg *msg, void *argp) 488 { 489 struct nlmsghdr *ret_hdr = nlmsg_hdr(msg); 490 struct nlattr *tb_msg[MACSEC_ATTR_MAX + 1]; 491 struct cb_arg *arg = (struct cb_arg *) argp; 492 struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(ret_hdr); 493 int err; 494 495 if (ret_hdr->nlmsg_type != arg->drv->ctx.macsec_genl_id) 496 return 0; 497 498 err = nla_parse(tb_msg, MACSEC_ATTR_MAX, genlmsg_attrdata(gnlh, 0), 499 genlmsg_attrlen(gnlh, 0), main_policy); 500 if (err < 0) 501 return 0; 502 503 if (!tb_msg[MACSEC_ATTR_IFINDEX]) 504 return 0; 505 506 if (nla_get_u32(tb_msg[MACSEC_ATTR_IFINDEX]) != (u32) arg->ifindex) 507 return 0; 508 509 if (arg->txsa < 4 && !tb_msg[MACSEC_ATTR_TXSA_LIST]) { 510 return 0; 511 } else if (arg->txsa < 4) { 512 struct nlattr *nla; 513 int rem; 514 515 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_TXSA_LIST], rem) { 516 struct nlattr *tb[MACSEC_SA_ATTR_MAX + 1]; 517 518 err = nla_parse_nested(tb, MACSEC_SA_ATTR_MAX, nla, 519 sa_policy); 520 if (err < 0) 521 continue; 522 if (!tb[MACSEC_SA_ATTR_AN]) 523 continue; 524 if (nla_get_u8(tb[MACSEC_SA_ATTR_AN]) != arg->txsa) 525 continue; 526 if (!tb[MACSEC_SA_ATTR_PN]) 527 return 0; 528 *arg->pn = nla_get_u32(tb[MACSEC_SA_ATTR_PN]); 529 return 0; 530 } 531 532 return 0; 533 } 534 535 if (arg->rxsci == UNUSED_SCI) 536 return 0; 537 538 if (tb_msg[MACSEC_ATTR_RXSC_LIST]) { 539 struct nlattr *nla; 540 int rem; 541 542 nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_RXSC_LIST], rem) { 543 struct nlattr *tb[MACSEC_RXSC_ATTR_MAX + 1]; 544 545 err = nla_parse_nested(tb, MACSEC_RXSC_ATTR_MAX, nla, 546 sc_policy); 547 if (err < 0) 548 return 0; 549 if (!tb[MACSEC_RXSC_ATTR_SCI]) 550 continue; 551 if (nla_get_u64(tb[MACSEC_RXSC_ATTR_SCI]) != arg->rxsci) 552 continue; 553 if (!tb[MACSEC_RXSC_ATTR_SA_LIST]) 554 return 0; 555 556 nla_for_each_nested(nla, tb[MACSEC_RXSC_ATTR_SA_LIST], 557 rem) { 558 struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1]; 559 560 err = nla_parse_nested(tb_sa, 561 MACSEC_SA_ATTR_MAX, nla, 562 sa_policy); 563 if (err < 0) 564 continue; 565 if (!tb_sa[MACSEC_SA_ATTR_AN]) 566 continue; 567 if (nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]) != 568 arg->rxsa) 569 continue; 570 if (!tb_sa[MACSEC_SA_ATTR_PN]) 571 return 0; 572 *arg->pn = 573 nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]); 574 575 return 0; 576 } 577 578 return 0; 579 } 580 581 return 0; 582 } 583 584 return 0; 585 } 586 587 588 static int nl_send_recv(struct nl_sock *sk, struct nl_msg *msg) 589 { 590 int ret; 591 592 ret = nl_send_auto_complete(sk, msg); 593 if (ret < 0) { 594 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to send: %d (%s)", 595 __func__, ret, nl_geterror(-ret)); 596 return ret; 597 } 598 599 ret = nl_recvmsgs_default(sk); 600 if (ret < 0) { 601 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to recv: %d (%s)", 602 __func__, ret, nl_geterror(-ret)); 603 } 604 605 return ret; 606 } 607 608 609 static int do_dump(struct macsec_drv_data *drv, u8 txsa, u64 rxsci, u8 rxsa, 610 u32 *pn) 611 { 612 struct macsec_genl_ctx *ctx = &drv->ctx; 613 struct nl_msg *msg; 614 int ret = 1; 615 616 ctx->cb_arg.ifindex = drv->ifi; 617 ctx->cb_arg.rxsci = rxsci; 618 ctx->cb_arg.rxsa = rxsa; 619 ctx->cb_arg.txsa = txsa; 620 ctx->cb_arg.pn = pn; 621 622 msg = nlmsg_alloc(); 623 if (!msg) { 624 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to alloc message", 625 __func__); 626 return 1; 627 } 628 629 if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ctx->macsec_genl_id, 0, 630 NLM_F_DUMP, MACSEC_CMD_GET_TXSC, 0)) { 631 wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to put header", 632 __func__); 633 goto out_free_msg; 634 } 635 636 ret = nl_send_recv(ctx->sk, msg); 637 if (ret < 0) 638 wpa_printf(MSG_ERROR, 639 DRV_PREFIX "failed to communicate: %d (%s)", 640 ret, nl_geterror(-ret)); 641 642 ctx->cb_arg.pn = NULL; 643 644 out_free_msg: 645 nlmsg_free(msg); 646 return ret; 647 } 648 649 650 /** 651 * macsec_drv_get_receive_lowest_pn - Get receive lowest PN 652 * @priv: Private driver interface data 653 * @sa: secure association 654 * Returns: 0 on success, -1 on failure (or if not supported) 655 */ 656 static int macsec_drv_get_receive_lowest_pn(void *priv, struct receive_sa *sa) 657 { 658 struct macsec_drv_data *drv = priv; 659 int err; 660 661 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s", __func__); 662 663 err = do_dump(drv, 0xff, mka_sci_u64(&sa->sc->sci), sa->an, 664 &sa->lowest_pn); 665 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: result %d", __func__, 666 sa->lowest_pn); 667 668 return err; 669 } 670 671 672 /** 673 * macsec_drv_get_transmit_next_pn - Get transmit next PN 674 * @priv: Private driver interface data 675 * @sa: secure association 676 * Returns: 0 on success, -1 on failure (or if not supported) 677 */ 678 static int macsec_drv_get_transmit_next_pn(void *priv, struct transmit_sa *sa) 679 { 680 struct macsec_drv_data *drv = priv; 681 int err; 682 683 wpa_printf(MSG_DEBUG, "%s", __func__); 684 685 err = do_dump(drv, sa->an, UNUSED_SCI, 0xff, &sa->next_pn); 686 wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: err %d result %d", __func__, err, 687 sa->next_pn); 688 return err; 689 } 690 691 692 /** 693 * macsec_drv_set_transmit_next_pn - Set transmit next pn 694 * @priv: Private driver interface data 695 * @sa: secure association 696 * Returns: 0 on success, -1 on failure (or if not supported) 697 */ 698 static int macsec_drv_set_transmit_next_pn(void *priv, struct transmit_sa *sa) 699 { 700 struct macsec_drv_data *drv = priv; 701 struct macsec_genl_ctx *ctx = &drv->ctx; 702 struct nl_msg *msg; 703 struct nlattr *nest; 704 int ret = -1; 705 706 wpa_printf(MSG_DEBUG, "%s -> %d: %d", __func__, sa->an, sa->next_pn); 707 708 msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, drv->ifi); 709 if (!msg) 710 return ret; 711 712 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); 713 if (!nest) 714 goto nla_put_failure; 715 716 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); 717 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn); 718 719 nla_nest_end(msg, nest); 720 721 ret = nl_send_recv(ctx->sk, msg); 722 if (ret < 0) { 723 wpa_printf(MSG_ERROR, 724 DRV_PREFIX "failed to communicate: %d (%s)", 725 ret, nl_geterror(-ret)); 726 } 727 728 nla_put_failure: 729 nlmsg_free(msg); 730 return ret; 731 } 732 733 734 #define SCISTR MACSTR "::%hx" 735 #define SCI2STR(addr, port) MAC2STR(addr), htons(port) 736 737 /** 738 * macsec_drv_create_receive_sc - Create secure channel for receiving 739 * @priv: Private driver interface data 740 * @sc: secure channel 741 * @sci_addr: secure channel identifier - address 742 * @sci_port: secure channel identifier - port 743 * @conf_offset: confidentiality offset (0, 30, or 50) 744 * @validation: frame validation policy (0 = Disabled, 1 = Checked, 745 * 2 = Strict) 746 * Returns: 0 on success, -1 on failure (or if not supported) 747 */ 748 static int macsec_drv_create_receive_sc(void *priv, struct receive_sc *sc, 749 unsigned int conf_offset, 750 int validation) 751 { 752 struct macsec_drv_data *drv = priv; 753 struct macsec_genl_ctx *ctx = &drv->ctx; 754 struct nl_msg *msg; 755 int ret = -1; 756 757 wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__, 758 SCI2STR(sc->sci.addr, sc->sci.port)); 759 760 msg = msg_prepare(MACSEC_CMD_ADD_RXSC, ctx, drv->ifi); 761 if (!msg) 762 return ret; 763 764 if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci))) 765 goto nla_put_failure; 766 767 ret = nl_send_recv(ctx->sk, msg); 768 if (ret < 0) { 769 wpa_printf(MSG_ERROR, 770 DRV_PREFIX "%s: failed to communicate: %d (%s)", 771 __func__, ret, nl_geterror(-ret)); 772 } 773 774 nla_put_failure: 775 nlmsg_free(msg); 776 return ret; 777 } 778 779 780 /** 781 * macsec_drv_delete_receive_sc - Delete secure connection for receiving 782 * @priv: private driver interface data from init() 783 * @sc: secure channel 784 * Returns: 0 on success, -1 on failure 785 */ 786 static int macsec_drv_delete_receive_sc(void *priv, struct receive_sc *sc) 787 { 788 struct macsec_drv_data *drv = priv; 789 struct macsec_genl_ctx *ctx = &drv->ctx; 790 struct nl_msg *msg; 791 int ret = -1; 792 793 wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__, 794 SCI2STR(sc->sci.addr, sc->sci.port)); 795 796 msg = msg_prepare(MACSEC_CMD_DEL_RXSC, ctx, drv->ifi); 797 if (!msg) 798 return ret; 799 800 if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci))) 801 goto nla_put_failure; 802 803 ret = nl_send_recv(ctx->sk, msg); 804 if (ret < 0) { 805 wpa_printf(MSG_ERROR, 806 DRV_PREFIX "%s: failed to communicate: %d (%s)", 807 __func__, ret, nl_geterror(-ret)); 808 } 809 810 nla_put_failure: 811 nlmsg_free(msg); 812 return ret; 813 } 814 815 816 /** 817 * macsec_drv_create_receive_sa - Create secure association for receive 818 * @priv: private driver interface data from init() 819 * @sa: secure association 820 * Returns: 0 on success, -1 on failure 821 */ 822 static int macsec_drv_create_receive_sa(void *priv, struct receive_sa *sa) 823 { 824 struct macsec_drv_data *drv = priv; 825 struct macsec_genl_ctx *ctx = &drv->ctx; 826 struct nl_msg *msg; 827 struct nlattr *nest; 828 int ret = -1; 829 830 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, 831 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); 832 833 msg = msg_prepare(MACSEC_CMD_ADD_RXSA, ctx, drv->ifi); 834 if (!msg) 835 return ret; 836 837 if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci))) 838 goto nla_put_failure; 839 840 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); 841 if (!nest) 842 goto nla_put_failure; 843 844 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); 845 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_receive); 846 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn); 847 NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier), 848 &sa->pkey->key_identifier); 849 NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key); 850 851 nla_nest_end(msg, nest); 852 853 ret = nl_send_recv(ctx->sk, msg); 854 if (ret < 0) { 855 wpa_printf(MSG_ERROR, 856 DRV_PREFIX "%s: failed to communicate: %d (%s)", 857 __func__, ret, nl_geterror(-ret)); 858 } 859 860 nla_put_failure: 861 nlmsg_free(msg); 862 return ret; 863 } 864 865 866 /** 867 * macsec_drv_delete_receive_sa - Delete secure association for receive 868 * @priv: private driver interface data from init() 869 * @sa: secure association 870 * Returns: 0 on success, -1 on failure 871 */ 872 static int macsec_drv_delete_receive_sa(void *priv, struct receive_sa *sa) 873 { 874 struct macsec_drv_data *drv = priv; 875 struct macsec_genl_ctx *ctx = &drv->ctx; 876 struct nl_msg *msg; 877 struct nlattr *nest; 878 int ret = -1; 879 880 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, 881 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); 882 883 msg = msg_prepare(MACSEC_CMD_DEL_RXSA, ctx, drv->ifi); 884 if (!msg) 885 return ret; 886 887 if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci))) 888 goto nla_put_failure; 889 890 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); 891 if (!nest) 892 goto nla_put_failure; 893 894 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); 895 896 nla_nest_end(msg, nest); 897 898 ret = nl_send_recv(ctx->sk, msg); 899 if (ret < 0) { 900 wpa_printf(MSG_ERROR, 901 DRV_PREFIX "%s: failed to communicate: %d (%s)", 902 __func__, ret, nl_geterror(-ret)); 903 } 904 905 nla_put_failure: 906 nlmsg_free(msg); 907 return ret; 908 } 909 910 911 static int set_active_rx_sa(const struct macsec_genl_ctx *ctx, int ifindex, 912 u64 sci, unsigned char an, Boolean state) 913 { 914 struct nl_msg *msg; 915 struct nlattr *nest; 916 int ret = -1; 917 918 msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, ifindex); 919 if (!msg) 920 return ret; 921 922 if (nla_put_rxsc_config(msg, sci)) 923 goto nla_put_failure; 924 925 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); 926 if (!nest) 927 goto nla_put_failure; 928 929 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an); 930 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state); 931 932 nla_nest_end(msg, nest); 933 934 ret = nl_send_recv(ctx->sk, msg); 935 if (ret < 0) 936 wpa_printf(MSG_ERROR, 937 DRV_PREFIX "%s: failed to communicate: %d (%s)", 938 __func__, ret, nl_geterror(-ret)); 939 940 nla_put_failure: 941 nlmsg_free(msg); 942 return ret; 943 } 944 945 946 /** 947 * macsec_drv_enable_receive_sa - Enable the SA for receive 948 * @priv: private driver interface data from init() 949 * @sa: secure association 950 * Returns: 0 on success, -1 on failure 951 */ 952 static int macsec_drv_enable_receive_sa(void *priv, struct receive_sa *sa) 953 { 954 struct macsec_drv_data *drv = priv; 955 struct macsec_genl_ctx *ctx = &drv->ctx; 956 957 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, 958 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); 959 960 return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci), 961 sa->an, TRUE); 962 } 963 964 965 /** 966 * macsec_drv_disable_receive_sa - Disable SA for receive 967 * @priv: private driver interface data from init() 968 * @sa: secure association 969 * Returns: 0 on success, -1 on failure 970 */ 971 static int macsec_drv_disable_receive_sa(void *priv, struct receive_sa *sa) 972 { 973 struct macsec_drv_data *drv = priv; 974 struct macsec_genl_ctx *ctx = &drv->ctx; 975 976 wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, 977 SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); 978 979 return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci), 980 sa->an, FALSE); 981 } 982 983 984 static struct rtnl_link * lookup_sc(struct nl_cache *cache, int parent, u64 sci) 985 { 986 struct rtnl_link *needle; 987 void *match; 988 989 needle = rtnl_link_macsec_alloc(); 990 if (!needle) 991 return NULL; 992 993 rtnl_link_set_link(needle, parent); 994 rtnl_link_macsec_set_sci(needle, sci); 995 996 match = nl_cache_find(cache, (struct nl_object *) needle); 997 rtnl_link_put(needle); 998 999 return (struct rtnl_link *) match; 1000 } 1001 1002 1003 /** 1004 * macsec_drv_create_transmit_sc - Create secure connection for transmit 1005 * @priv: private driver interface data from init() 1006 * @sc: secure channel 1007 * @conf_offset: confidentiality offset 1008 * Returns: 0 on success, -1 on failure 1009 */ 1010 static int macsec_drv_create_transmit_sc( 1011 void *priv, struct transmit_sc *sc, 1012 unsigned int conf_offset) 1013 { 1014 struct macsec_drv_data *drv = priv; 1015 struct rtnl_link *link; 1016 char *ifname; 1017 u64 sci; 1018 int err; 1019 1020 wpa_printf(MSG_DEBUG, "%s", __func__); 1021 1022 if (!drv->sk) { 1023 wpa_printf(MSG_ERROR, DRV_PREFIX "NULL rtnl socket"); 1024 return -1; 1025 } 1026 1027 link = rtnl_link_macsec_alloc(); 1028 if (!link) { 1029 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link"); 1030 return -1; 1031 } 1032 1033 rtnl_link_set_link(link, drv->parent_ifi); 1034 1035 sci = mka_sci_u64(&sc->sci); 1036 rtnl_link_macsec_set_sci(link, sci); 1037 1038 drv->created_link = TRUE; 1039 1040 err = rtnl_link_add(drv->sk, link, NLM_F_CREATE); 1041 if (err == -NLE_BUSY) { 1042 wpa_printf(MSG_INFO, 1043 DRV_PREFIX "link already exists, using it"); 1044 drv->created_link = FALSE; 1045 } else if (err < 0) { 1046 rtnl_link_put(link); 1047 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't create link: err %d", 1048 err); 1049 return err; 1050 } 1051 1052 rtnl_link_put(link); 1053 1054 nl_cache_refill(drv->sk, drv->link_cache); 1055 link = lookup_sc(drv->link_cache, drv->parent_ifi, sci); 1056 if (!link) { 1057 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't find link"); 1058 return -1; 1059 } 1060 1061 drv->ifi = rtnl_link_get_ifindex(link); 1062 ifname = rtnl_link_get_name(link); 1063 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 1064 rtnl_link_put(link); 1065 1066 drv->link = rtnl_link_macsec_alloc(); 1067 if (!drv->link) { 1068 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link"); 1069 return -1; 1070 } 1071 1072 rtnl_link_set_name(drv->link, drv->ifname); 1073 1074 /* In case some settings have already been done but we couldn't apply 1075 * them. */ 1076 return try_commit(drv); 1077 } 1078 1079 1080 /** 1081 * macsec_drv_delete_transmit_sc - Delete secure connection for transmit 1082 * @priv: private driver interface data from init() 1083 * @sc: secure channel 1084 * Returns: 0 on success, -1 on failure 1085 */ 1086 static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc) 1087 { 1088 struct macsec_drv_data *drv = priv; 1089 int err; 1090 1091 wpa_printf(MSG_DEBUG, "%s", __func__); 1092 1093 if (!drv->sk) 1094 return 0; 1095 1096 if (!drv->created_link) { 1097 rtnl_link_put(drv->link); 1098 drv->link = NULL; 1099 wpa_printf(MSG_DEBUG, DRV_PREFIX 1100 "we didn't create the link, leave it alone"); 1101 return 0; 1102 } 1103 1104 err = rtnl_link_delete(drv->sk, drv->link); 1105 if (err < 0) 1106 wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't delete link"); 1107 rtnl_link_put(drv->link); 1108 drv->link = NULL; 1109 1110 return err; 1111 } 1112 1113 1114 /** 1115 * macsec_drv_create_transmit_sa - Create secure association for transmit 1116 * @priv: private driver interface data from init() 1117 * @sa: secure association 1118 * Returns: 0 on success, -1 on failure 1119 */ 1120 static int macsec_drv_create_transmit_sa(void *priv, struct transmit_sa *sa) 1121 { 1122 struct macsec_drv_data *drv = priv; 1123 struct macsec_genl_ctx *ctx = &drv->ctx; 1124 struct nl_msg *msg; 1125 struct nlattr *nest; 1126 int ret = -1; 1127 1128 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); 1129 1130 msg = msg_prepare(MACSEC_CMD_ADD_TXSA, ctx, drv->ifi); 1131 if (!msg) 1132 return ret; 1133 1134 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); 1135 if (!nest) 1136 goto nla_put_failure; 1137 1138 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); 1139 NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn); 1140 NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier), 1141 &sa->pkey->key_identifier); 1142 NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key); 1143 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_transmit); 1144 1145 nla_nest_end(msg, nest); 1146 1147 ret = nl_send_recv(ctx->sk, msg); 1148 if (ret < 0) { 1149 wpa_printf(MSG_ERROR, 1150 DRV_PREFIX "%s: failed to communicate: %d (%s)", 1151 __func__, ret, nl_geterror(-ret)); 1152 } 1153 1154 nla_put_failure: 1155 nlmsg_free(msg); 1156 return ret; 1157 } 1158 1159 1160 /** 1161 * macsec_drv_delete_transmit_sa - Delete secure association for transmit 1162 * @priv: private driver interface data from init() 1163 * @sa: secure association 1164 * Returns: 0 on success, -1 on failure 1165 */ 1166 static int macsec_drv_delete_transmit_sa(void *priv, struct transmit_sa *sa) 1167 { 1168 struct macsec_drv_data *drv = priv; 1169 struct macsec_genl_ctx *ctx = &drv->ctx; 1170 struct nl_msg *msg; 1171 struct nlattr *nest; 1172 int ret = -1; 1173 1174 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); 1175 1176 msg = msg_prepare(MACSEC_CMD_DEL_TXSA, ctx, drv->ifi); 1177 if (!msg) 1178 return ret; 1179 1180 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); 1181 if (!nest) 1182 goto nla_put_failure; 1183 1184 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); 1185 1186 nla_nest_end(msg, nest); 1187 1188 ret = nl_send_recv(ctx->sk, msg); 1189 if (ret < 0) { 1190 wpa_printf(MSG_ERROR, 1191 DRV_PREFIX "%s: failed to communicate: %d (%s)", 1192 __func__, ret, nl_geterror(-ret)); 1193 } 1194 1195 nla_put_failure: 1196 nlmsg_free(msg); 1197 return ret; 1198 } 1199 1200 1201 static int set_active_tx_sa(const struct macsec_genl_ctx *ctx, int ifindex, 1202 unsigned char an, Boolean state) 1203 { 1204 struct nl_msg *msg; 1205 struct nlattr *nest; 1206 int ret = -1; 1207 1208 msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, ifindex); 1209 if (!msg) 1210 return ret; 1211 1212 nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); 1213 if (!nest) 1214 goto nla_put_failure; 1215 1216 NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an); 1217 NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state); 1218 1219 nla_nest_end(msg, nest); 1220 1221 ret = nl_send_recv(ctx->sk, msg); 1222 if (ret < 0) { 1223 wpa_printf(MSG_ERROR, 1224 DRV_PREFIX "%s: failed to communicate: %d (%s)", 1225 __func__, ret, nl_geterror(-ret)); 1226 } 1227 1228 nla_put_failure: 1229 nlmsg_free(msg); 1230 return ret; 1231 } 1232 1233 1234 /** 1235 * macsec_drv_enable_transmit_sa - Enable SA for transmit 1236 * @priv: private driver interface data from init() 1237 * @sa: secure association 1238 * Returns: 0 on success, -1 on failure 1239 */ 1240 static int macsec_drv_enable_transmit_sa(void *priv, struct transmit_sa *sa) 1241 { 1242 struct macsec_drv_data *drv = priv; 1243 struct macsec_genl_ctx *ctx = &drv->ctx; 1244 int ret; 1245 1246 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); 1247 1248 ret = set_active_tx_sa(ctx, drv->ifi, sa->an, TRUE); 1249 if (ret < 0) { 1250 wpa_printf(MSG_ERROR, DRV_PREFIX "failed to enable txsa"); 1251 return ret; 1252 } 1253 1254 drv->encoding_sa_set = TRUE; 1255 drv->encoding_sa = sa->an; 1256 1257 return try_commit(drv); 1258 } 1259 1260 1261 /** 1262 * macsec_drv_disable_transmit_sa - Disable SA for transmit 1263 * @priv: private driver interface data from init() 1264 * @sa: secure association 1265 * Returns: 0 on success, -1 on failure 1266 */ 1267 static int macsec_drv_disable_transmit_sa(void *priv, struct transmit_sa *sa) 1268 { 1269 struct macsec_drv_data *drv = priv; 1270 struct macsec_genl_ctx *ctx = &drv->ctx; 1271 1272 wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); 1273 1274 return set_active_tx_sa(ctx, drv->ifi, sa->an, FALSE); 1275 } 1276 1277 1278 const struct wpa_driver_ops wpa_driver_macsec_linux_ops = { 1279 .name = "macsec_linux", 1280 .desc = "MACsec Ethernet driver for Linux", 1281 .get_ssid = driver_wired_get_ssid, 1282 .get_bssid = driver_wired_get_bssid, 1283 .get_capa = driver_wired_get_capa, 1284 .init = macsec_drv_wpa_init, 1285 .deinit = macsec_drv_wpa_deinit, 1286 1287 .macsec_init = macsec_drv_macsec_init, 1288 .macsec_deinit = macsec_drv_macsec_deinit, 1289 .macsec_get_capability = macsec_drv_get_capability, 1290 .enable_protect_frames = macsec_drv_enable_protect_frames, 1291 .enable_encrypt = macsec_drv_enable_encrypt, 1292 .set_replay_protect = macsec_drv_set_replay_protect, 1293 .set_current_cipher_suite = macsec_drv_set_current_cipher_suite, 1294 .enable_controlled_port = macsec_drv_enable_controlled_port, 1295 .get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn, 1296 .get_transmit_next_pn = macsec_drv_get_transmit_next_pn, 1297 .set_transmit_next_pn = macsec_drv_set_transmit_next_pn, 1298 .create_receive_sc = macsec_drv_create_receive_sc, 1299 .delete_receive_sc = macsec_drv_delete_receive_sc, 1300 .create_receive_sa = macsec_drv_create_receive_sa, 1301 .delete_receive_sa = macsec_drv_delete_receive_sa, 1302 .enable_receive_sa = macsec_drv_enable_receive_sa, 1303 .disable_receive_sa = macsec_drv_disable_receive_sa, 1304 .create_transmit_sc = macsec_drv_create_transmit_sc, 1305 .delete_transmit_sc = macsec_drv_delete_transmit_sc, 1306 .create_transmit_sa = macsec_drv_create_transmit_sa, 1307 .delete_transmit_sa = macsec_drv_delete_transmit_sa, 1308 .enable_transmit_sa = macsec_drv_enable_transmit_sa, 1309 .disable_transmit_sa = macsec_drv_disable_transmit_sa, 1310 }; 1311