]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Add missing WPA3-SAE auth_data in auth retry case
authorhongwang.li <hongwang.li@sonos.com>
Tue, 12 Jan 2021 02:12:58 +0000 (18:12 -0800)
committerJouni Malinen <j@w1.fi>
Fri, 15 Jan 2021 10:14:17 +0000 (12:14 +0200)
When wpa_supplicant sends NL80211_CMD_AUTHENTICATE to kernel, it is
possible that the cfg80211 in kernel has expired the BSS entry that
we are trying to auth with. Then cfg80211 will reject the auth cmd.
In this case, wpa_supplicant will trigger a single channel scan to
refresh cfg80211 BSS entry, and retry the auth when scan is finished.

When this case happens, wpa_supplicant makes a copy of auth params,
such as frequency, bssid, ssid, ie and so on. So when we retry auth,
the copy of these params will be used. The problem is, a param named
auth_data is missed when making the copy. The auth_data is used by
NL80211_ATTR_SAE_DATA which is a mandatory field for WPA3-SAE auth.
In WPA3-SAE case the auth retry will always fail because auth_data is
missing. This patch fixes the issue.

Signed-off-by: hongwang.li <hongwang.li@sonos.com>
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h

index 64544e09d4c0332690e98c12680be869b0c40dbb..13ecd11d3f0108970f3ec9a88450425c8013e849 100644 (file)
@@ -2975,6 +2975,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
        os_free(drv->filter_ssids);
 
        os_free(drv->auth_ie);
+       os_free(drv->auth_data);
 
        if (drv->in_interface_list)
                dl_list_del(&drv->list);
@@ -3628,6 +3629,16 @@ static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
                }
        }
 
+       os_free(drv->auth_data);
+       drv->auth_data = NULL;
+       drv->auth_data_len = 0;
+       if (params->auth_data) {
+               drv->auth_data = os_memdup(params->auth_data,
+                                          params->auth_data_len);
+               if (drv->auth_data)
+                       drv->auth_data_len = params->auth_data_len;
+       }
+
        for (i = 0; i < 4; i++) {
                if (params->wep_key[i] && params->wep_key_len[i] &&
                    params->wep_key_len[i] <= 16) {
@@ -3881,6 +3892,8 @@ int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv)
 
        params.ie = drv->auth_ie;
        params.ie_len = drv->auth_ie_len;
+       params.auth_data = drv->auth_data;
+       params.auth_data_len = drv->auth_data_len;
 
        for (i = 0; i < 4; i++) {
                if (drv->auth_wep_key_len[i]) {
index 2926c815ec4021ccd716cc3a245db7214844f23d..7b9be1f3a9f49b567dbb4c84f29c1bcede4d263d 100644 (file)
@@ -209,6 +209,8 @@ struct wpa_driver_nl80211_data {
        int auth_alg;
        u8 *auth_ie;
        size_t auth_ie_len;
+       u8 *auth_data;
+       size_t auth_data_len;
        u8 auth_wep_key[4][16];
        size_t auth_wep_key_len[4];
        int auth_wep_tx_keyidx;