aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-08 08:22:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:09 -0400
commitfffd0934b9390f34bec45762192b7edd3b12b4b5 (patch)
treed9779803763261f5795fe39a402d79c4220a3a22 /net/mac80211
parentb9454e83cac42fcdc90bfbfba479132bd6629455 (diff)
cfg80211: rework key operation
This reworks the key operation in cfg80211, and now only allows, from userspace, configuring keys (via nl80211) after the connection has been established (in managed mode), the IBSS been joined (in IBSS mode), at any time (in AP[_VLAN] modes) or never for all the other modes. In order to do shared key authentication correctly, it is now possible to give a WEP key to the AUTH command. To configure static WEP keys, these are given to the CONNECT or IBSS_JOIN command directly, for a userspace SME it is assumed it will configure it properly after the connection has been established. Since mac80211 used to check the default key in IBSS mode to see whether or not the network is protected, it needs an update in that area, as well as an update to make use of the WEP key passed to auth() for shared key authentication. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ibss.c9
-rw-r--r--net/mac80211/ieee80211_i.h8
-rw-r--r--net/mac80211/mlme.c11
-rw-r--r--net/mac80211/util.c16
-rw-r--r--net/mac80211/wep.c6
-rw-r--r--net/mac80211/wep.h3
6 files changed, 37 insertions, 16 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 15d5a53b59a8..8e2220000e5c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -57,7 +57,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
57 */ 57 */
58 if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) 58 if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
59 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, 59 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
60 sdata->u.ibss.bssid, 0); 60 sdata->u.ibss.bssid, NULL, 0, 0);
61} 61}
62 62
63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
@@ -494,7 +494,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
494 494
495 capability = WLAN_CAPABILITY_IBSS; 495 capability = WLAN_CAPABILITY_IBSS;
496 496
497 if (sdata->default_key) 497 if (ifibss->privacy)
498 capability |= WLAN_CAPABILITY_PRIVACY; 498 capability |= WLAN_CAPABILITY_PRIVACY;
499 else 499 else
500 sdata->drop_unencrypted = 0; 500 sdata->drop_unencrypted = 0;
@@ -524,9 +524,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
524 return; 524 return;
525 525
526 capability = WLAN_CAPABILITY_IBSS; 526 capability = WLAN_CAPABILITY_IBSS;
527 if (sdata->default_key) 527 if (ifibss->privacy)
528 capability |= WLAN_CAPABILITY_PRIVACY; 528 capability |= WLAN_CAPABILITY_PRIVACY;
529
530 if (ifibss->fixed_bssid) 529 if (ifibss->fixed_bssid)
531 bssid = ifibss->bssid; 530 bssid = ifibss->bssid;
532 if (ifibss->fixed_channel) 531 if (ifibss->fixed_channel)
@@ -872,6 +871,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
872 } else 871 } else
873 sdata->u.ibss.fixed_bssid = false; 872 sdata->u.ibss.fixed_bssid = false;
874 873
874 sdata->u.ibss.privacy = params->privacy;
875
875 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 876 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
876 877
877 sdata->u.ibss.channel = params->channel; 878 sdata->u.ibss.channel = params->channel;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 327aabc07abe..06b3411530f2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -247,6 +247,9 @@ struct ieee80211_mgd_work {
247 247
248 int tries; 248 int tries;
249 249
250 u8 key[WLAN_KEY_LEN_WEP104];
251 u8 key_len, key_idx;
252
250 /* must be last */ 253 /* must be last */
251 u8 ie[0]; /* for auth or assoc frame, not probe */ 254 u8 ie[0]; /* for auth or assoc frame, not probe */
252}; 255};
@@ -321,6 +324,7 @@ struct ieee80211_if_ibss {
321 324
322 bool fixed_bssid; 325 bool fixed_bssid;
323 bool fixed_channel; 326 bool fixed_channel;
327 bool privacy;
324 328
325 u8 bssid[ETH_ALEN]; 329 u8 bssid[ETH_ALEN];
326 u8 ssid[IEEE80211_MAX_SSID_LEN]; 330 u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -1093,8 +1097,8 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
1093 1097
1094void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1098void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1095 u16 transaction, u16 auth_alg, 1099 u16 transaction, u16 auth_alg,
1096 u8 *extra, size_t extra_len, 1100 u8 *extra, size_t extra_len, const u8 *bssid,
1097 const u8 *bssid, int encrypt); 1101 const u8 *key, u8 key_len, u8 key_idx);
1098int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1102int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1099 const u8 *ie, size_t ie_len); 1103 const u8 *ie, size_t ie_len);
1100void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1104void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c9db9646025b..8e4a60497bba 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -954,7 +954,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
954 sdata->dev->name, wk->bss->cbss.bssid, wk->tries); 954 sdata->dev->name, wk->bss->cbss.bssid, wk->tries);
955 955
956 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len, 956 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len,
957 wk->bss->cbss.bssid, 0); 957 wk->bss->cbss.bssid, NULL, 0, 0);
958 wk->auth_transaction = 2; 958 wk->auth_transaction = 2;
959 959
960 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 960 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
@@ -1176,7 +1176,8 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1176 return; 1176 return;
1177 ieee80211_send_auth(sdata, 3, wk->auth_alg, 1177 ieee80211_send_auth(sdata, 3, wk->auth_alg,
1178 elems.challenge - 2, elems.challenge_len + 2, 1178 elems.challenge - 2, elems.challenge_len + 2,
1179 wk->bss->cbss.bssid, 1); 1179 wk->bss->cbss.bssid,
1180 wk->key, wk->key_len, wk->key_idx);
1180 wk->auth_transaction = 4; 1181 wk->auth_transaction = 4;
1181} 1182}
1182 1183
@@ -2175,6 +2176,12 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2175 wk->ie_len = req->ie_len; 2176 wk->ie_len = req->ie_len;
2176 } 2177 }
2177 2178
2179 if (req->key && req->key_len) {
2180 wk->key_len = req->key_len;
2181 wk->key_idx = req->key_idx;
2182 memcpy(wk->key, req->key, req->key_len);
2183 }
2184
2178 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 2185 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
2179 memcpy(wk->ssid, ssid + 2, ssid[1]); 2186 memcpy(wk->ssid, ssid + 2, ssid[1]);
2180 wk->ssid_len = ssid[1]; 2187 wk->ssid_len = ssid[1];
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 915e77769312..dbf66b52d38c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -31,6 +31,7 @@
31#include "mesh.h" 31#include "mesh.h"
32#include "wme.h" 32#include "wme.h"
33#include "led.h" 33#include "led.h"
34#include "wep.h"
34 35
35/* privid for wiphys to determine whether they belong to us or not */ 36/* privid for wiphys to determine whether they belong to us or not */
36void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 37void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -804,12 +805,13 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
804 805
805void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 806void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
806 u16 transaction, u16 auth_alg, 807 u16 transaction, u16 auth_alg,
807 u8 *extra, size_t extra_len, 808 u8 *extra, size_t extra_len, const u8 *bssid,
808 const u8 *bssid, int encrypt) 809 const u8 *key, u8 key_len, u8 key_idx)
809{ 810{
810 struct ieee80211_local *local = sdata->local; 811 struct ieee80211_local *local = sdata->local;
811 struct sk_buff *skb; 812 struct sk_buff *skb;
812 struct ieee80211_mgmt *mgmt; 813 struct ieee80211_mgmt *mgmt;
814 int err;
813 815
814 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 816 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
815 sizeof(*mgmt) + 6 + extra_len); 817 sizeof(*mgmt) + 6 + extra_len);
@@ -824,8 +826,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
824 memset(mgmt, 0, 24 + 6); 826 memset(mgmt, 0, 24 + 6);
825 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 827 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
826 IEEE80211_STYPE_AUTH); 828 IEEE80211_STYPE_AUTH);
827 if (encrypt)
828 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
829 memcpy(mgmt->da, bssid, ETH_ALEN); 829 memcpy(mgmt->da, bssid, ETH_ALEN);
830 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 830 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
831 memcpy(mgmt->bssid, bssid, ETH_ALEN); 831 memcpy(mgmt->bssid, bssid, ETH_ALEN);
@@ -835,7 +835,13 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
835 if (extra) 835 if (extra)
836 memcpy(skb_put(skb, extra_len), extra, extra_len); 836 memcpy(skb_put(skb, extra_len), extra, extra_len);
837 837
838 ieee80211_tx_skb(sdata, skb, encrypt); 838 if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
839 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
840 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
841 WARN_ON(err);
842 }
843
844 ieee80211_tx_skb(sdata, skb, 0);
839} 845}
840 846
841int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 847int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 4fafb2d27c84..8a980f136941 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -144,9 +144,9 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
144 * 144 *
145 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) 145 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
146 */ 146 */
147static int ieee80211_wep_encrypt(struct ieee80211_local *local, 147int ieee80211_wep_encrypt(struct ieee80211_local *local,
148 struct sk_buff *skb, 148 struct sk_buff *skb,
149 const u8 *key, int keylen, int keyidx) 149 const u8 *key, int keylen, int keyidx)
150{ 150{
151 u8 *iv; 151 u8 *iv;
152 size_t len; 152 size_t len;
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index 85219ded8703..fe29d7e5759f 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -20,6 +20,9 @@ int ieee80211_wep_init(struct ieee80211_local *local);
20void ieee80211_wep_free(struct ieee80211_local *local); 20void ieee80211_wep_free(struct ieee80211_local *local);
21void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 21void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
22 size_t klen, u8 *data, size_t data_len); 22 size_t klen, u8 *data, size_t data_len);
23int ieee80211_wep_encrypt(struct ieee80211_local *local,
24 struct sk_buff *skb,
25 const u8 *key, int keylen, int keyidx);
23int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 26int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
24 size_t klen, u8 *data, size_t data_len); 27 size_t klen, u8 *data, size_t data_len);
25bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); 28bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);