aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-07-07 15:07:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-08 16:35:50 -0400
commit3473187d2459a078e00e5fac8aafc30af69c57fa (patch)
tree93c3da6dbcbfd09ea81884bee790219d4cee0d56
parent73e194639d90594d06d0c10019c0ab4638869135 (diff)
mac80211: remove wep dependency
The current mac80211 code assumes that WEP is always available. If WEP fails to initialize, ieee80211_register_hw will always fail. In some cases (e.g. FIPS certification), the cryptography used by WEP is unavailable. However, in such cases there is no good reason why CCMP encryption (or even no link level encryption) cannot be used. So, this patch removes mac80211's assumption that WEP (and TKIP) will always be available for use. Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/cfg.c5
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/tkip.c8
-rw-r--r--net/mac80211/tkip.h2
-rw-r--r--net/mac80211/wep.c24
-rw-r--r--net/mac80211/wep.h2
-rw-r--r--net/mac80211/wpa.c5
7 files changed, 30 insertions, 21 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e55970bf2ba0..5b8b4460b69f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -143,6 +143,11 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
143 return -EINVAL; 143 return -EINVAL;
144 } 144 }
145 145
146 /* reject WEP and TKIP keys if WEP failed to initialize */
147 if ((alg == ALG_WEP || alg == ALG_TKIP) &&
148 IS_ERR(sdata->local->wep_tx_tfm))
149 return -EINVAL;
150
146 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key, 151 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
147 params->seq_len, params->seq); 152 params->seq_len, params->seq);
148 if (!key) 153 if (!key)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index edf7aff93268..0e95c750ded9 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -637,11 +637,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
637 goto fail_sta_info; 637 goto fail_sta_info;
638 638
639 result = ieee80211_wep_init(local); 639 result = ieee80211_wep_init(local);
640 if (result < 0) { 640 if (result < 0)
641 printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", 641 printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",
642 wiphy_name(local->hw.wiphy), result); 642 wiphy_name(local->hw.wiphy), result);
643 goto fail_wep;
644 }
645 643
646 rtnl_lock(); 644 rtnl_lock();
647 645
@@ -694,7 +692,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
694 fail_rate: 692 fail_rate:
695 rtnl_unlock(); 693 rtnl_unlock();
696 ieee80211_wep_free(local); 694 ieee80211_wep_free(local);
697 fail_wep:
698 sta_info_stop(local); 695 sta_info_stop(local);
699 fail_sta_info: 696 fail_sta_info:
700 destroy_workqueue(local->workqueue); 697 destroy_workqueue(local->workqueue);
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 7ef491e9d66d..e840c9cd46db 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -202,9 +202,9 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
202 * @payload_len is the length of payload (_not_ including IV/ICV length). 202 * @payload_len is the length of payload (_not_ including IV/ICV length).
203 * @ta is the transmitter addresses. 203 * @ta is the transmitter addresses.
204 */ 204 */
205void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, 205int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
206 struct ieee80211_key *key, 206 struct ieee80211_key *key,
207 u8 *pos, size_t payload_len, u8 *ta) 207 u8 *pos, size_t payload_len, u8 *ta)
208{ 208{
209 u8 rc4key[16]; 209 u8 rc4key[16];
210 struct tkip_ctx *ctx = &key->u.tkip.tx; 210 struct tkip_ctx *ctx = &key->u.tkip.tx;
@@ -216,7 +216,7 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
216 216
217 tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); 217 tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
218 218
219 ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); 219 return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
220} 220}
221 221
222/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the 222/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h
index d4714383f5fc..7e83dee976fa 100644
--- a/net/mac80211/tkip.h
+++ b/net/mac80211/tkip.h
@@ -15,7 +15,7 @@
15 15
16u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); 16u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
17 17
18void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, 18int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
19 struct ieee80211_key *key, 19 struct ieee80211_key *key,
20 u8 *pos, size_t payload_len, u8 *ta); 20 u8 *pos, size_t payload_len, u8 *ta);
21enum { 21enum {
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5f3a4113bda1..6d133b6efce5 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -47,8 +47,10 @@ int ieee80211_wep_init(struct ieee80211_local *local)
47 47
48void ieee80211_wep_free(struct ieee80211_local *local) 48void ieee80211_wep_free(struct ieee80211_local *local)
49{ 49{
50 crypto_free_blkcipher(local->wep_tx_tfm); 50 if (!IS_ERR(local->wep_tx_tfm))
51 crypto_free_blkcipher(local->wep_rx_tfm); 51 crypto_free_blkcipher(local->wep_tx_tfm);
52 if (!IS_ERR(local->wep_rx_tfm))
53 crypto_free_blkcipher(local->wep_rx_tfm);
52} 54}
53 55
54static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) 56static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
@@ -122,19 +124,24 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
122/* Perform WEP encryption using given key. data buffer must have tailroom 124/* Perform WEP encryption using given key. data buffer must have tailroom
123 * for 4-byte ICV. data_len must not include this ICV. Note: this function 125 * for 4-byte ICV. data_len must not include this ICV. Note: this function
124 * does _not_ add IV. data = RC4(data | CRC32(data)) */ 126 * does _not_ add IV. data = RC4(data | CRC32(data)) */
125void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 127int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
126 size_t klen, u8 *data, size_t data_len) 128 size_t klen, u8 *data, size_t data_len)
127{ 129{
128 struct blkcipher_desc desc = { .tfm = tfm }; 130 struct blkcipher_desc desc = { .tfm = tfm };
129 struct scatterlist sg; 131 struct scatterlist sg;
130 __le32 icv; 132 __le32 icv;
131 133
134 if (IS_ERR(tfm))
135 return -1;
136
132 icv = cpu_to_le32(~crc32_le(~0, data, data_len)); 137 icv = cpu_to_le32(~crc32_le(~0, data, data_len));
133 put_unaligned(icv, (__le32 *)(data + data_len)); 138 put_unaligned(icv, (__le32 *)(data + data_len));
134 139
135 crypto_blkcipher_setkey(tfm, rc4key, klen); 140 crypto_blkcipher_setkey(tfm, rc4key, klen);
136 sg_init_one(&sg, data, data_len + WEP_ICV_LEN); 141 sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
137 crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); 142 crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
143
144 return 0;
138} 145}
139 146
140 147
@@ -168,10 +175,8 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
168 /* Add room for ICV */ 175 /* Add room for ICV */
169 skb_put(skb, WEP_ICV_LEN); 176 skb_put(skb, WEP_ICV_LEN);
170 177
171 ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, 178 return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
172 iv + WEP_IV_LEN, len); 179 iv + WEP_IV_LEN, len);
173
174 return 0;
175} 180}
176 181
177 182
@@ -185,6 +190,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
185 struct scatterlist sg; 190 struct scatterlist sg;
186 __le32 crc; 191 __le32 crc;
187 192
193 if (IS_ERR(tfm))
194 return -1;
195
188 crypto_blkcipher_setkey(tfm, rc4key, klen); 196 crypto_blkcipher_setkey(tfm, rc4key, klen);
189 sg_init_one(&sg, data, data_len + WEP_ICV_LEN); 197 sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
190 crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); 198 crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index fe29d7e5759f..58654ee33518 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -18,7 +18,7 @@
18 18
19int ieee80211_wep_init(struct ieee80211_local *local); 19int 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, 21int 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, 23int ieee80211_wep_encrypt(struct ieee80211_local *local,
24 struct sk_buff *skb, 24 struct sk_buff *skb,
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index a14e67707476..8d59d27d887e 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -183,9 +183,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
183 skb_put(skb, TKIP_ICV_LEN); 183 skb_put(skb, TKIP_ICV_LEN);
184 184
185 hdr = (struct ieee80211_hdr *) skb->data; 185 hdr = (struct ieee80211_hdr *) skb->data;
186 ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, 186 return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
187 key, pos, len, hdr->addr2); 187 key, pos, len, hdr->addr2);
188 return 0;
189} 188}
190 189
191 190