aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wep.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r--net/mac80211/wep.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index f0e2d3ecb5c4..7043ddc75498 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -17,6 +17,7 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/scatterlist.h> 19#include <linux/scatterlist.h>
20#include <asm/unaligned.h>
20 21
21#include <net/mac80211.h> 22#include <net/mac80211.h>
22#include "ieee80211_i.h" 23#include "ieee80211_i.h"
@@ -49,17 +50,19 @@ void ieee80211_wep_free(struct ieee80211_local *local)
49 crypto_free_blkcipher(local->wep_rx_tfm); 50 crypto_free_blkcipher(local->wep_rx_tfm);
50} 51}
51 52
52static inline int ieee80211_wep_weak_iv(u32 iv, int keylen) 53static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
53{ 54{
54 /* Fluhrer, Mantin, and Shamir have reported weaknesses in the 55 /*
56 * Fluhrer, Mantin, and Shamir have reported weaknesses in the
55 * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, 57 * key scheduling algorithm of RC4. At least IVs (KeyByte + 3,
56 * 0xff, N) can be used to speedup attacks, so avoid using them. */ 58 * 0xff, N) can be used to speedup attacks, so avoid using them.
59 */
57 if ((iv & 0xff00) == 0xff00) { 60 if ((iv & 0xff00) == 0xff00) {
58 u8 B = (iv >> 16) & 0xff; 61 u8 B = (iv >> 16) & 0xff;
59 if (B >= 3 && B < 3 + keylen) 62 if (B >= 3 && B < 3 + keylen)
60 return 1; 63 return true;
61 } 64 }
62 return 0; 65 return false;
63} 66}
64 67
65 68
@@ -123,10 +126,10 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
123{ 126{
124 struct blkcipher_desc desc = { .tfm = tfm }; 127 struct blkcipher_desc desc = { .tfm = tfm };
125 struct scatterlist sg; 128 struct scatterlist sg;
126 __le32 *icv; 129 __le32 icv;
127 130
128 icv = (__le32 *)(data + data_len); 131 icv = cpu_to_le32(~crc32_le(~0, data, data_len));
129 *icv = cpu_to_le32(~crc32_le(~0, data, data_len)); 132 put_unaligned(icv, (__le32 *)(data + data_len));
130 133
131 crypto_blkcipher_setkey(tfm, rc4key, klen); 134 crypto_blkcipher_setkey(tfm, rc4key, klen);
132 sg_init_one(&sg, data, data_len + WEP_ICV_LEN); 135 sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
@@ -268,7 +271,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
268} 271}
269 272
270 273
271u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) 274bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
272{ 275{
273 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 276 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
274 unsigned int hdrlen; 277 unsigned int hdrlen;
@@ -276,16 +279,13 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
276 u32 iv; 279 u32 iv;
277 280
278 if (!ieee80211_has_protected(hdr->frame_control)) 281 if (!ieee80211_has_protected(hdr->frame_control))
279 return NULL; 282 return false;
280 283
281 hdrlen = ieee80211_hdrlen(hdr->frame_control); 284 hdrlen = ieee80211_hdrlen(hdr->frame_control);
282 ivpos = skb->data + hdrlen; 285 ivpos = skb->data + hdrlen;
283 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; 286 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
284 287
285 if (ieee80211_wep_weak_iv(iv, key->conf.keylen)) 288 return ieee80211_wep_weak_iv(iv, key->conf.keylen);
286 return ivpos;
287
288 return NULL;
289} 289}
290 290
291ieee80211_rx_result 291ieee80211_rx_result
@@ -329,6 +329,8 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
329ieee80211_tx_result 329ieee80211_tx_result
330ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) 330ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
331{ 331{
332 int i;
333
332 ieee80211_tx_set_protected(tx); 334 ieee80211_tx_set_protected(tx);
333 335
334 if (wep_encrypt_skb(tx, tx->skb) < 0) { 336 if (wep_encrypt_skb(tx, tx->skb) < 0) {
@@ -337,9 +339,8 @@ ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
337 } 339 }
338 340
339 if (tx->extra_frag) { 341 if (tx->extra_frag) {
340 int i;
341 for (i = 0; i < tx->num_extra_frag; i++) { 342 for (i = 0; i < tx->num_extra_frag; i++) {
342 if (wep_encrypt_skb(tx, tx->extra_frag[i]) < 0) { 343 if (wep_encrypt_skb(tx, tx->extra_frag[i])) {
343 I802_DEBUG_INC(tx->local-> 344 I802_DEBUG_INC(tx->local->
344 tx_handlers_drop_wep); 345 tx_handlers_drop_wep);
345 return TX_DROP; 346 return TX_DROP;