Driver/Firmware advertising SAE AP offload support would take care of SAE authentication and PMK generation at driver/firmware. This feature requires the driver to be supporting 4way handshake offload to process the generated PMK at the driver level for 4way handshake. Signed-off-by: Vinayak Yadawad <vinayak.yadawad@xxxxxxxxxxxx> --- src/ap/beacon.c | 27 +++++++++++++++++++++++++++ src/ap/ieee802_11.c | 6 +++--- src/ap/ieee802_11.h | 10 +++++++++- src/ap/wpa_auth.h | 1 + src/ap/wpa_auth_glue.c | 15 +++++++++++++++ src/ap/wpa_auth_ie.c | 29 ++++++++++++++++++++++++----- src/drivers/driver.h | 6 ++++++ src/drivers/driver_nl80211.c | 6 ++++++ src/drivers/driver_nl80211_capa.c | 4 ++++ 9 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/ap/beacon.c b/src/ap/beacon.c index b88aeb03c..6d775f597 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -2026,6 +2026,33 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, resp = hostapd_probe_resp_offloads(hapd, &resp_len); #endif /* NEED_AP_MLME */ +#ifdef CONFIG_SAE + /* If SAE offload is enabled, provide passphrase to lower layer for + * PMK generation + */ + if ((wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt)) && + (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP)) { + if (hostapd_sae_pk_in_use(hapd->conf)) { + wpa_printf(MSG_ERROR, + "sae_pk not supported with SAE offload"); + return -1; + } + + if (hostapd_sae_pw_id_in_use(hapd->conf)) { + wpa_printf(MSG_ERROR, + "sae pw_id not supported with SAE offlaod"); + return -1; + } + + params->sae_password = sae_get_password(hapd, NULL, NULL, NULL, + NULL, NULL); + if (!params->sae_password) { + wpa_printf(MSG_ERROR, "sae password not configured"); + return -1; + } + } +#endif /* CONFIG_SAE */ + params->head = (u8 *) head; params->head_len = head_len; params->tail = tail; diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index d48185a17..73c4a1106 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -540,7 +540,7 @@ static void sae_set_state(struct sta_info *sta, enum sae_state state, } -static const char * sae_get_password(struct hostapd_data *hapd, +const char * sae_get_password(struct hostapd_data *hapd, struct sta_info *sta, const char *rx_id, struct sae_password_entry **pw_entry, @@ -554,7 +554,7 @@ static const char * sae_get_password(struct hostapd_data *hapd, struct hostapd_sta_wpa_psk_short *psk = NULL; for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) { - if (!is_broadcast_ether_addr(pw->peer_addr) && + if (!is_broadcast_ether_addr(pw->peer_addr) && sta && os_memcmp(pw->peer_addr, sta->addr, ETH_ALEN) != 0) continue; if ((rx_id && !pw->identifier) || (!rx_id && pw->identifier)) @@ -573,7 +573,7 @@ static const char * sae_get_password(struct hostapd_data *hapd, pt = hapd->conf->ssid.pt; } - if (!password) { + if (!password && sta) { for (psk = sta->psk; psk; psk = psk->next) { if (psk->is_passphrase) { password = psk->passphrase; diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 8ffce0bf5..8f81c6e7d 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -20,6 +20,9 @@ struct radius_sta; enum ieee80211_op_mode; enum oper_chan_width; struct ieee802_11_elems; +struct sae_pk; +struct sae_pt; +struct sae_password_entry; int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, struct hostapd_frame_info *fi); @@ -238,5 +241,10 @@ u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end, void punct_update_legacy_bw(u16 bitmap, u8 pri_chan, enum oper_chan_width *width, u8 *seg0, u8 *seg1); bool hostapd_is_mld_ap(struct hostapd_data *hapd); - +#ifdef CONFIG_SAE +const char * sae_get_password(struct hostapd_data *hapd, + struct sta_info *sta, const char *rx_id, + struct sae_password_entry **pw_entry, + struct sae_pt **s_pt, const struct sae_pk **s_pk); +#endif /* CONFIG_SAE */ #endif /* IEEE802_11_H */ diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 28eea83d8..d6ed6772b 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -395,6 +395,7 @@ struct wpa_auth_callbacks { int (*get_ml_rsn_info)(void *ctx, struct wpa_auth_ml_rsn_info *info); int (*get_ml_key_info)(void *ctx, struct wpa_auth_ml_key_info *info); #endif /* CONFIG_IEEE80211BE */ + int (*get_drv_flags)(void *ctx, u64 *drv_flags, u64 *drv_flags2); }; struct wpa_authenticator * wpa_init(const u8 *addr, diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 30a72b126..14da825d9 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -1600,6 +1600,20 @@ static int hostapd_wpa_auth_get_ml_key_info(void *ctx, #endif /* CONFIG_IEEE80211BE */ +static int hostapd_wpa_auth_get_drv_flags(void *ctx, + u64 *drv_flags, u64 *drv_flags2) +{ + struct hostapd_data *hapd = ctx; + + if (!drv_flags || !drv_flags2) + return -1; + + *drv_flags = hapd->iface->drv_flags; + *drv_flags2 = hapd->iface->drv_flags2; + + return 0; +} + int hostapd_setup_wpa(struct hostapd_data *hapd) { @@ -1655,6 +1669,7 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) .get_ml_rsn_info = hostapd_wpa_auth_get_ml_rsn_info, .get_ml_key_info = hostapd_wpa_auth_get_ml_key_info, #endif /* CONFIG_IEEE80211BE */ + .get_drv_flags = hostapd_wpa_auth_get_drv_flags, }; const u8 *wpa_ie; size_t wpa_ie_len; diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 9b90e0749..15fb6baaf 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -17,7 +17,7 @@ #include "pmksa_cache_auth.h" #include "wpa_auth_ie.h" #include "wpa_auth_i.h" - +#include "drivers/driver.h" #ifdef CONFIG_RSN_TESTING int rsn_testing = 0; @@ -600,6 +600,14 @@ static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx) return 0; } +static int wpa_auth_get_drv_flags(struct wpa_authenticator *wpa_auth, + u64 *drv_flags, u64 *drv_flags2) +{ + if(!wpa_auth->cb->get_drv_flags) + return -1; + return wpa_auth->cb->get_drv_flags(wpa_auth->cb_ctx, + drv_flags, drv_flags2); +} enum wpa_validate_result wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, @@ -1013,11 +1021,22 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, } #ifdef CONFIG_SAE - if (sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE && data.num_pmkid && - !sm->pmksa) { - wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, + if (sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE) { + u64 drv_flags = 0; + u64 drv_flags2 = 0; + bool ap_sae_offload = false; + + if (!wpa_auth_get_drv_flags(wpa_auth, &drv_flags, + &drv_flags2)) { + ap_sae_offload = + !!(drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP); + } + + if (!ap_sae_offload && data.num_pmkid && !sm->pmksa) { + wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, "No PMKSA cache entry found for SAE"); - return WPA_INVALID_PMKID; + return WPA_INVALID_PMKID; + } } #endif /* CONFIG_SAE */ diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 24016b344..292266c29 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1809,6 +1809,10 @@ struct wpa_driver_ap_params { * mld_link_id - Link id for MLD BSS's */ u8 mld_link_id; + /** + * sae_password - sae password for SAE offload + */ + const char *sae_password; }; struct wpa_driver_mesh_bss_params { @@ -2281,6 +2285,8 @@ struct wpa_driver_capa { #define WPA_DRIVER_FLAGS2_SCAN_MIN_PREQ 0x0000000000008000ULL /** Driver supports SAE authentication offload in STA mode */ #define WPA_DRIVER_FLAGS2_SAE_OFFLOAD_STA 0x0000000000010000ULL +/** Driver support AP SAE authentication offload */ +#define WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP 0x0000000000020000ULL u64 flags2; #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 8b72d74c5..0a4f33d25 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -5110,6 +5110,12 @@ static int wpa_driver_nl80211_set_ap(void *priv, suites)) goto fail; + if (wpa_key_mgmt_sae(params->key_mgmt_suites) && + (drv->capa.flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP) && + params->sae_password && (nla_put(msg, NL80211_ATTR_SAE_PASSWORD, + os_strlen(params->sae_password), params->sae_password))) + goto fail; + if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X_NO_WPA && (!params->pairwise_ciphers || params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40)) && diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index b7d914140..2be1f5cd8 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -705,6 +705,10 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info, if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT)) capa->flags2 |= WPA_DRIVER_FLAGS2_SCAN_MIN_PREQ; + + if (ext_feature_isset(ext_features, len, + NL80211_EXT_FEATURE_SAE_OFFLOAD_AP)) + capa->flags2 |= WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP; } -- 2.32.0
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap