]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/mac80211/mlme.c
net: bcm63xx_enet: Utilize phy_ethtool_nway_reset
[linux.git] / net / mac80211 / mlme.c
index 7486f2dab4ba70ade0b2faf48ffa7f3880ac2ad4..d157b250ff7710088dfeee928045f2612e8c5464 100644 (file)
@@ -30,6 +30,7 @@
 #include "driver-ops.h"
 #include "rate.h"
 #include "led.h"
+#include "fils_aead.h"
 
 #define IEEE80211_AUTH_TIMEOUT         (HZ / 5)
 #define IEEE80211_AUTH_TIMEOUT_LONG    (HZ / 2)
@@ -652,6 +653,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                        2 + sizeof(struct ieee80211_ht_cap) + /* HT */
                        2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
                        assoc_data->ie_len + /* extra IEs */
+                       (assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) +
                        9, /* WMM */
                        GFP_KERNEL);
        if (!skb)
@@ -875,6 +877,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                memcpy(pos, assoc_data->ie + offset, noffset - offset);
        }
 
+       if (assoc_data->fils_kek_len &&
+           fils_encrypt_assoc_req(skb, assoc_data) < 0) {
+               dev_kfree_skb(skb);
+               return;
+       }
+
        drv_mgd_prepare_tx(local, sdata);
 
        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
@@ -2618,6 +2626,9 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
        case WLAN_AUTH_LEAP:
        case WLAN_AUTH_FT:
        case WLAN_AUTH_SAE:
+       case WLAN_AUTH_FILS_SK:
+       case WLAN_AUTH_FILS_SK_PFS:
+       case WLAN_AUTH_FILS_PK:
                break;
        case WLAN_AUTH_SHARED_KEY:
                if (ifmgd->auth_data->expected_transaction != 4) {
@@ -3143,6 +3154,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                   reassoc ? "Rea" : "A", mgmt->sa,
                   capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
 
+       if (assoc_data->fils_kek_len &&
+           fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0)
+               return;
+
        pos = mgmt->u.assoc_resp.variable;
        ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems);
 
@@ -3193,7 +3208,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                uapsd_queues = 0;
                for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
                        if (sdata->tx_conf[ac].uapsd)
-                               uapsd_queues |= BIT(ac);
+                               uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
        }
 
        cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len, uapsd_queues);
@@ -4479,24 +4494,36 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
        case NL80211_AUTHTYPE_SAE:
                auth_alg = WLAN_AUTH_SAE;
                break;
+       case NL80211_AUTHTYPE_FILS_SK:
+               auth_alg = WLAN_AUTH_FILS_SK;
+               break;
+       case NL80211_AUTHTYPE_FILS_SK_PFS:
+               auth_alg = WLAN_AUTH_FILS_SK_PFS;
+               break;
+       case NL80211_AUTHTYPE_FILS_PK:
+               auth_alg = WLAN_AUTH_FILS_PK;
+               break;
        default:
                return -EOPNOTSUPP;
        }
 
-       auth_data = kzalloc(sizeof(*auth_data) + req->sae_data_len +
+       auth_data = kzalloc(sizeof(*auth_data) + req->auth_data_len +
                            req->ie_len, GFP_KERNEL);
        if (!auth_data)
                return -ENOMEM;
 
        auth_data->bss = req->bss;
 
-       if (req->sae_data_len >= 4) {
-               __le16 *pos = (__le16 *) req->sae_data;
-               auth_data->sae_trans = le16_to_cpu(pos[0]);
-               auth_data->sae_status = le16_to_cpu(pos[1]);
-               memcpy(auth_data->data, req->sae_data + 4,
-                      req->sae_data_len - 4);
-               auth_data->data_len += req->sae_data_len - 4;
+       if (req->auth_data_len >= 4) {
+               if (req->auth_type == NL80211_AUTHTYPE_SAE) {
+                       __le16 *pos = (__le16 *) req->auth_data;
+
+                       auth_data->sae_trans = le16_to_cpu(pos[0]);
+                       auth_data->sae_status = le16_to_cpu(pos[1]);
+               }
+               memcpy(auth_data->data, req->auth_data + 4,
+                      req->auth_data_len - 4);
+               auth_data->data_len += req->auth_data_len - 4;
        }
 
        if (req->ie && req->ie_len) {
@@ -4692,6 +4719,21 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                assoc_data->ie_len = req->ie_len;
        }
 
+       if (req->fils_kek) {
+               /* should already be checked in cfg80211 - so warn */
+               if (WARN_ON(req->fils_kek_len > FILS_MAX_KEK_LEN)) {
+                       err = -EINVAL;
+                       goto err_free;
+               }
+               memcpy(assoc_data->fils_kek, req->fils_kek,
+                      req->fils_kek_len);
+               assoc_data->fils_kek_len = req->fils_kek_len;
+       }
+
+       if (req->fils_nonces)
+               memcpy(assoc_data->fils_nonces, req->fils_nonces,
+                      2 * FILS_NONCE_LEN);
+
        assoc_data->bss = req->bss;
 
        if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {