summaryrefslogtreecommitdiffstats
path: root/net/mac80211/wep.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r--net/mac80211/wep.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5f3a4113bda..9ebc8d8a1f5 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -32,13 +32,16 @@ int ieee80211_wep_init(struct ieee80211_local *local)
local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
- if (IS_ERR(local->wep_tx_tfm))
+ if (IS_ERR(local->wep_tx_tfm)) {
+ local->wep_rx_tfm = ERR_PTR(-EINVAL);
return PTR_ERR(local->wep_tx_tfm);
+ }
local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(local->wep_rx_tfm)) {
crypto_free_blkcipher(local->wep_tx_tfm);
+ local->wep_tx_tfm = ERR_PTR(-EINVAL);
return PTR_ERR(local->wep_rx_tfm);
}
@@ -47,8 +50,10 @@ int ieee80211_wep_init(struct ieee80211_local *local)
void ieee80211_wep_free(struct ieee80211_local *local)
{
- crypto_free_blkcipher(local->wep_tx_tfm);
- crypto_free_blkcipher(local->wep_rx_tfm);
+ if (!IS_ERR(local->wep_tx_tfm))
+ crypto_free_blkcipher(local->wep_tx_tfm);
+ if (!IS_ERR(local->wep_rx_tfm))
+ crypto_free_blkcipher(local->wep_rx_tfm);
}
static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
@@ -122,19 +127,24 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
/* Perform WEP encryption using given key. data buffer must have tailroom
* for 4-byte ICV. data_len must not include this ICV. Note: this function
* does _not_ add IV. data = RC4(data | CRC32(data)) */
-void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len)
+int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+ size_t klen, u8 *data, size_t data_len)
{
struct blkcipher_desc desc = { .tfm = tfm };
struct scatterlist sg;
__le32 icv;
+ if (IS_ERR(tfm))
+ return -1;
+
icv = cpu_to_le32(~crc32_le(~0, data, data_len));
put_unaligned(icv, (__le32 *)(data + data_len));
crypto_blkcipher_setkey(tfm, rc4key, klen);
sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
+
+ return 0;
}
@@ -168,10 +178,8 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
/* Add room for ICV */
skb_put(skb, WEP_ICV_LEN);
- ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
- iv + WEP_IV_LEN, len);
-
- return 0;
+ return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
+ iv + WEP_IV_LEN, len);
}
@@ -185,6 +193,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
struct scatterlist sg;
__le32 crc;
+ if (IS_ERR(tfm))
+ return -1;
+
crypto_blkcipher_setkey(tfm, rc4key, klen);
sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);