]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: External authentication in driver-based AP SME mode
authorSrinivas Dasari <dasaris@codeaurora.org>
Mon, 25 Feb 2019 12:22:05 +0000 (17:52 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 12 Apr 2019 17:29:56 +0000 (20:29 +0300)
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 <dasaris@codeaurora.org>
src/drivers/driver.h
src/drivers/driver_nl80211.c

index 23423d92e898d28de6c09c68df9b267db0615521..073c50e54516217ead8737dcaa60674b10decebe 100644 (file)
@@ -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;
 };
 
 /**
index 661e34e668aece2583e255b0e513a4f7fde50c9e..b934c8422a8e674e247ca850579ddaa653f20f0e 100644 (file)
@@ -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);