Commit b8676221 authored by David Spinadel's avatar David Spinadel Committed by Johannes Berg

cfg80211: Add support for static WEP in the driver

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: default avatarDavid Spinadel <david.spinadel@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent e0e2efff
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * 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 * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -593,6 +593,8 @@ struct survey_info { ...@@ -593,6 +593,8 @@ struct survey_info {
s8 noise; s8 noise;
}; };
#define CFG80211_MAX_WEP_KEYS 4
/** /**
* struct cfg80211_crypto_settings - Crypto settings * struct cfg80211_crypto_settings - Crypto settings
* @wpa_versions: indicates which, if any, WPA versions are enabled * @wpa_versions: indicates which, if any, WPA versions are enabled
...@@ -610,6 +612,9 @@ struct survey_info { ...@@ -610,6 +612,9 @@ struct survey_info {
* allowed through even on unauthorized ports * allowed through even on unauthorized ports
* @control_port_no_encrypt: TRUE to prevent encryption of control port * @control_port_no_encrypt: TRUE to prevent encryption of control port
* protocol frames. * 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 { struct cfg80211_crypto_settings {
u32 wpa_versions; u32 wpa_versions;
...@@ -621,6 +626,8 @@ struct cfg80211_crypto_settings { ...@@ -621,6 +626,8 @@ struct cfg80211_crypto_settings {
bool control_port; bool control_port;
__be16 control_port_ethertype; __be16 control_port_ethertype;
bool control_port_no_encrypt; bool control_port_no_encrypt;
struct key_params *wep_keys;
int wep_tx_key;
}; };
/** /**
...@@ -2905,6 +2912,8 @@ struct cfg80211_ops { ...@@ -2905,6 +2912,8 @@ struct cfg80211_ops {
* @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels.
* @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in
* beaconing mode (AP, IBSS, Mesh, ...). * beaconing mode (AP, IBSS, Mesh, ...).
* @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation
* before connection.
*/ */
enum wiphy_flags { enum wiphy_flags {
/* use hole at 0 */ /* use hole at 0 */
...@@ -2930,6 +2939,7 @@ enum wiphy_flags { ...@@ -2930,6 +2939,7 @@ enum wiphy_flags {
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22), WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23), WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23),
WIPHY_FLAG_HAS_STATIC_WEP = BIT(24),
}; };
/** /**
......
...@@ -249,8 +249,8 @@ struct cfg80211_event { ...@@ -249,8 +249,8 @@ struct cfg80211_event {
}; };
struct cfg80211_cached_keys { struct cfg80211_cached_keys {
struct key_params params[4]; struct key_params params[CFG80211_MAX_WEP_KEYS];
u8 data[4][WLAN_KEY_LEN_WEP104]; u8 data[CFG80211_MAX_WEP_KEYS][WLAN_KEY_LEN_WEP104];
int def; int def;
}; };
......
...@@ -43,7 +43,8 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, ...@@ -43,7 +43,8 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
cfg80211_hold_bss(bss_from_pub(bss)); cfg80211_hold_bss(bss_from_pub(bss));
wdev->current_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, nl80211_send_ibss_bssid(wiphy_to_rdev(wdev->wiphy), dev, bssid,
GFP_KERNEL); GFP_KERNEL);
...@@ -296,7 +297,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, ...@@ -296,7 +297,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
if (!ck) if (!ck)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < 4; i++) for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
ck->params[i].key = ck->data[i]; ck->params[i].key = ck->data[i];
} }
err = __cfg80211_join_ibss(rdev, wdev->netdev, err = __cfg80211_join_ibss(rdev, wdev->netdev,
......
...@@ -726,7 +726,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, ...@@ -726,7 +726,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
wdev->current_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);
rcu_read_lock(); rcu_read_lock();
country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY); country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
...@@ -1043,6 +1044,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, ...@@ -1043,6 +1044,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
connect->crypto.ciphers_pairwise[0] = cipher; connect->crypto.ciphers_pairwise[0] = cipher;
} }
} }
connect->crypto.wep_keys = connkeys->params;
connect->crypto.wep_tx_key = connkeys->def;
} else { } else {
if (WARN_ON(connkeys)) if (WARN_ON(connkeys))
return -EINVAL; return -EINVAL;
......
...@@ -912,7 +912,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) ...@@ -912,7 +912,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
if (!wdev->connect_keys) if (!wdev->connect_keys)
return; return;
for (i = 0; i < 4; i++) { for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++) {
if (!wdev->connect_keys->params[i].cipher) if (!wdev->connect_keys->params[i].cipher)
continue; continue;
if (rdev_add_key(rdev, dev, i, false, NULL, if (rdev_add_key(rdev, dev, i, false, NULL,
......
...@@ -415,7 +415,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, ...@@ -415,7 +415,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
GFP_KERNEL); GFP_KERNEL);
if (!wdev->wext.keys) if (!wdev->wext.keys)
return -ENOMEM; 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->params[i].key =
wdev->wext.keys->data[i]; wdev->wext.keys->data[i];
} }
......
...@@ -46,7 +46,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, ...@@ -46,7 +46,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
if (!ck) if (!ck)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < 4; i++) for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
ck->params[i].key = ck->data[i]; ck->params[i].key = ck->data[i];
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment