diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 23423d92e..073c50e54 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -2156,6 +2156,7 @@ enum wpa_drv_update_connect_params_mask { * use %WLAN_STATUS_UNSPECIFIED_FAILURE if wpa_supplicant cannot give * the real status code for failures. Used only for the request interface * from user space to the driver. + * @pmkid: Generated PMKID as part of external auth exchange (e.g., SAE). */ struct external_auth { enum { @@ -2167,6 +2168,7 @@ struct external_auth { size_t ssid_len; unsigned int key_mgmt_suite; u16 status; + const u8 *pmkid; }; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 661e34e66..b934c8422 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -2469,6 +2469,16 @@ static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss) if (nl80211_action_subscribe_ap(bss)) goto out_err; + if (bss->drv->device_ap_sme) { + u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4); + + /* Register for all Authentication frames */ + if (nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0) + < 0) + wpa_printf(MSG_DEBUG, + "nl80211: Failed to subscribe to handle Authentication frames - SAE offload may not work"); + } + nl80211_mgmt_handle_register_eloop(bss); return 0; @@ -4160,6 +4170,9 @@ static int wpa_driver_nl80211_set_ap(void *priv, nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) goto fail; + if (drv->device_ap_sme && (params->key_mgmt_suites & WPA_KEY_MGMT_SAE)) + nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT); + wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x", params->pairwise_ciphers); num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers, @@ -10792,14 +10805,25 @@ static int nl80211_send_external_auth_status(void *priv, struct nl_msg *msg = NULL; int ret = -1; + /* External auth command/status is intended for drivers that implement + * intenral SME but want to offload authentication processing (e.g., + * SAE) to hostapd/wpa_supplicant. Do nott send the status to drivers + * which do not support AP SME or use wpa_supplicant/hostapd SME. + */ + if (!bss->drv->device_ap_sme || + (drv->capa.flags & WPA_DRIVER_FLAGS_SME)) + return -1; + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: External auth status: %u", params->status); msg = nl80211_drv_msg(drv, 0, NL80211_CMD_EXTERNAL_AUTH); if (!msg || nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, params->status) || - nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, - params->ssid) || + (params->ssid_len && + nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid)) || + (params->pmkid && + nla_put(msg, NL80211_ATTR_PMKID, PMKID_LEN, params->pmkid)) || nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid)) goto fail; ret = send_and_recv_msgs(drv, msg, NULL, NULL);