Message ID | 20230214082657.20468-1-ehakim@nvidia.com |
---|---|
State | Accepted |
Headers | show |
Series | [1/2] mka: Allow configuration of MACsec hardware offload | expand |
++ sd@queasysnail.net add missing maintainer of relevant subsystem > -----Original Message----- > From: Emeel Hakim <ehakim@nvidia.com> > Sent: Tuesday, 14 February 2023 10:27 > To: hostap@lists.infradead.org > Cc: Emeel Hakim <ehakim@nvidia.com> > Subject: [PATCH 1/2] mka: Allow configuration of MACsec hardware offload > > Add new configuration parameter macsec_offload to allow user to set up MACsec > hardware offload feature. > > Signed-off-by: Emeel Hakim <ehakim@nvidia.com> > --- > hostapd/config_file.c | 11 +++++++++++ > hostapd/hostapd.conf | 8 ++++++++ > src/ap/ap_config.h | 13 +++++++++++++ > src/ap/wpa_auth_kay.c | 1 + > src/drivers/driver.h | 10 ++++++++++ > src/pae/ieee802_1x_cp.c | 8 ++++++++ > src/pae/ieee802_1x_kay.c | 8 ++++++-- > src/pae/ieee802_1x_kay.h | 7 +++++-- > src/pae/ieee802_1x_secy_ops.c | 20 ++++++++++++++++++++ > src/pae/ieee802_1x_secy_ops.h | 1 + > wpa_supplicant/config.c | 1 + > wpa_supplicant/config_file.c | 1 + > wpa_supplicant/config_ssid.h | 12 ++++++++++++ > wpa_supplicant/driver_i.h | 8 ++++++++ > wpa_supplicant/wpa_cli.c | 1 + > wpa_supplicant/wpa_supplicant.conf | 9 +++++++++ > wpa_supplicant/wpas_kay.c | 8 +++++++- > 17 files changed, 122 insertions(+), 5 deletions(-) > > diff --git a/hostapd/config_file.c b/hostapd/config_file.c index > 76f9cf831..e1ad0bf00 100644 > --- a/hostapd/config_file.c > +++ b/hostapd/config_file.c > @@ -4636,6 +4636,17 @@ static int hostapd_config_fill(struct hostapd_config > *conf, > bss->macsec_replay_protect = macsec_replay_protect; > } else if (os_strcmp(buf, "macsec_replay_window") == 0) { > bss->macsec_replay_window = atoi(pos); > + } else if (os_strcmp(buf, "macsec_offload") == 0) { > + int macsec_offload = atoi(pos); > + > + if (macsec_offload < 0 || macsec_offload > 2) { > + wpa_printf(MSG_ERROR, > + "Line %d: invalid macsec_offload (%d): '%s'.", > + line, macsec_offload, pos); > + return 1; > + } > + bss->macsec_offload = macsec_offload; > + > } else if (os_strcmp(buf, "macsec_port") == 0) { > int macsec_port = atoi(pos); > > diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index > c5e74a6a2..0e5b8d82b 100644 > --- a/hostapd/hostapd.conf > +++ b/hostapd/hostapd.conf > @@ -1117,6 +1117,14 @@ eapol_key_index_workaround=0 # 0: No replay > window, strict check (default) # 1..2^32-1: number of packets that could be > misordered # > +# macsec_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_OFFLOAD_OFF (default) # 1 = MACSEC_OFFLOAD_PHY # 2 = > +MACSEC_OFFLOAD_MAC # > # macsec_port: IEEE 802.1X/MACsec port > # Port component of the SCI > # Range: 1-65534 (default: 1) > diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 1631cf2aa..dfe259c30 > 100644 > --- a/src/ap/ap_config.h > +++ b/src/ap/ap_config.h > @@ -844,6 +844,19 @@ struct hostapd_bss_config { > */ > u32 macsec_replay_window; > > + /** > + * macsec_offload - Enable MACsec 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_OFFLOAD_OFF (default) > + * 1 = MACSEC_OFFLOAD_PHY > + * 2 = MACSEC_OFFLOAD_MAC > + */ > + int macsec_offload; > + > /** > * macsec_port - MACsec port (in SCI) > * > diff --git a/src/ap/wpa_auth_kay.c b/src/ap/wpa_auth_kay.c index > e2c4e109e..664ab8872 100644 > --- a/src/ap/wpa_auth_kay.c > +++ b/src/ap/wpa_auth_kay.c > @@ -327,6 +327,7 @@ int ieee802_1x_alloc_kay_sm_hapd(struct hostapd_data > *hapd, > res = ieee802_1x_kay_init(kay_ctx, policy, > hapd->conf->macsec_replay_protect, > hapd->conf->macsec_replay_window, > + hapd->conf->macsec_offload, > hapd->conf->macsec_port, > hapd->conf->mka_priority, > hapd->conf->macsec_csindex, > diff --git a/src/drivers/driver.h b/src/drivers/driver.h index cb27282aa..a6171b3ef > 100644 > --- a/src/drivers/driver.h > +++ b/src/drivers/driver.h > @@ -4505,6 +4505,16 @@ struct wpa_driver_ops { > */ > int (*set_replay_protect)(void *priv, bool enabled, u32 window); > > + /** > + * set_offload - Set offload > + * @priv: Private driver interface data > + * @offload: 0 = MACSEC_OFFLOAD_OFF > + * 1 = MACSEC_OFFLOAD_PHY > + * 2 = MACSEC_OFFLOAD_MAC > + * Returns: 0 on success, -1 on failure (or if not supported) > + */ > + int (*set_offload)(void *priv, u8 offload); > + > /** > * set_current_cipher_suite - Set current cipher suite > * @priv: Private driver interface data diff --git a/src/pae/ieee802_1x_cp.c > b/src/pae/ieee802_1x_cp.c index 2bf3e8e8c..e9782174d 100644 > --- a/src/pae/ieee802_1x_cp.c > +++ b/src/pae/ieee802_1x_cp.c > @@ -84,6 +84,7 @@ struct ieee802_1x_cp_sm { > > /* not defined IEEE Std 802.1X-2010 */ > struct ieee802_1x_kay *kay; > + u8 offload; > }; > > static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx, @@ -188,6 > +189,7 @@ SM_STATE(CP, AUTHENTICATED) > sm->protect_frames = false; > sm->replay_protect = false; > sm->validate_frames = Checked; > + sm->offload = sm->kay->macsec_offload; > > sm->port_valid = false; > sm->controlled_port_enabled = true; > @@ -197,6 +199,7 @@ SM_STATE(CP, AUTHENTICATED) > secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); > secy_cp_control_validate_frames(sm->kay, sm->validate_frames); > secy_cp_control_replay(sm->kay, sm->replay_protect, sm- > >replay_window); > + secy_cp_control_offload(sm->kay, sm->offload); > } > > > @@ -208,6 +211,7 @@ SM_STATE(CP, SECURED) > > sm->protect_frames = sm->kay->macsec_protect; > sm->replay_protect = sm->kay->macsec_replay_protect; > + sm->offload = sm->kay->macsec_offload; > sm->validate_frames = sm->kay->macsec_validate; > > sm->current_cipher_suite = sm->cipher_suite; @@ -223,6 +227,7 @@ > SM_STATE(CP, SECURED) > secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); > secy_cp_control_validate_frames(sm->kay, sm->validate_frames); > secy_cp_control_replay(sm->kay, sm->replay_protect, sm- > >replay_window); > + secy_cp_control_offload(sm->kay, sm->offload); > } > > > @@ -462,6 +467,7 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct > ieee802_1x_kay *kay) > sm->validate_frames = kay->macsec_validate; > sm->replay_protect = kay->macsec_replay_protect; > sm->replay_window = kay->macsec_replay_window; > + sm->offload = kay->macsec_offload; > > sm->controlled_port_enabled = false; > > @@ -491,6 +497,8 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct > ieee802_1x_kay *kay) > secy_cp_control_confidentiality_offset(sm->kay, > sm->confidentiality_offset); > secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite); > + secy_cp_control_offload(sm->kay, sm->offload); > + > > SM_STEP_RUN(CP); > > diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c index > a1f8ae934..7c05263c5 100644 > --- a/src/pae/ieee802_1x_kay.c > +++ b/src/pae/ieee802_1x_kay.c > @@ -3464,8 +3464,9 @@ static void kay_l2_receive(void *ctx, const u8 *src_addr, > const u8 *buf, struct ieee802_1x_kay * ieee802_1x_kay_init(struct > ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, > bool macsec_replay_protect, u32 macsec_replay_window, > - u16 port, u8 priority, u32 macsec_csindex, > - const char *ifname, const u8 *addr) > + u8 macsec_offload, u16 port, u8 priority, > + u32 macsec_csindex, const char *ifname, > + const u8 *addr) > { > struct ieee802_1x_kay *kay; > > @@ -3524,6 +3525,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, > enum macsec_policy policy, > kay->macsec_validate = Disabled; > kay->macsec_replay_protect = false; > kay->macsec_replay_window = 0; > + kay->macsec_offload = 0; > kay->macsec_confidentiality = CONFIDENTIALITY_NONE; > kay->mka_hello_time = MKA_HELLO_TIME; > } else { > @@ -3540,6 +3542,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, > enum macsec_policy policy, > kay->macsec_validate = Strict; > kay->macsec_replay_protect = macsec_replay_protect; > kay->macsec_replay_window = macsec_replay_window; > + kay->macsec_offload = macsec_offload; > kay->mka_hello_time = MKA_HELLO_TIME; > } > > @@ -3740,6 +3743,7 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay > *kay, > secy_cp_control_protect_frames(kay, kay->macsec_protect); > secy_cp_control_replay(kay, kay->macsec_replay_protect, > kay->macsec_replay_window); > + secy_cp_control_offload(kay, kay->macsec_offload); > if (secy_create_transmit_sc(kay, participant->txsc)) > goto fail; > > diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h index > 11cf7b758..3aad6d2ed 100644 > --- a/src/pae/ieee802_1x_kay.h > +++ b/src/pae/ieee802_1x_kay.h > @@ -166,6 +166,7 @@ struct ieee802_1x_kay_ctx { > int (*delete_transmit_sa)(void *ctx, struct transmit_sa *sa); > int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa); > int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa); > + int (*set_offload)(void *ctx, u8 offload); > }; > > struct ieee802_1x_kay { > @@ -206,6 +207,7 @@ struct ieee802_1x_kay { > bool is_key_server; > bool is_obliged_key_server; > char if_name[IFNAMSIZ]; > + u8 macsec_offload; > > unsigned int macsec_csindex; /* MACsec cipher suite table index */ > int mka_algindex; /* MKA alg table index */ @@ -240,8 +242,9 @@ u64 > mka_sci_u64(struct ieee802_1x_mka_sci *sci); struct ieee802_1x_kay * > ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, > bool macsec_replay_protect, u32 macsec_replay_window, > - u16 port, u8 priority, u32 macsec_csindex, > - const char *ifname, const u8 *addr); > + u8 macsec_offload, u16 port, u8 priority, > + u32 macsec_csindex, const char *ifname, > + const u8 *addr); > void ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay); > > struct ieee802_1x_mka_participant * > diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c index > 0f36e6b53..f35baadbf 100644 > --- a/src/pae/ieee802_1x_secy_ops.c > +++ b/src/pae/ieee802_1x_secy_ops.c > @@ -85,6 +85,26 @@ int secy_cp_control_replay(struct ieee802_1x_kay *kay, bool > enabled, u32 win) } > > > +int secy_cp_control_offload(struct ieee802_1x_kay *kay, u8 offload) { > + struct ieee802_1x_kay_ctx *ops; > + > + if (!kay) { > + wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); > + return -1; > + } > + > + ops = kay->ctx; > + if (!ops || !ops->set_offload) { > + wpa_printf(MSG_ERROR, > + "KaY: secy set_offload operation not supported"); > + return -1; > + } > + > + return ops->set_offload(ops->ctx, offload); } > + > + > int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs) { > struct ieee802_1x_kay_ctx *ops; > diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h index > 18c06f665..b82507bca 100644 > --- a/src/pae/ieee802_1x_secy_ops.h > +++ b/src/pae/ieee802_1x_secy_ops.h > @@ -23,6 +23,7 @@ int secy_cp_control_validate_frames(struct ieee802_1x_kay > *kay, int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, bool flag); > int secy_cp_control_encrypt(struct ieee802_1x_kay *kay, bool enabled); int > secy_cp_control_replay(struct ieee802_1x_kay *kay, bool flag, u32 win); > +int secy_cp_control_offload(struct ieee802_1x_kay *kay, u8 offload); > int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs); int > secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay, > enum confidentiality_offset co); diff --git > a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 9477ad472..eed53f155 > 100644 > --- a/wpa_supplicant/config.c > +++ b/wpa_supplicant/config.c > @@ -2677,6 +2677,7 @@ static const struct parse_data ssid_fields[] = { > { INT_RANGE(macsec_integ_only, 0, 1) }, > { INT_RANGE(macsec_replay_protect, 0, 1) }, > { INT(macsec_replay_window) }, > + { INT_RANGE(macsec_offload, 0, 2) }, > { INT_RANGE(macsec_port, 1, 65534) }, > { INT_RANGE(mka_priority, 0, 255) }, > { INT_RANGE(macsec_csindex, 0, 1) }, > diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index > 4d50f44a8..3cbf9b1e8 100644 > --- a/wpa_supplicant/config_file.c > +++ b/wpa_supplicant/config_file.c > @@ -814,6 +814,7 @@ static void wpa_config_write_network(FILE *f, struct > wpa_ssid *ssid) > INT(macsec_integ_only); > INT(macsec_replay_protect); > INT(macsec_replay_window); > + INT(macsec_offload); > INT(macsec_port); > INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER); > INT(macsec_csindex); > diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index > 4d89e04b9..d3136a66b 100644 > --- a/wpa_supplicant/config_ssid.h > +++ b/wpa_supplicant/config_ssid.h > @@ -926,6 +926,18 @@ struct wpa_ssid { > */ > u32 macsec_replay_window; > > + /** > + * macsec_offload - Enable MACsec hardware offload > + * > + * This setting applies only when MACsec is in use, i.e., > + * - the key server has decided to enable MACsec > + * > + * 0 = MACSEC_OFFLOAD_OFF (default) > + * 1 = MACSEC_OFFLOAD_PHY > + * 2 = MACSEC_OFFLOAD_MAC > + */ > + int macsec_offload; > + > /** > * macsec_port - MACsec port (in SCI) > * > diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index > 5dd2a514c..cfce5fa6a 100644 > --- a/wpa_supplicant/driver_i.h > +++ b/wpa_supplicant/driver_i.h > @@ -803,6 +803,14 @@ static inline int wpa_drv_set_replay_protect(struct > wpa_supplicant *wpa_s, > window); > } > > +static inline int wpa_drv_set_offload(struct wpa_supplicant *wpa_s, u8 > +offload) { > + if (!wpa_s->driver->set_offload) > + return -1; > + return wpa_s->driver->set_offload(wpa_s->drv_priv, offload); > + > +} > + > static inline int wpa_drv_set_current_cipher_suite(struct wpa_supplicant *wpa_s, > u64 cs) > { > diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index > bfdc42de4..f808ac424 100644 > --- a/wpa_supplicant/wpa_cli.c > +++ b/wpa_supplicant/wpa_cli.c > @@ -1487,6 +1487,7 @@ static const char *network_fields[] = { > "macsec_integ_only", > "macsec_replay_protect", > "macsec_replay_window", > + "macsec_offload", > "macsec_port", > "mka_priority", > #endif /* CONFIG_MACSEC */ > diff --git a/wpa_supplicant/wpa_supplicant.conf > b/wpa_supplicant/wpa_supplicant.conf > index 1bb3cc18b..f0b82443e 100644 > --- a/wpa_supplicant/wpa_supplicant.conf > +++ b/wpa_supplicant/wpa_supplicant.conf > @@ -1142,6 +1142,15 @@ fast_reauth=1 > # 0: No replay window, strict check (default) # 1..2^32-1: number of packets that > could be misordered # > +# macsec_offload - Enable MACsec hardware offload # # This setting > +applies only when MACsec is in use, i.e., # - the key server has > +decided to enable MACsec # # 0 = MACSEC_OFFLOAD_OFF (default) # 1 = > +MACSEC_OFFLOAD_PHY # 2 = MACSEC_OFFLOAD_MAC # > # macsec_port: IEEE 802.1X/MACsec port > # Port component of the SCI > # Range: 1-65534 (default: 1) > diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c index > c3ef93bf7..4eb1d5a81 100644 > --- a/wpa_supplicant/wpas_kay.c > +++ b/wpa_supplicant/wpas_kay.c > @@ -97,6 +97,10 @@ static int wpas_set_receive_lowest_pn(void *wpa_s, struct > receive_sa *sa) > return wpa_drv_set_receive_lowest_pn(wpa_s, sa); } > > +static int wpas_set_offload(void *wpa_s, u8 offload) { > + return wpa_drv_set_offload(wpa_s, offload); } > > static unsigned int conf_offset_val(enum confidentiality_offset co) { @@ -219,6 > +223,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct > wpa_ssid *ssid) > kay_ctx->enable_protect_frames = wpas_enable_protect_frames; > kay_ctx->enable_encrypt = wpas_enable_encrypt; > kay_ctx->set_replay_protect = wpas_set_replay_protect; > + kay_ctx->set_offload = wpas_set_offload; > kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite; > kay_ctx->enable_controlled_port = wpas_enable_controlled_port; > kay_ctx->get_receive_lowest_pn = wpas_get_receive_lowest_pn; @@ - > 239,7 +244,8 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, > struct wpa_ssid *ssid) > kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; > > res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_replay_protect, > - ssid->macsec_replay_window, ssid->macsec_port, > + ssid->macsec_replay_window, > + ssid->macsec_offload, ssid->macsec_port, > ssid->mka_priority, ssid->macsec_csindex, > wpa_s->ifname, wpa_s->own_addr); > /* ieee802_1x_kay_init() frees kay_ctx on failure */ > -- > 2.21.3
diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 76f9cf831..e1ad0bf00 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -4636,6 +4636,17 @@ static int hostapd_config_fill(struct hostapd_config *conf, bss->macsec_replay_protect = macsec_replay_protect; } else if (os_strcmp(buf, "macsec_replay_window") == 0) { bss->macsec_replay_window = atoi(pos); + } else if (os_strcmp(buf, "macsec_offload") == 0) { + int macsec_offload = atoi(pos); + + if (macsec_offload < 0 || macsec_offload > 2) { + wpa_printf(MSG_ERROR, + "Line %d: invalid macsec_offload (%d): '%s'.", + line, macsec_offload, pos); + return 1; + } + bss->macsec_offload = macsec_offload; + } else if (os_strcmp(buf, "macsec_port") == 0) { int macsec_port = atoi(pos); diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index c5e74a6a2..0e5b8d82b 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1117,6 +1117,14 @@ eapol_key_index_workaround=0 # 0: No replay window, strict check (default) # 1..2^32-1: number of packets that could be misordered # +# macsec_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_OFFLOAD_OFF (default) +# 1 = MACSEC_OFFLOAD_PHY +# 2 = MACSEC_OFFLOAD_MAC +# # macsec_port: IEEE 802.1X/MACsec port # Port component of the SCI # Range: 1-65534 (default: 1) diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 1631cf2aa..dfe259c30 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -844,6 +844,19 @@ struct hostapd_bss_config { */ u32 macsec_replay_window; + /** + * macsec_offload - Enable MACsec 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_OFFLOAD_OFF (default) + * 1 = MACSEC_OFFLOAD_PHY + * 2 = MACSEC_OFFLOAD_MAC + */ + int macsec_offload; + /** * macsec_port - MACsec port (in SCI) * diff --git a/src/ap/wpa_auth_kay.c b/src/ap/wpa_auth_kay.c index e2c4e109e..664ab8872 100644 --- a/src/ap/wpa_auth_kay.c +++ b/src/ap/wpa_auth_kay.c @@ -327,6 +327,7 @@ int ieee802_1x_alloc_kay_sm_hapd(struct hostapd_data *hapd, res = ieee802_1x_kay_init(kay_ctx, policy, hapd->conf->macsec_replay_protect, hapd->conf->macsec_replay_window, + hapd->conf->macsec_offload, hapd->conf->macsec_port, hapd->conf->mka_priority, hapd->conf->macsec_csindex, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index cb27282aa..a6171b3ef 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4505,6 +4505,16 @@ struct wpa_driver_ops { */ int (*set_replay_protect)(void *priv, bool enabled, u32 window); + /** + * set_offload - Set offload + * @priv: Private driver interface data + * @offload: 0 = MACSEC_OFFLOAD_OFF + * 1 = MACSEC_OFFLOAD_PHY + * 2 = MACSEC_OFFLOAD_MAC + * Returns: 0 on success, -1 on failure (or if not supported) + */ + int (*set_offload)(void *priv, u8 offload); + /** * set_current_cipher_suite - Set current cipher suite * @priv: Private driver interface data diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c index 2bf3e8e8c..e9782174d 100644 --- a/src/pae/ieee802_1x_cp.c +++ b/src/pae/ieee802_1x_cp.c @@ -84,6 +84,7 @@ struct ieee802_1x_cp_sm { /* not defined IEEE Std 802.1X-2010 */ struct ieee802_1x_kay *kay; + u8 offload; }; static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx, @@ -188,6 +189,7 @@ SM_STATE(CP, AUTHENTICATED) sm->protect_frames = false; sm->replay_protect = false; sm->validate_frames = Checked; + sm->offload = sm->kay->macsec_offload; sm->port_valid = false; sm->controlled_port_enabled = true; @@ -197,6 +199,7 @@ SM_STATE(CP, AUTHENTICATED) secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); secy_cp_control_validate_frames(sm->kay, sm->validate_frames); secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); + secy_cp_control_offload(sm->kay, sm->offload); } @@ -208,6 +211,7 @@ SM_STATE(CP, SECURED) sm->protect_frames = sm->kay->macsec_protect; sm->replay_protect = sm->kay->macsec_replay_protect; + sm->offload = sm->kay->macsec_offload; sm->validate_frames = sm->kay->macsec_validate; sm->current_cipher_suite = sm->cipher_suite; @@ -223,6 +227,7 @@ SM_STATE(CP, SECURED) secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); secy_cp_control_validate_frames(sm->kay, sm->validate_frames); secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); + secy_cp_control_offload(sm->kay, sm->offload); } @@ -462,6 +467,7 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay) sm->validate_frames = kay->macsec_validate; sm->replay_protect = kay->macsec_replay_protect; sm->replay_window = kay->macsec_replay_window; + sm->offload = kay->macsec_offload; sm->controlled_port_enabled = false; @@ -491,6 +497,8 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay) secy_cp_control_confidentiality_offset(sm->kay, sm->confidentiality_offset); secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite); + secy_cp_control_offload(sm->kay, sm->offload); + SM_STEP_RUN(CP); diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c index a1f8ae934..7c05263c5 100644 --- a/src/pae/ieee802_1x_kay.c +++ b/src/pae/ieee802_1x_kay.c @@ -3464,8 +3464,9 @@ static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf, struct ieee802_1x_kay * ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, bool macsec_replay_protect, u32 macsec_replay_window, - u16 port, u8 priority, u32 macsec_csindex, - const char *ifname, const u8 *addr) + u8 macsec_offload, u16 port, u8 priority, + u32 macsec_csindex, const char *ifname, + const u8 *addr) { struct ieee802_1x_kay *kay; @@ -3524,6 +3525,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, kay->macsec_validate = Disabled; kay->macsec_replay_protect = false; kay->macsec_replay_window = 0; + kay->macsec_offload = 0; kay->macsec_confidentiality = CONFIDENTIALITY_NONE; kay->mka_hello_time = MKA_HELLO_TIME; } else { @@ -3540,6 +3542,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, kay->macsec_validate = Strict; kay->macsec_replay_protect = macsec_replay_protect; kay->macsec_replay_window = macsec_replay_window; + kay->macsec_offload = macsec_offload; kay->mka_hello_time = MKA_HELLO_TIME; } @@ -3740,6 +3743,7 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, secy_cp_control_protect_frames(kay, kay->macsec_protect); secy_cp_control_replay(kay, kay->macsec_replay_protect, kay->macsec_replay_window); + secy_cp_control_offload(kay, kay->macsec_offload); if (secy_create_transmit_sc(kay, participant->txsc)) goto fail; diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h index 11cf7b758..3aad6d2ed 100644 --- a/src/pae/ieee802_1x_kay.h +++ b/src/pae/ieee802_1x_kay.h @@ -166,6 +166,7 @@ struct ieee802_1x_kay_ctx { int (*delete_transmit_sa)(void *ctx, struct transmit_sa *sa); int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa); int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa); + int (*set_offload)(void *ctx, u8 offload); }; struct ieee802_1x_kay { @@ -206,6 +207,7 @@ struct ieee802_1x_kay { bool is_key_server; bool is_obliged_key_server; char if_name[IFNAMSIZ]; + u8 macsec_offload; unsigned int macsec_csindex; /* MACsec cipher suite table index */ int mka_algindex; /* MKA alg table index */ @@ -240,8 +242,9 @@ u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci); struct ieee802_1x_kay * ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, bool macsec_replay_protect, u32 macsec_replay_window, - u16 port, u8 priority, u32 macsec_csindex, - const char *ifname, const u8 *addr); + u8 macsec_offload, u16 port, u8 priority, + u32 macsec_csindex, const char *ifname, + const u8 *addr); void ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay); struct ieee802_1x_mka_participant * diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c index 0f36e6b53..f35baadbf 100644 --- a/src/pae/ieee802_1x_secy_ops.c +++ b/src/pae/ieee802_1x_secy_ops.c @@ -85,6 +85,26 @@ int secy_cp_control_replay(struct ieee802_1x_kay *kay, bool enabled, u32 win) } +int secy_cp_control_offload(struct ieee802_1x_kay *kay, u8 offload) +{ + struct ieee802_1x_kay_ctx *ops; + + if (!kay) { + wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); + return -1; + } + + ops = kay->ctx; + if (!ops || !ops->set_offload) { + wpa_printf(MSG_ERROR, + "KaY: secy set_offload operation not supported"); + return -1; + } + + return ops->set_offload(ops->ctx, offload); +} + + int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs) { struct ieee802_1x_kay_ctx *ops; diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h index 18c06f665..b82507bca 100644 --- a/src/pae/ieee802_1x_secy_ops.h +++ b/src/pae/ieee802_1x_secy_ops.h @@ -23,6 +23,7 @@ int secy_cp_control_validate_frames(struct ieee802_1x_kay *kay, int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, bool flag); int secy_cp_control_encrypt(struct ieee802_1x_kay *kay, bool enabled); int secy_cp_control_replay(struct ieee802_1x_kay *kay, bool flag, u32 win); +int secy_cp_control_offload(struct ieee802_1x_kay *kay, u8 offload); int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs); int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay, enum confidentiality_offset co); diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 9477ad472..eed53f155 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2677,6 +2677,7 @@ static const struct parse_data ssid_fields[] = { { INT_RANGE(macsec_integ_only, 0, 1) }, { INT_RANGE(macsec_replay_protect, 0, 1) }, { INT(macsec_replay_window) }, + { INT_RANGE(macsec_offload, 0, 2) }, { INT_RANGE(macsec_port, 1, 65534) }, { INT_RANGE(mka_priority, 0, 255) }, { INT_RANGE(macsec_csindex, 0, 1) }, diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 4d50f44a8..3cbf9b1e8 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -814,6 +814,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT(macsec_integ_only); INT(macsec_replay_protect); INT(macsec_replay_window); + INT(macsec_offload); INT(macsec_port); INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER); INT(macsec_csindex); diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 4d89e04b9..d3136a66b 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -926,6 +926,18 @@ struct wpa_ssid { */ u32 macsec_replay_window; + /** + * macsec_offload - Enable MACsec hardware offload + * + * This setting applies only when MACsec is in use, i.e., + * - the key server has decided to enable MACsec + * + * 0 = MACSEC_OFFLOAD_OFF (default) + * 1 = MACSEC_OFFLOAD_PHY + * 2 = MACSEC_OFFLOAD_MAC + */ + int macsec_offload; + /** * macsec_port - MACsec port (in SCI) * diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 5dd2a514c..cfce5fa6a 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -803,6 +803,14 @@ static inline int wpa_drv_set_replay_protect(struct wpa_supplicant *wpa_s, window); } +static inline int wpa_drv_set_offload(struct wpa_supplicant *wpa_s, u8 offload) +{ + if (!wpa_s->driver->set_offload) + return -1; + return wpa_s->driver->set_offload(wpa_s->drv_priv, offload); + +} + static inline int wpa_drv_set_current_cipher_suite(struct wpa_supplicant *wpa_s, u64 cs) { diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index bfdc42de4..f808ac424 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1487,6 +1487,7 @@ static const char *network_fields[] = { "macsec_integ_only", "macsec_replay_protect", "macsec_replay_window", + "macsec_offload", "macsec_port", "mka_priority", #endif /* CONFIG_MACSEC */ diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 1bb3cc18b..f0b82443e 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1142,6 +1142,15 @@ fast_reauth=1 # 0: No replay window, strict check (default) # 1..2^32-1: number of packets that could be misordered # +# macsec_offload - Enable MACsec hardware offload +# +# This setting applies only when MACsec is in use, i.e., +# - the key server has decided to enable MACsec +# +# 0 = MACSEC_OFFLOAD_OFF (default) +# 1 = MACSEC_OFFLOAD_PHY +# 2 = MACSEC_OFFLOAD_MAC +# # macsec_port: IEEE 802.1X/MACsec port # Port component of the SCI # Range: 1-65534 (default: 1) diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c index c3ef93bf7..4eb1d5a81 100644 --- a/wpa_supplicant/wpas_kay.c +++ b/wpa_supplicant/wpas_kay.c @@ -97,6 +97,10 @@ static int wpas_set_receive_lowest_pn(void *wpa_s, struct receive_sa *sa) return wpa_drv_set_receive_lowest_pn(wpa_s, sa); } +static int wpas_set_offload(void *wpa_s, u8 offload) +{ + return wpa_drv_set_offload(wpa_s, offload); +} static unsigned int conf_offset_val(enum confidentiality_offset co) { @@ -219,6 +223,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) kay_ctx->enable_protect_frames = wpas_enable_protect_frames; kay_ctx->enable_encrypt = wpas_enable_encrypt; kay_ctx->set_replay_protect = wpas_set_replay_protect; + kay_ctx->set_offload = wpas_set_offload; kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite; kay_ctx->enable_controlled_port = wpas_enable_controlled_port; kay_ctx->get_receive_lowest_pn = wpas_get_receive_lowest_pn; @@ -239,7 +244,8 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_replay_protect, - ssid->macsec_replay_window, ssid->macsec_port, + ssid->macsec_replay_window, + ssid->macsec_offload, ssid->macsec_port, ssid->mka_priority, ssid->macsec_csindex, wpa_s->ifname, wpa_s->own_addr); /* ieee802_1x_kay_init() frees kay_ctx on failure */
Add new configuration parameter macsec_offload to allow user to set up MACsec hardware offload feature. Signed-off-by: Emeel Hakim <ehakim@nvidia.com> --- hostapd/config_file.c | 11 +++++++++++ hostapd/hostapd.conf | 8 ++++++++ src/ap/ap_config.h | 13 +++++++++++++ src/ap/wpa_auth_kay.c | 1 + src/drivers/driver.h | 10 ++++++++++ src/pae/ieee802_1x_cp.c | 8 ++++++++ src/pae/ieee802_1x_kay.c | 8 ++++++-- src/pae/ieee802_1x_kay.h | 7 +++++-- src/pae/ieee802_1x_secy_ops.c | 20 ++++++++++++++++++++ src/pae/ieee802_1x_secy_ops.h | 1 + wpa_supplicant/config.c | 1 + wpa_supplicant/config_file.c | 1 + wpa_supplicant/config_ssid.h | 12 ++++++++++++ wpa_supplicant/driver_i.h | 8 ++++++++ wpa_supplicant/wpa_cli.c | 1 + wpa_supplicant/wpa_supplicant.conf | 9 +++++++++ wpa_supplicant/wpas_kay.c | 8 +++++++- 17 files changed, 122 insertions(+), 5 deletions(-)