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.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5f3a4113bda1..9ebc8d8a1f5b 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -32,13 +32,16 @@ int ieee80211_wep_init(struct ieee80211_local *local)
32 32
33 local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, 33 local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
34 CRYPTO_ALG_ASYNC); 34 CRYPTO_ALG_ASYNC);
35 if (IS_ERR(local->wep_tx_tfm)) 35 if (IS_ERR(local->wep_tx_tfm)) {
36 local->wep_rx_tfm = ERR_PTR(-EINVAL);
36 return PTR_ERR(local->wep_tx_tfm); 37 return PTR_ERR(local->wep_tx_tfm);
38 }
37 39
38 local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, 40 local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
39 CRYPTO_ALG_ASYNC); 41 CRYPTO_ALG_ASYNC);
40 if (IS_ERR(local->wep_rx_tfm)) { 42 if (IS_ERR(local->wep_rx_tfm)) {
41 crypto_free_blkcipher(local->wep_tx_tfm); 43 crypto_free_blkcipher(local->wep_tx_tfm);
44 local->wep_tx_tfm = ERR_PTR(-EINVAL);
42 return PTR_ERR(local->wep_rx_tfm); 45 return PTR_ERR(local->wep_rx_tfm);
43 } 46 }
44 47
@@ -47,8 +50,10 @@ int ieee80211_wep_init(struct ieee80211_local *local)
47 50
48void ieee80211_wep_free(struct ieee80211_local *local) 51void ieee80211_wep_free(struct ieee80211_local *local)
49{ 52{
50 crypto_free_blkcipher(local->wep_tx_tfm); 53 if (!IS_ERR(local->wep_tx_tfm))
51 crypto_free_blkcipher(local->wep_rx_tfm); 54 crypto_free_blkcipher(local->wep_tx_tfm);
55 if (!IS_ERR(local->wep_rx_tfm))
56 crypto_free_blkcipher(local->wep_rx_tfm);
52} 57}
53 58
54static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) 59static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
@@ -122,19 +127,24 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
122/* Perform WEP encryption using given key. data buffer must have tailroom 127/* 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 128 * for 4-byte ICV. data_len must not include this ICV. Note: this function
124 * does _not_ add IV. data = RC4(data | CRC32(data)) */ 129 * does _not_ add IV. data = RC4(data | CRC32(data)) */
125void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 130int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
126 size_t klen, u8 *data, size_t data_len) 131 size_t klen, u8 *data, size_t data_len)
127{ 132{
128 struct blkcipher_desc desc = { .tfm = tfm }; 133 struct blkcipher_desc desc = { .tfm = tfm };
129 struct scatterlist sg; 134 struct scatterlist sg;
130 __le32 icv; 135 __le32 icv;
131 136
137 if (IS_ERR(tfm))
138 return -1;
139
132 icv = cpu_to_le32(~crc32_le(~0, data, data_len)); 140 icv = cpu_to_le32(~crc32_le(~0, data, data_len));
133 put_unaligned(icv, (__le32 *)(data + data_len)); 141 put_unaligned(icv, (__le32 *)(data + data_len));
134 142
135 crypto_blkcipher_setkey(tfm, rc4key, klen); 143 crypto_blkcipher_setkey(tfm, rc4key, klen);
136 sg_init_one(&sg, data, data_len + WEP_ICV_LEN); 144 sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
137 crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); 145 crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
146
147 return 0;
138} 148}
139 149
140 150
@@ -168,10 +178,8 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
168 /* Add room for ICV */ 178 /* Add room for ICV */
169 skb_put(skb, WEP_ICV_LEN); 179 skb_put(skb, WEP_ICV_LEN);
170 180
171 ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, 181 return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
172 iv + WEP_IV_LEN, len); 182 iv + WEP_IV_LEN, len);
173
174 return 0;
175} 183}
176 184
177 185
@@ -185,6 +193,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
185 struct scatterlist sg; 193 struct scatterlist sg;
186 __le32 crc; 194 __le32 crc;
187 195
196 if (IS_ERR(tfm))
197 return -1;
198
188 crypto_blkcipher_setkey(tfm, rc4key, klen); 199 crypto_blkcipher_setkey(tfm, rc4key, klen);
189 sg_init_one(&sg, data, data_len + WEP_ICV_LEN); 200 sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
190 crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); 201 crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);