diff options
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r-- | net/mac80211/wep.c | 33 |
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 | ||
52 | static inline int ieee80211_wep_weak_iv(u32 iv, int keylen) | 53 | static 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 | ||
271 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 274 | bool 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 | ||
291 | ieee80211_rx_result | 291 | ieee80211_rx_result |
@@ -329,6 +329,8 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
329 | ieee80211_tx_result | 329 | ieee80211_tx_result |
330 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | 330 | ieee80211_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; |