From 236e793e7b8b96f7ad3e9aa3ea83b7c7c83b43fa Mon Sep 17 00:00:00 2001 From: Srinivas Dasari Date: Mon, 25 Feb 2019 17:52:05 +0530 Subject: [PATCH] nl80211: External authentication in driver-based AP SME mode This extends driver interface to nl80211 by introducing the following changes, 1. Register for Authenication frames in driver-based AP SME mode. 2. Advertise NL80211_ATTR_EXTERNAL_AUTH_SUPPORT in set_ap when offloaded SAE authentication is supported. 3. Extend the NL80211_CMD_EXTERNAL_AUTH interface to also send PMKID so that the drivers can respond to the PMKSA cached connection attempts from the stations avoiding the need to contact user space for all PMKID-based connections. 4. Send external auth status to driver only if it is a driver based SME solution. Signed-off-by: Srinivas Dasari --- src/drivers/driver.h | 2 ++ src/drivers/driver_nl80211.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) 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); -- 2.39.2