cfg80211: Add support for static WEP in the driver
authorDavid Spinadel <david.spinadel@intel.com>
Thu, 22 Sep 2016 20:16:50 +0000 (23:16 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 30 Sep 2016 11:19:10 +0000 (13:19 +0200)
Add support for drivers that implement static WEP internally, i.e.
expose connection keys to the driver in connect flow and don't
upload the keys after the connection.

Signed-off-by: David Spinadel <david.spinadel@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
net/wireless/core.h
net/wireless/ibss.c
net/wireless/sme.c
net/wireless/util.c
net/wireless/wext-compat.c
net/wireless/wext-sme.c

index ed37304fa09dc7b8bc8a16f4837e56eeac27a0c9..68dca3d93b8590762f0774f83ded49ffa91e5825 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright 2015      Intel Deutschland GmbH
+ * Copyright 2015-2016 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -593,6 +593,8 @@ struct survey_info {
        s8 noise;
 };
 
+#define CFG80211_MAX_WEP_KEYS  4
+
 /**
  * struct cfg80211_crypto_settings - Crypto settings
  * @wpa_versions: indicates which, if any, WPA versions are enabled
@@ -610,6 +612,9 @@ struct survey_info {
  *     allowed through even on unauthorized ports
  * @control_port_no_encrypt: TRUE to prevent encryption of control port
  *     protocol frames.
+ * @wep_keys: static WEP keys, if not NULL points to an array of
+ *     CFG80211_MAX_WEP_KEYS WEP keys
+ * @wep_tx_key: key index (0..3) of the default TX static WEP key
  */
 struct cfg80211_crypto_settings {
        u32 wpa_versions;
@@ -621,6 +626,8 @@ struct cfg80211_crypto_settings {
        bool control_port;
        __be16 control_port_ethertype;
        bool control_port_no_encrypt;
+       struct key_params *wep_keys;
+       int wep_tx_key;
 };
 
 /**
@@ -2905,6 +2912,8 @@ struct cfg80211_ops {
  * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels.
  * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in
  *     beaconing mode (AP, IBSS, Mesh, ...).
+ * @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation
+ *     before connection.
  */
 enum wiphy_flags {
        /* use hole at 0 */
@@ -2930,6 +2939,7 @@ enum wiphy_flags {
        WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL        = BIT(21),
        WIPHY_FLAG_SUPPORTS_5_10_MHZ            = BIT(22),
        WIPHY_FLAG_HAS_CHANNEL_SWITCH           = BIT(23),
+       WIPHY_FLAG_HAS_STATIC_WEP               = BIT(24),
 };
 
 /**
index 5555e3c13ae9db52b93993eef1810741e91f24bc..554f87d0f991e31a8bc3a161a25167ab9bda0ed9 100644 (file)
@@ -249,8 +249,8 @@ struct cfg80211_event {
 };
 
 struct cfg80211_cached_keys {
-       struct key_params params[4];
-       u8 data[4][WLAN_KEY_LEN_WEP104];
+       struct key_params params[CFG80211_MAX_WEP_KEYS];
+       u8 data[CFG80211_MAX_WEP_KEYS][WLAN_KEY_LEN_WEP104];
        int def;
 };
 
index eafdfa5798ae4a734368e4a0d3d2ac41e0f357a6..364f900a3dc4d2810c90fa3f613d1b9a08cb5e71 100644 (file)
@@ -43,7 +43,8 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
        cfg80211_hold_bss(bss_from_pub(bss));
        wdev->current_bss = bss_from_pub(bss);
 
-       cfg80211_upload_connect_keys(wdev);
+       if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))
+               cfg80211_upload_connect_keys(wdev);
 
        nl80211_send_ibss_bssid(wiphy_to_rdev(wdev->wiphy), dev, bssid,
                                GFP_KERNEL);
@@ -296,7 +297,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
                ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
                if (!ck)
                        return -ENOMEM;
-               for (i = 0; i < 4; i++)
+               for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
                        ck->params[i].key = ck->data[i];
        }
        err = __cfg80211_join_ibss(rdev, wdev->netdev,
index c08a3b57dca1268b0f57d5c20cd1e47a16676043..a77db333927ec1bc8ab6efa4ee26b9fc7e711f5e 100644 (file)
@@ -726,7 +726,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 
        wdev->current_bss = bss_from_pub(bss);
 
-       cfg80211_upload_connect_keys(wdev);
+       if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))
+               cfg80211_upload_connect_keys(wdev);
 
        rcu_read_lock();
        country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
@@ -1043,6 +1044,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
                                connect->crypto.ciphers_pairwise[0] = cipher;
                        }
                }
+
+               connect->crypto.wep_keys = connkeys->params;
+               connect->crypto.wep_tx_key = connkeys->def;
        } else {
                if (WARN_ON(connkeys))
                        return -EINVAL;
index 9e6e2aaa7766147f9fe88b414193c7bedab2b525..e02141d66b69877d6c2b080fafa419d121ef5a29 100644 (file)
@@ -912,7 +912,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
        if (!wdev->connect_keys)
                return;
 
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++) {
                if (!wdev->connect_keys->params[i].cipher)
                        continue;
                if (rdev_add_key(rdev, dev, i, false, NULL,
index 2b096c02eb8577835d1912f6cee9a35c66abfc4e..a220156cf2175a459727fcf67e1291036dca21ae 100644 (file)
@@ -415,7 +415,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
                                          GFP_KERNEL);
                if (!wdev->wext.keys)
                        return -ENOMEM;
-               for (i = 0; i < 4; i++)
+               for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
                        wdev->wext.keys->params[i].key =
                                wdev->wext.keys->data[i];
        }
index 88f1f6931ab8e030bce4ce224ee5d6484798274e..995163830a61f582c11b9234b370bb2c3766f7f0 100644 (file)
@@ -46,7 +46,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
                ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
                if (!ck)
                        return -ENOMEM;
-               for (i = 0; i < 4; i++)
+               for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
                        ck->params[i].key = ck->data[i];
        }