diff options
Diffstat (limited to 'net/ieee80211/ieee80211_crypt_wep.c')
| -rw-r--r-- | net/ieee80211/ieee80211_crypt_wep.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c index 649e581fa565..1b2efff11d39 100644 --- a/net/ieee80211/ieee80211_crypt_wep.c +++ b/net/ieee80211/ieee80211_crypt_wep.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * more details. | 9 | * more details. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/config.h> | 12 | #include <linux/err.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| @@ -33,26 +33,34 @@ struct prism2_wep_data { | |||
| 33 | u8 key[WEP_KEY_LEN + 1]; | 33 | u8 key[WEP_KEY_LEN + 1]; |
| 34 | u8 key_len; | 34 | u8 key_len; |
| 35 | u8 key_idx; | 35 | u8 key_idx; |
| 36 | struct crypto_tfm *tfm; | 36 | struct crypto_blkcipher *tx_tfm; |
| 37 | struct crypto_blkcipher *rx_tfm; | ||
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | static void *prism2_wep_init(int keyidx) | 40 | static void *prism2_wep_init(int keyidx) |
| 40 | { | 41 | { |
| 41 | struct prism2_wep_data *priv; | 42 | struct prism2_wep_data *priv; |
| 42 | 43 | ||
| 43 | priv = kmalloc(sizeof(*priv), GFP_ATOMIC); | 44 | priv = kzalloc(sizeof(*priv), GFP_ATOMIC); |
| 44 | if (priv == NULL) | 45 | if (priv == NULL) |
| 45 | goto fail; | 46 | goto fail; |
| 46 | memset(priv, 0, sizeof(*priv)); | ||
| 47 | priv->key_idx = keyidx; | 47 | priv->key_idx = keyidx; |
| 48 | 48 | ||
| 49 | priv->tfm = crypto_alloc_tfm("arc4", 0); | 49 | priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); |
| 50 | if (priv->tfm == NULL) { | 50 | if (IS_ERR(priv->tx_tfm)) { |
| 51 | printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " | 51 | printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " |
| 52 | "crypto API arc4\n"); | 52 | "crypto API arc4\n"); |
| 53 | priv->tx_tfm = NULL; | ||
| 53 | goto fail; | 54 | goto fail; |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 57 | priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); | ||
| 58 | if (IS_ERR(priv->rx_tfm)) { | ||
| 59 | printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " | ||
| 60 | "crypto API arc4\n"); | ||
| 61 | priv->rx_tfm = NULL; | ||
| 62 | goto fail; | ||
| 63 | } | ||
| 56 | /* start WEP IV from a random value */ | 64 | /* start WEP IV from a random value */ |
| 57 | get_random_bytes(&priv->iv, 4); | 65 | get_random_bytes(&priv->iv, 4); |
| 58 | 66 | ||
| @@ -60,8 +68,10 @@ static void *prism2_wep_init(int keyidx) | |||
| 60 | 68 | ||
| 61 | fail: | 69 | fail: |
| 62 | if (priv) { | 70 | if (priv) { |
| 63 | if (priv->tfm) | 71 | if (priv->tx_tfm) |
| 64 | crypto_free_tfm(priv->tfm); | 72 | crypto_free_blkcipher(priv->tx_tfm); |
| 73 | if (priv->rx_tfm) | ||
| 74 | crypto_free_blkcipher(priv->rx_tfm); | ||
| 65 | kfree(priv); | 75 | kfree(priv); |
| 66 | } | 76 | } |
| 67 | return NULL; | 77 | return NULL; |
| @@ -70,8 +80,12 @@ static void *prism2_wep_init(int keyidx) | |||
| 70 | static void prism2_wep_deinit(void *priv) | 80 | static void prism2_wep_deinit(void *priv) |
| 71 | { | 81 | { |
| 72 | struct prism2_wep_data *_priv = priv; | 82 | struct prism2_wep_data *_priv = priv; |
| 73 | if (_priv && _priv->tfm) | 83 | if (_priv) { |
| 74 | crypto_free_tfm(_priv->tfm); | 84 | if (_priv->tx_tfm) |
| 85 | crypto_free_blkcipher(_priv->tx_tfm); | ||
| 86 | if (_priv->rx_tfm) | ||
| 87 | crypto_free_blkcipher(_priv->rx_tfm); | ||
| 88 | } | ||
| 75 | kfree(priv); | 89 | kfree(priv); |
| 76 | } | 90 | } |
| 77 | 91 | ||
| @@ -122,6 +136,7 @@ static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, | |||
| 122 | static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | 136 | static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) |
| 123 | { | 137 | { |
| 124 | struct prism2_wep_data *wep = priv; | 138 | struct prism2_wep_data *wep = priv; |
| 139 | struct blkcipher_desc desc = { .tfm = wep->tx_tfm }; | ||
| 125 | u32 crc, klen, len; | 140 | u32 crc, klen, len; |
| 126 | u8 *pos, *icv; | 141 | u8 *pos, *icv; |
| 127 | struct scatterlist sg; | 142 | struct scatterlist sg; |
| @@ -153,13 +168,11 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
| 153 | icv[2] = crc >> 16; | 168 | icv[2] = crc >> 16; |
| 154 | icv[3] = crc >> 24; | 169 | icv[3] = crc >> 24; |
| 155 | 170 | ||
| 156 | crypto_cipher_setkey(wep->tfm, key, klen); | 171 | crypto_blkcipher_setkey(wep->tx_tfm, key, klen); |
| 157 | sg.page = virt_to_page(pos); | 172 | sg.page = virt_to_page(pos); |
| 158 | sg.offset = offset_in_page(pos); | 173 | sg.offset = offset_in_page(pos); |
| 159 | sg.length = len + 4; | 174 | sg.length = len + 4; |
| 160 | crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4); | 175 | return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); |
| 161 | |||
| 162 | return 0; | ||
| 163 | } | 176 | } |
| 164 | 177 | ||
| 165 | /* Perform WEP decryption on given buffer. Buffer includes whole WEP part of | 178 | /* Perform WEP decryption on given buffer. Buffer includes whole WEP part of |
| @@ -172,6 +185,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
| 172 | static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | 185 | static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) |
| 173 | { | 186 | { |
| 174 | struct prism2_wep_data *wep = priv; | 187 | struct prism2_wep_data *wep = priv; |
| 188 | struct blkcipher_desc desc = { .tfm = wep->rx_tfm }; | ||
| 175 | u32 crc, klen, plen; | 189 | u32 crc, klen, plen; |
| 176 | u8 key[WEP_KEY_LEN + 3]; | 190 | u8 key[WEP_KEY_LEN + 3]; |
| 177 | u8 keyidx, *pos, icv[4]; | 191 | u8 keyidx, *pos, icv[4]; |
| @@ -196,11 +210,12 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
| 196 | /* Apply RC4 to data and compute CRC32 over decrypted data */ | 210 | /* Apply RC4 to data and compute CRC32 over decrypted data */ |
| 197 | plen = skb->len - hdr_len - 8; | 211 | plen = skb->len - hdr_len - 8; |
| 198 | 212 | ||
| 199 | crypto_cipher_setkey(wep->tfm, key, klen); | 213 | crypto_blkcipher_setkey(wep->rx_tfm, key, klen); |
| 200 | sg.page = virt_to_page(pos); | 214 | sg.page = virt_to_page(pos); |
| 201 | sg.offset = offset_in_page(pos); | 215 | sg.offset = offset_in_page(pos); |
| 202 | sg.length = plen + 4; | 216 | sg.length = plen + 4; |
| 203 | crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4); | 217 | if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) |
| 218 | return -7; | ||
| 204 | 219 | ||
| 205 | crc = ~crc32_le(~0, pos, plen); | 220 | crc = ~crc32_le(~0, pos, plen); |
| 206 | icv[0] = crc; | 221 | icv[0] = crc; |
