11 #include <linux/netdevice.h>
12 #include <linux/types.h>
13 #include <linux/random.h>
14 #include <linux/compiler.h>
20 #include <linux/slab.h>
21 #include <asm/unaligned.h>
57 static inline bool ieee80211_wep_weak_iv(
u32 iv,
int keylen)
64 if ((iv & 0xff00) == 0xff00) {
65 u8 B = (iv >> 16) & 0xff;
66 if (B >= 3 && B < 3 + keylen)
74 int keylen,
int keyidx,
u8 *iv)
77 if (ieee80211_wep_weak_iv(local->
wep_iv, keylen))
83 *iv++ = (local->
wep_iv >> 16) & 0xff;
84 *iv++ = (local->
wep_iv >> 8) & 0xff;
85 *iv++ = local->
wep_iv & 0xff;
92 int keylen,
int keyidx)
110 if (
info->control.hw_key &&
114 skb_set_network_header(skb, skb_network_offset(skb) +
WEP_IV_LEN);
115 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
148 crypto_cipher_setkey(tfm, rc4key, klen);
150 crypto_cipher_encrypt_one(tfm, data + i, data + i);
165 const u8 *key,
int keylen,
int keyidx)
171 iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx);
181 memcpy(rc4key + 3, key, keylen);
203 crypto_cipher_setkey(tfm, rc4key, klen);
205 crypto_cipher_decrypt_one(tfm, data + i, data + i);
208 if (
memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0)
245 keyidx = skb->
data[hdrlen + 3] >> 6;
247 if (!key || keyidx != key->
conf.keyidx)
250 klen = 3 + key->
conf.keylen;
274 static bool ieee80211_wep_is_weak_iv(
struct sk_buff *skb,
284 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
286 return ieee80211_wep_weak_iv(iv, key->
conf.keylen);
297 if (!ieee80211_is_data(
fc) && !ieee80211_is_auth(
fc))
301 if (skb_linearize(rx->
skb))
303 if (rx->
sta && ieee80211_wep_is_weak_iv(rx->
skb, rx->
key))
304 rx->
sta->wep_weak_iv_count++;
310 if (rx->
sta && ieee80211_wep_is_weak_iv(rx->
skb, rx->
key))
311 rx->
sta->wep_weak_iv_count++;
312 ieee80211_wep_remove_iv(rx->
local, rx->
skb, rx->
key);
314 if (pskb_trim(rx->
skb, rx->
skb->len - WEP_ICV_LEN))
328 tx->
key->conf.keylen,
329 tx->
key->conf.keyidx))
333 if (!ieee80211_wep_add_iv(tx->
local, skb,
334 tx->
key->conf.keylen,
335 tx->
key->conf.keyidx))
349 skb_queue_walk(&tx->
skbs, skb) {
350 if (wep_encrypt_skb(tx, skb) < 0) {