Binary files hostap.org/.git/index and hostap/.git/index differ diff -ruiN hostap.org/src/ap/ap_config.h hostap/src/ap/ap_config.h --- hostap.org/src/ap/ap_config.h 2022-08-26 13:41:54.086948068 +0200 +++ hostap/src/ap/ap_config.h 2022-08-26 13:58:22.439939238 +0200 @@ -763,6 +763,19 @@ int macsec_integ_only; /** + * macsec_hw_offload - Offload MACsec to hardware + * + * This setting applies only when MACsec is in use, i.e., + * - macsec_policy is enabled + * - the key server has decided to enable MACsec + * + * 0: MACsec hardware offload is off (default) + * 1: MACsec hardware offload to PHY + * 2: MACsec hardware offload to MAC + */ + int macsec_hw_offload; + + /** * macsec_replay_protect - Enable MACsec replay protection * * This setting applies only when MACsec is in use, i.e., diff -ruiN hostap.org/src/ap/wpa_auth_kay.c hostap/src/ap/wpa_auth_kay.c --- hostap.org/src/ap/wpa_auth_kay.c 2022-08-26 13:41:54.090948023 +0200 +++ hostap/src/ap/wpa_auth_kay.c 2022-10-05 15:44:48.855797539 +0200 @@ -212,14 +212,15 @@ static int hapd_create_transmit_sc(void *priv, struct transmit_sc *sc, - enum confidentiality_offset co) + enum confidentiality_offset co, u8 hw_offload) { struct hostapd_data *hapd = priv; if (!hapd->driver->create_transmit_sc) return -1; return hapd->driver->create_transmit_sc(hapd->drv_priv, sc, - conf_offset_val(co)); + conf_offset_val(co), + hw_offload); } @@ -328,7 +329,7 @@ res = ieee802_1x_kay_init(kay_ctx, policy, hapd->conf->macsec_replay_protect, hapd->conf->macsec_replay_window, - hapd->conf->macsec_port, + hapd->conf->macsec_port, hapd->conf->macsec_hw_offload, hapd->conf->mka_priority, hapd->conf->iface, hapd->own_addr); /* ieee802_1x_kay_init() frees kay_ctx on failure */ diff -ruiN hostap.org/src/drivers/driver.h hostap/src/drivers/driver.h --- hostap.org/src/drivers/driver.h 2022-08-26 13:41:54.094947978 +0200 +++ hostap/src/drivers/driver.h 2022-08-31 12:09:16.602493820 +0200 @@ -3855,6 +3855,14 @@ int (*set_replay_protect)(void *priv, Boolean enabled, u32 window); /** + * set_hw_offload - Set hardware offload + * @priv: Private driver interface data + * @hw_offload: Hardware offload value + * Returns: 0 on success, -1 on failure (or if not supported) + */ + int (*set_hw_offload)(void *priv, int hw_offload); + + /** * set_current_cipher_suite - Set current cipher suite * @priv: Private driver interface data * @cs: EUI64 identifier @@ -3961,10 +3969,11 @@ * @priv: private driver interface data from init() * @sc: secure channel * @conf_offset: confidentiality offset (0, 30, or 50) + * @hw_offload: Offload to hardware (0=disabled, 1=PHY, 2=MAC) * Returns: 0 on success, -1 on failure */ int (*create_transmit_sc)(void *priv, struct transmit_sc *sc, - unsigned int conf_offset); + unsigned int conf_offset, u8 hw_offload); /** * delete_transmit_sc - delete secure connection for transmit diff -ruiN hostap.org/src/drivers/driver_macsec_linux.c hostap/src/drivers/driver_macsec_linux.c --- hostap.org/src/drivers/driver_macsec_linux.c 2022-08-26 13:41:54.094947978 +0200 +++ hostap/src/drivers/driver_macsec_linux.c 2022-08-31 15:03:11.711333563 +0200 @@ -60,6 +60,7 @@ int ifi; int parent_ifi; int use_pae_group_addr; + int hw_offload; Boolean created_link; @@ -84,6 +85,7 @@ static int dump_callback(struct nl_msg *msg, void *argp); +static int nl_send_recv(struct nl_sock *sk, struct nl_msg *msg); static struct nl_msg * msg_prepare(enum macsec_nl_commands cmd, const struct macsec_genl_ctx *ctx, @@ -455,6 +457,52 @@ /** + * macsec_drv_set_hw_offload - Set hardware offload + * @priv: Private driver interface data + * @hw_offload: Hardware offload value + * Returns: 0 on success, -1 on failure (or if not supported) + */ +static int macsec_drv_set_hw_offload(void *priv, u8 hw_offload) +{ + struct macsec_drv_data *drv = priv; + struct macsec_genl_ctx *ctx = &drv->ctx; + struct nl_msg *msg; + struct nlattr *nest; + int ret = -1; + + wpa_printf(MSG_DEBUG, "%s -> %i", __func__, hw_offload); + + if (hw_offload == drv->hw_offload) + return 0; + + drv->hw_offload = hw_offload; + + msg = msg_prepare(MACSEC_CMD_UPD_OFFLOAD, ctx, drv->ifi); + if (!msg) + return ret; + + nest = nla_nest_start(msg, MACSEC_ATTR_OFFLOAD); + if (!nest) + goto nla_put_failure; + + NLA_PUT_U8(msg, MACSEC_OFFLOAD_ATTR_TYPE, hw_offload); + + nla_nest_end(msg, nest); + + ret = nl_send_recv(ctx->sk, msg); + if (ret < 0) { + wpa_printf(MSG_ERROR, + DRV_PREFIX "failed to communicate: %d (%s)", + ret, nl_geterror(-ret)); + } + + nla_put_failure: + nlmsg_free(msg); + return ret; +} + + +/** * macsec_drv_set_current_cipher_suite - Set current cipher suite * @priv: Private driver interface data * @cs: EUI64 identifier @@ -1086,11 +1134,12 @@ * @priv: private driver interface data from init() * @sc: secure channel * @conf_offset: confidentiality offset + * @hw_offload: Offload to hardware (0=disabled, 1=PHY, 2=MAC) * Returns: 0 on success, -1 on failure */ static int macsec_drv_create_transmit_sc( void *priv, struct transmit_sc *sc, - unsigned int conf_offset) + unsigned int conf_offset, u8 hw_offload) { struct macsec_drv_data *drv = priv; struct rtnl_link *link; @@ -1099,9 +1148,9 @@ int err; wpa_printf(MSG_DEBUG, DRV_PREFIX - "%s: create_transmit_sc -> " SCISTR " (conf_offset=%d)", + "%s: create_transmit_sc -> " SCISTR " (conf_offset=%d hw_offload=%u)", drv->common.ifname, SCI2STR(sc->sci.addr, sc->sci.port), - conf_offset); + conf_offset, hw_offload); if (!drv->sk) { wpa_printf(MSG_ERROR, DRV_PREFIX "NULL rtnl socket"); @@ -1160,7 +1209,10 @@ /* In case some settings have already been done but we couldn't apply * them. */ - return try_commit(drv); + err = try_commit(drv); + if (err) + return err; + return macsec_drv_set_hw_offload(drv, hw_offload); } @@ -1628,6 +1680,7 @@ .enable_protect_frames = macsec_drv_enable_protect_frames, .enable_encrypt = macsec_drv_enable_encrypt, .set_replay_protect = macsec_drv_set_replay_protect, + .set_hw_offload = macsec_drv_set_hw_offload, .set_current_cipher_suite = macsec_drv_set_current_cipher_suite, .enable_controlled_port = macsec_drv_enable_controlled_port, .get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn, diff -ruiN hostap.org/src/drivers/driver_macsec_qca.c hostap/src/drivers/driver_macsec_qca.c --- hostap.org/src/drivers/driver_macsec_qca.c 2022-08-26 13:41:54.094947978 +0200 +++ hostap/src/drivers/driver_macsec_qca.c 2022-08-31 12:09:41.794282192 +0200 @@ -846,7 +846,7 @@ static int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc, - unsigned int conf_offset) + unsigned int conf_offset, u8 hw_offload) { struct macsec_qca_data *drv = priv; int ret; diff -ruiN hostap.org/src/pae/ieee802_1x_kay.c hostap/src/pae/ieee802_1x_kay.c --- hostap.org/src/pae/ieee802_1x_kay.c 2022-08-26 13:41:54.098947933 +0200 +++ hostap/src/pae/ieee802_1x_kay.c 2022-10-05 15:44:01.320289422 +0200 @@ -3419,13 +3419,14 @@ struct ieee802_1x_kay * ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, Boolean macsec_replay_protect, u32 macsec_replay_window, - u16 port, u8 priority, const char *ifname, const u8 *addr) + u16 port, u8 macsec_hw_offload, u8 priority, + const char *ifname, const u8 *addr) { struct ieee802_1x_kay *kay; wpa_printf(MSG_DEBUG, "KaY: Initialize - ifname=%s addr=" MACSTR - " port=%u priority=%u", - ifname, MAC2STR(addr), port, priority); + " port=%u priority=%u macsec_hw_offload=%u", + ifname, MAC2STR(addr), port, priority, macsec_hw_offload); kay = os_zalloc(sizeof(*kay)); if (!kay) { wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); @@ -3478,6 +3479,7 @@ kay->macsec_validate = Disabled; kay->macsec_replay_protect = FALSE; kay->macsec_replay_window = 0; + kay->macsec_hw_offload = 0; kay->macsec_confidentiality = CONFIDENTIALITY_NONE; kay->mka_hello_time = MKA_HELLO_TIME; } else { @@ -3494,6 +3496,7 @@ kay->macsec_validate = Strict; kay->macsec_replay_protect = macsec_replay_protect; kay->macsec_replay_window = macsec_replay_window; + kay->macsec_hw_offload = macsec_hw_offload; kay->mka_hello_time = MKA_HELLO_TIME; } diff -ruiN hostap.org/src/pae/ieee802_1x_kay.h hostap/src/pae/ieee802_1x_kay.h --- hostap.org/src/pae/ieee802_1x_kay.h 2022-08-26 13:41:54.098947933 +0200 +++ hostap/src/pae/ieee802_1x_kay.h 2022-10-05 15:44:13.324165242 +0200 @@ -160,7 +160,8 @@ int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); int (*create_transmit_sc)(void *ctx, struct transmit_sc *sc, - enum confidentiality_offset co); + enum confidentiality_offset co, + u8 hw_offload); int (*delete_transmit_sc)(void *ctx, struct transmit_sc *sc); int (*create_transmit_sa)(void *ctx, struct transmit_sa *sa); int (*delete_transmit_sa)(void *ctx, struct transmit_sa *sa); @@ -185,8 +186,9 @@ Boolean macsec_desired; Boolean macsec_protect; Boolean macsec_encrypt; - Boolean macsec_replay_protect; + Boolean macsec_replay_protect; u32 macsec_replay_window; + u8 macsec_hw_offload; enum validate_frames macsec_validate; enum confidentiality_offset macsec_confidentiality; u32 mka_hello_time; @@ -240,7 +242,8 @@ struct ieee802_1x_kay * ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, Boolean macsec_replay_protect, u32 macsec_replay_window, - u16 port, u8 priority, const char *ifname, const u8 *addr); + u16 port, u8 macsec_hw_offload, u8 priority, + const char *ifname, const u8 *addr); void ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay); struct ieee802_1x_mka_participant * diff -ruiN hostap.org/src/pae/ieee802_1x_secy_ops.c hostap/src/pae/ieee802_1x_secy_ops.c --- hostap.org/src/pae/ieee802_1x_secy_ops.c 2022-08-26 13:41:54.098947933 +0200 +++ hostap/src/pae/ieee802_1x_secy_ops.c 2022-08-31 12:06:38.675795916 +0200 @@ -378,7 +378,7 @@ return -1; } - return ops->create_transmit_sc(ops->ctx, txsc, kay->co); + return ops->create_transmit_sc(ops->ctx, txsc, kay->co, kay->macsec_hw_offload); } diff -ruiN hostap.org/wpa_supplicant/config.c hostap/wpa_supplicant/config.c --- hostap.org/wpa_supplicant/config.c 2022-08-26 13:41:54.114947752 +0200 +++ hostap/wpa_supplicant/config.c 2022-08-26 13:52:13.072026131 +0200 @@ -2383,6 +2383,7 @@ #ifdef CONFIG_MACSEC { INT_RANGE(macsec_policy, 0, 1) }, { INT_RANGE(macsec_integ_only, 0, 1) }, + { INT_RANGE(macsec_hw_offload, 0, 2) }, { INT_RANGE(macsec_replay_protect, 0, 1) }, { INT(macsec_replay_window) }, { INT_RANGE(macsec_port, 1, 65534) }, diff -ruiN hostap.org/wpa_supplicant/config_file.c hostap/wpa_supplicant/config_file.c --- hostap.org/wpa_supplicant/config_file.c 2022-08-26 13:41:54.114947752 +0200 +++ hostap/wpa_supplicant/config_file.c 2022-08-26 13:43:51.637625448 +0200 @@ -864,6 +864,7 @@ write_mka_cak(f, ssid); write_mka_ckn(f, ssid); INT(macsec_integ_only); + INT(macsec_hw_offload); INT(macsec_replay_protect); INT(macsec_replay_window); INT(macsec_port); diff -ruiN hostap.org/wpa_supplicant/config_ssid.h hostap/wpa_supplicant/config_ssid.h --- hostap.org/wpa_supplicant/config_ssid.h 2022-08-26 13:41:54.114947752 +0200 +++ hostap/wpa_supplicant/config_ssid.h 2022-08-26 13:58:30.515850188 +0200 @@ -808,6 +808,19 @@ int macsec_integ_only; /** + * macsec_hw_offload - Offload MACsec to hardware + * + * This setting applies only when MACsec is in use, i.e., + * - macsec_policy is enabled + * - the key server has decided to enable MACsec + * + * 0: MACsec hardware offload is off (default) + * 1: MACsec hardware offload to PHY + * 2: MACsec hardware offload to MAC + */ + int macsec_hw_offload; + + /** * macsec_replay_protect - Enable MACsec replay protection * * This setting applies only when MACsec is in use, i.e., diff -ruiN hostap.org/wpa_supplicant/driver_i.h hostap/wpa_supplicant/driver_i.h --- hostap.org/wpa_supplicant/driver_i.h 2022-08-26 13:41:54.118947707 +0200 +++ hostap/wpa_supplicant/driver_i.h 2022-08-31 12:17:31.282159734 +0200 @@ -874,12 +874,12 @@ static inline int wpa_drv_create_transmit_sc(struct wpa_supplicant *wpa_s, struct transmit_sc *sc, - unsigned int conf_offset) + unsigned int conf_offset, u8 hw_offload) { if (!wpa_s->driver->create_transmit_sc) return -1; return wpa_s->driver->create_transmit_sc(wpa_s->drv_priv, sc, - conf_offset); + conf_offset, hw_offload); } static inline int wpa_drv_delete_transmit_sc(struct wpa_supplicant *wpa_s, diff -ruiN hostap.org/wpa_supplicant/wpa_cli.c hostap/wpa_supplicant/wpa_cli.c --- hostap.org/wpa_supplicant/wpa_cli.c 2022-08-26 13:41:54.118947707 +0200 +++ hostap/wpa_supplicant/wpa_cli.c 2022-08-26 13:52:45.895661835 +0200 @@ -1463,6 +1463,7 @@ #ifdef CONFIG_MACSEC "macsec_policy", "macsec_integ_only", + "macsec_hw_offload", "macsec_replay_protect", "macsec_replay_window", "macsec_port", diff -ruiN hostap.org/wpa_supplicant/wpas_kay.c hostap/wpa_supplicant/wpas_kay.c --- hostap.org/wpa_supplicant/wpas_kay.c 2022-08-26 13:41:54.122947663 +0200 +++ hostap/wpa_supplicant/wpas_kay.c 2022-10-05 15:44:25.864035491 +0200 @@ -152,9 +152,9 @@ static int wpas_create_transmit_sc(void *wpa_s, struct transmit_sc *sc, - enum confidentiality_offset co) + enum confidentiality_offset co, u8 hw_offload) { - return wpa_drv_create_transmit_sc(wpa_s, sc, conf_offset_val(co)); + return wpa_drv_create_transmit_sc(wpa_s, sc, conf_offset_val(co), hw_offload); } @@ -241,6 +241,7 @@ res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_replay_protect, ssid->macsec_replay_window, ssid->macsec_port, + ssid->macsec_hw_offload, ssid->mka_priority, wpa_s->ifname, wpa_s->own_addr); /* ieee802_1x_kay_init() frees kay_ctx on failure */ diff -ruiN hostap.org/wpa_supplicant/wpa_supplicant.conf hostap/wpa_supplicant/wpa_supplicant.conf --- hostap.org/wpa_supplicant/wpa_supplicant.conf 2022-08-26 13:41:54.122947663 +0200 +++ hostap/wpa_supplicant/wpa_supplicant.conf 2022-08-26 13:58:52.815604377 +0200 @@ -1016,6 +1016,14 @@ # 0: Encrypt traffic (default) # 1: Integrity only # +# macsec_hw_offload: IEEE 802.1X/MACsec hardware offload +# This setting applies only when MACsec is in use, i.e., +# - macsec_policy is enabled +# - the key server has decided to enable MACsec +# 0: MACsec hardware offload is off (default) +# 1: MACsec hardware offload to PHY +# 2: MACsec hardware offload to MAC +# # macsec_replay_protect: IEEE 802.1X/MACsec replay protection # This setting applies only when MACsec is in use, i.e., # - macsec_policy is enabled