#include "common/ieee802_11_common.h"
#include "common/hw_features_common.h"
#include "common/wpa_ctrl.h"
+#include "crypto/sha1.h"
#include "wps/wps_defs.h"
#include "p2p/p2p.h"
#include "hostapd.h"
resp = hostapd_probe_resp_offloads(hapd, &resp_len);
#endif /* NEED_AP_MLME */
+ /* If key management offload is enabled, configure PSK to the driver. */
+ if (wpa_key_mgmt_wpa_psk_no_sae(hapd->conf->wpa_key_mgmt) &&
+ (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);
+ params->psk_len = 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) == 0) {
+ params->psk_len = PMK_LEN;
+ }
+ }
+
params->head = (u8 *) head;
params->head_len = head_len;
params->tail = tail;
union wpa_event_data *data)
{
struct hostapd_data *hapd = ctx;
+ struct sta_info *sta;
#ifndef CONFIG_NO_STDOUT_DEBUG
int level = MSG_DEBUG;
data->assoc_info.link_addr,
data->assoc_info.reassoc);
break;
+ case EVENT_PORT_AUTHORIZED:
+ /* Port authorized event for an 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,
+ "No STA info matching port authorized event found");
+ break;
#ifdef CONFIG_OWE
case EVENT_UPDATE_DH:
if (!data)
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)) {
+ /* The 4-way handshake offloaded case will have this handled
+ * based on the port authorized 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) {
* mld_link_id - Link id for MLD BSS's
*/
u8 mld_link_id;
+
+ /**
+ * psk - PSK passed to the driver for 4-way handshake offload
+ */
+ u8 psk[PMK_LEN];
+
+ /**
+ * psk_len - PSK length in bytes (0 = not set)
+ */
+ size_t psk_len;
};
struct wpa_driver_mesh_bss_params {
#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) \
/**
* struct port_authorized - Data for EVENT_PORT_AUTHORIZED
+ * @td_bitmap: For STA mode, transition disable bitmap, if received in
+ * EAPOL-Key msg 3/4
+ * @td_bitmap_len: For STA mode, length of td_bitmap
+ * @sta_addr: For AP mode, the MAC address of the associated STA
+ *
+ * This event is used to indicate that the port is authorized and
+ * open for normal data in STA and AP modes when 4-way handshake is
+ * offloaded to the driver.
*/
struct port_authorized {
const u8 *td_bitmap;
size_t td_bitmap_len;
+ const u8 *sta_addr;
} port_authorized;
/**
suites))
goto fail;
+ if ((params->key_mgmt_suites & WPA_KEY_MGMT_PSK) &&
+ (drv->capa.flags & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK) &&
+ params->psk_len &&
+ nla_put(msg, NL80211_ATTR_PMK, params->psk_len, 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)) &&
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;
}
}
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) {
+ event.port_authorized.sta_addr = addr;
+ 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 ")",
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;
#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"
break;
#endif /* CONFIG_PASN */
case EVENT_PORT_AUTHORIZED:
+#ifdef CONFIG_AP
+ if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) {
+ struct sta_info *sta;
+
+ 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_DEBUG,
+ "No STA info matching port authorized event found");
+ break;
+ }
+#endif /* CONFIG_AP */
#ifndef CONFIG_NO_WPA
if (data->port_authorized.td_bitmap_len) {
wpa_printf(MSG_DEBUG,