aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h4
-rw-r--r--include/net/wireless.h5
-rw-r--r--net/mac80211/main.c14
-rw-r--r--net/wireless/nl80211.c14
4 files changed, 36 insertions, 1 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 05ba3539b77e..c01423888db9 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -453,6 +453,9 @@ enum nl80211_commands {
453 * attributes consists of a nested attribute containing 453 * attributes consists of a nested attribute containing
454 * NL80211_FREQUENCY_ATTR_* 454 * NL80211_FREQUENCY_ATTR_*
455 * 455 *
456 * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
457 * cipher suites
458 *
456 * @NL80211_ATTR_MAX: highest attribute number currently defined 459 * @NL80211_ATTR_MAX: highest attribute number currently defined
457 * @__NL80211_ATTR_AFTER_LAST: internal use 460 * @__NL80211_ATTR_AFTER_LAST: internal use
458 */ 461 */
@@ -540,6 +543,7 @@ enum nl80211_attrs {
540 NL80211_ATTR_KEY_TYPE, 543 NL80211_ATTR_KEY_TYPE,
541 544
542 NL80211_ATTR_MAX_SCAN_IE_LEN, 545 NL80211_ATTR_MAX_SCAN_IE_LEN,
546 NL80211_ATTR_CIPHER_SUITES,
543 547
544 NL80211_ATTR_FREQ_BEFORE, 548 NL80211_ATTR_FREQ_BEFORE,
545 NL80211_ATTR_FREQ_AFTER, 549 NL80211_ATTR_FREQ_AFTER,
diff --git a/include/net/wireless.h b/include/net/wireless.h
index 2bcdeda46d81..44c2642d3c06 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -205,6 +205,8 @@ struct ieee80211_supported_band {
205 * on the reg_notifier() if it chooses to ignore future 205 * on the reg_notifier() if it chooses to ignore future
206 * regulatory domain changes caused by other drivers. 206 * regulatory domain changes caused by other drivers.
207 * @signal_type: signal type reported in &struct cfg80211_bss. 207 * @signal_type: signal type reported in &struct cfg80211_bss.
208 * @cipher_suites: supported cipher suites
209 * @n_cipher_suites: number of supported cipher suites
208 */ 210 */
209struct wiphy { 211struct wiphy {
210 /* assign these fields before you register the wiphy */ 212 /* assign these fields before you register the wiphy */
@@ -224,6 +226,9 @@ struct wiphy {
224 u8 max_scan_ssids; 226 u8 max_scan_ssids;
225 u16 max_scan_ie_len; 227 u16 max_scan_ie_len;
226 228
229 int n_cipher_suites;
230 const u32 *cipher_suites;
231
227 /* If multiple wiphys are registered and you're handed e.g. 232 /* If multiple wiphys are registered and you're handed e.g.
228 * a regular netdev with assigned ieee80211_ptr, you won't 233 * a regular netdev with assigned ieee80211_ptr, you won't
229 * know whether it points to a wiphy your driver has registered 234 * know whether it points to a wiphy your driver has registered
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 679b3a14f11f..c1145be72da4 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -823,6 +823,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
823 struct ieee80211_master_priv *mpriv; 823 struct ieee80211_master_priv *mpriv;
824 int channels, i, j, max_bitrates; 824 int channels, i, j, max_bitrates;
825 bool supp_ht; 825 bool supp_ht;
826 static const u32 cipher_suites[] = {
827 WLAN_CIPHER_SUITE_WEP40,
828 WLAN_CIPHER_SUITE_WEP104,
829 WLAN_CIPHER_SUITE_TKIP,
830 WLAN_CIPHER_SUITE_CCMP,
831
832 /* keep last -- depends on hw flags! */
833 WLAN_CIPHER_SUITE_AES_CMAC
834 };
826 835
827 /* 836 /*
828 * generic code guarantees at least one band, 837 * generic code guarantees at least one band,
@@ -894,6 +903,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
894 if (local->hw.wiphy->max_scan_ie_len) 903 if (local->hw.wiphy->max_scan_ie_len)
895 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; 904 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
896 905
906 local->hw.wiphy->cipher_suites = cipher_suites;
907 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
908 if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
909 local->hw.wiphy->n_cipher_suites--;
910
897 result = wiphy_register(local->hw.wiphy); 911 result = wiphy_register(local->hw.wiphy);
898 if (result < 0) 912 if (result < 0)
899 goto fail_wiphy_register; 913 goto fail_wiphy_register;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 85b5aa3c76f8..d33cab0e0fb2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -208,6 +208,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
208 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, 208 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
209 dev->wiphy.max_scan_ie_len); 209 dev->wiphy.max_scan_ie_len);
210 210
211 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
212 sizeof(u32) * dev->wiphy.n_cipher_suites,
213 dev->wiphy.cipher_suites);
214
211 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 215 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
212 if (!nl_modes) 216 if (!nl_modes)
213 goto nla_put_failure; 217 goto nla_put_failure;
@@ -979,7 +983,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
979static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 983static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
980{ 984{
981 struct cfg80211_registered_device *drv; 985 struct cfg80211_registered_device *drv;
982 int err; 986 int err, i;
983 struct net_device *dev; 987 struct net_device *dev;
984 struct key_params params; 988 struct key_params params;
985 u8 key_idx = 0; 989 u8 key_idx = 0;
@@ -1048,6 +1052,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1048 if (err) 1052 if (err)
1049 goto unlock_rtnl; 1053 goto unlock_rtnl;
1050 1054
1055 for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
1056 if (params.cipher == drv->wiphy.cipher_suites[i])
1057 break;
1058 if (i == drv->wiphy.n_cipher_suites) {
1059 err = -EINVAL;
1060 goto out;
1061 }
1062
1051 if (!drv->ops->add_key) { 1063 if (!drv->ops->add_key) {
1052 err = -EOPNOTSUPP; 1064 err = -EOPNOTSUPP;
1053 goto out; 1065 goto out;