@@ -32,7 +32,7 @@
#include "dfs.h"
#include "taxonomy.h"
#include "ieee802_11_auth.h"
-
+#include "crypto/sha1.h"
#ifdef NEED_AP_MLME
@@ -2026,6 +2026,17 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
resp = hostapd_probe_resp_offloads(hapd, &resp_len);
#endif /* NEED_AP_MLME */
+ /* If key mgmt offload is enabled, configure PSK */
+ if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
+ (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
+ if (hapd->conf->ssid.wpa_psk && hapd->conf->ssid.wpa_psk_set) {
+ os_memcpy(params->psk, hapd->conf->ssid.wpa_psk->psk, PMK_LEN);
+ } else if (hapd->conf->ssid.wpa_passphrase) {
+ pbkdf2_sha1(hapd->conf->ssid.wpa_passphrase, hapd->conf->ssid.ssid,
+ hapd->conf->ssid.ssid_len, 4096, params->psk, PMK_LEN);
+ }
+ }
+
params->head = (u8 *) head;
params->head_len = head_len;
params->tail = tail;
@@ -2186,6 +2186,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
struct hostapd_data *hapd = ctx;
+ struct sta_info *sta = NULL;
#ifndef CONFIG_NO_STDOUT_DEBUG
int level = MSG_DEBUG;
@@ -2305,6 +2306,15 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->assoc_info.link_addr,
data->assoc_info.reassoc);
break;
+ case EVENT_PORT_AUTHORIZED:
+ /* Port auth event from associated STA */
+ sta = ap_get_sta(hapd, data->port_authorized.sta_addr);
+ if (sta)
+ ap_sta_set_authorized(hapd, sta, 1);
+ else
+ wpa_printf(MSG_DEBUG, "sta info not found");
+ break;
+
#ifdef CONFIG_OWE
case EVENT_UPDATE_DH:
if (!data)
@@ -3573,8 +3573,13 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
sta->auth_alg != WLAN_AUTH_FILS_PK &&
!(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
- } else
+ } else if (!(hapd->iface->drv_flags2 &
+ WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
+ /* 4way HS offloaded STA will have this handled from port auth
+ * event
+ */
wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
+ }
if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) {
if (eloop_cancel_timeout(ap_handle_timer, hapd, sta) > 0) {
@@ -1809,6 +1809,11 @@ struct wpa_driver_ap_params {
* mld_link_id - Link id for MLD BSS's
*/
u8 mld_link_id;
+
+ /**
+ * psk - PSK passed to driver for 4-way HS offload
+ */
+ u8 psk[PMK_LEN];
};
struct wpa_driver_mesh_bss_params {
@@ -2281,6 +2286,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_PSK authentication offload */
+#define WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK 0x0000000000020000ULL
u64 flags2;
#define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
@@ -6668,11 +6675,16 @@ union wpa_event_data {
struct pasn_auth pasn_auth;
/**
- * struct port_authorized - Data for EVENT_PORT_AUTHORIZED
+ * struct port_authorized - Data for EVENT_PORT_AUTHORIZED for STA or AP
+ * to indicate that port is authorized and open for data.
+ * td_bitmap, td_bitmap_len: STA event would indicate td_bitmap if peer AP
+ * notifies the same in EAPOL 3/4.
+ * sta_addr: For AP, this would be the associated STA's macaddr.
*/
struct port_authorized {
const u8 *td_bitmap;
size_t td_bitmap_len;
+ u8 sta_addr[ETH_ALEN];
} port_authorized;
/**
@@ -5110,6 +5110,11 @@ static int wpa_driver_nl80211_set_ap(void *priv,
suites))
goto fail;
+ if ((params->key_mgmt_suites & WPA_KEY_MGMT_PSK) &&
+ (drv->capa.flags & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK) &&
+ (nla_put(msg, NL80211_ATTR_PMK, 32, params->psk)))
+ 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)) &&
@@ -705,6 +705,11 @@ 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_4WAY_HANDSHAKE_AP_PSK))
+ capa->flags2 |= WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK;
+
}
@@ -3506,7 +3506,14 @@ static void nl80211_port_authorized(struct wpa_driver_nl80211_data *drv,
}
addr = nla_data(tb[NL80211_ATTR_MAC]);
- if (os_memcmp(addr, drv->bssid, ETH_ALEN) != 0) {
+ if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
+ /* Update STA assoc address */
+ os_memcpy(event.port_authorized.sta_addr, addr, ETH_ALEN);
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Port authorized for STA addr " MACSTR,
+ MAC2STR(addr));
+ } else if (is_sta_interface(drv->nlmode) &&
+ os_memcmp(addr, drv->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_DEBUG,
"nl80211: Ignore port authorized event for " MACSTR
" (not the currently connected BSSID " MACSTR ")",
@@ -1058,6 +1058,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
return -1;
hapd_iface->owner = wpa_s;
hapd_iface->drv_flags = wpa_s->drv_flags;
+ hapd_iface->drv_flags2 = wpa_s->drv_flags2;
hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
hapd_iface->extended_capa = wpa_s->extended_capa;
hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
@@ -22,6 +22,7 @@
#include "common/wpa_ctrl.h"
#include "eap_peer/eap.h"
#include "ap/hostapd.h"
+#include "ap/sta_info.h"
#include "p2p/p2p.h"
#include "fst/fst.h"
#include "wnm_sta.h"
@@ -6416,7 +6417,20 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
wpa_s, data->port_authorized.td_bitmap[0]);
}
#endif /* CONFIG_NO_WPA */
- wpa_supplicant_event_port_authorized(wpa_s);
+ if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) {
+ /* ap/p2p_go authorizing sta/p2p_gc */
+ struct sta_info *sta = NULL;
+
+ sta = ap_get_sta(wpa_s->ap_iface->bss[0],
+ data->port_authorized.sta_addr);
+ if (sta)
+ ap_sta_set_authorized(wpa_s->ap_iface->bss[0], sta, 1);
+ else
+ wpa_printf(MSG_ERROR, "sta info not found");
+ } else {
+ /* sta/p2p gc port authorized event handling */
+ wpa_supplicant_event_port_authorized(wpa_s);
+ }
break;
case EVENT_STATION_OPMODE_CHANGED:
#ifdef CONFIG_AP
This patch adds support for AP/P2P GO 4way HS support. For drivers supporting the AP PSK offload, supplicant/hostapd would pass down the PSK for driver to handle 4way handshake. The driver is expected to indicate PORT authorized event to indicate that the 4way handshake is completed successfully. Signed-off-by: Vinayak Yadawad <vinayak.yadawad@broadcom.com> --- src/ap/beacon.c | 13 ++++++++++++- src/ap/drv_callbacks.c | 10 ++++++++++ src/ap/hostapd.c | 7 ++++++- src/drivers/driver.h | 14 +++++++++++++- src/drivers/driver_nl80211.c | 5 +++++ src/drivers/driver_nl80211_capa.c | 5 +++++ src/drivers/driver_nl80211_event.c | 9 ++++++++- wpa_supplicant/ap.c | 1 + wpa_supplicant/events.c | 16 +++++++++++++++- 9 files changed, 75 insertions(+), 5 deletions(-)