diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-08 08:22:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-24 15:05:09 -0400 |
commit | fffd0934b9390f34bec45762192b7edd3b12b4b5 (patch) | |
tree | d9779803763261f5795fe39a402d79c4220a3a22 /net/mac80211 | |
parent | b9454e83cac42fcdc90bfbfba479132bd6629455 (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.c | 9 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 8 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 11 | ||||
-rw-r--r-- | net/mac80211/util.c | 16 | ||||
-rw-r--r-- | net/mac80211/wep.c | 6 | ||||
-rw-r--r-- | net/mac80211/wep.h | 3 |
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 | ||
63 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | 63 | static 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 | ||
1094 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1098 | void 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); |
1098 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1102 | int 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); |
1100 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1104 | void 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 */ |
36 | void *mac80211_wiphy_privid = &mac80211_wiphy_privid; | 37 | void *mac80211_wiphy_privid = &mac80211_wiphy_privid; |
@@ -804,12 +805,13 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | |||
804 | 805 | ||
805 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 806 | void 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 | ||
841 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 847 | int 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 | */ |
147 | static int ieee80211_wep_encrypt(struct ieee80211_local *local, | 147 | int 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); | |||
20 | void ieee80211_wep_free(struct ieee80211_local *local); | 20 | void ieee80211_wep_free(struct ieee80211_local *local); |
21 | void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | 21 | void 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); |
23 | int ieee80211_wep_encrypt(struct ieee80211_local *local, | ||
24 | struct sk_buff *skb, | ||
25 | const u8 *key, int keylen, int keyidx); | ||
23 | int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | 26 | int 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); |
25 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | 28 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); |