Patch to support MACsec HW offload

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Using wpa_supplicant to configure MACsec via the linux driver, but there is currently no support for creating MACsec interfaces that offload MACsec to the hardware, even though the linux MACsec implementation supports it.

I have attached a patch I made for wpa_supplicant ver. 2.9 that adds a macsec_hw_offload parameter:

     * 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;

The patch has been tested with wpa_supplicant ver. 2.9 on a hardware board with a HW MACsec solution.

/Benny
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
_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap

[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux