diff options
Diffstat (limited to 'net/ieee80211/ieee80211_crypt_tkip.c')
-rw-r--r-- | net/ieee80211/ieee80211_crypt_tkip.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index 34dba0ba545d..d60ce9b49b4f 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * more details. | 9 | * more details. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/err.h> | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
@@ -52,7 +53,7 @@ struct ieee80211_tkip_data { | |||
52 | 53 | ||
53 | int key_idx; | 54 | int key_idx; |
54 | 55 | ||
55 | struct crypto_tfm *tfm_arc4; | 56 | struct crypto_blkcipher *tfm_arc4; |
56 | struct crypto_tfm *tfm_michael; | 57 | struct crypto_tfm *tfm_michael; |
57 | 58 | ||
58 | /* scratch buffers for virt_to_page() (crypto API) */ | 59 | /* scratch buffers for virt_to_page() (crypto API) */ |
@@ -85,10 +86,12 @@ static void *ieee80211_tkip_init(int key_idx) | |||
85 | 86 | ||
86 | priv->key_idx = key_idx; | 87 | priv->key_idx = key_idx; |
87 | 88 | ||
88 | priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); | 89 | priv->tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, |
89 | if (priv->tfm_arc4 == NULL) { | 90 | CRYPTO_ALG_ASYNC); |
91 | if (IS_ERR(priv->tfm_arc4)) { | ||
90 | printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " | 92 | printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " |
91 | "crypto API arc4\n"); | 93 | "crypto API arc4\n"); |
94 | priv->tfm_arc4 = NULL; | ||
92 | goto fail; | 95 | goto fail; |
93 | } | 96 | } |
94 | 97 | ||
@@ -106,7 +109,7 @@ static void *ieee80211_tkip_init(int key_idx) | |||
106 | if (priv->tfm_michael) | 109 | if (priv->tfm_michael) |
107 | crypto_free_tfm(priv->tfm_michael); | 110 | crypto_free_tfm(priv->tfm_michael); |
108 | if (priv->tfm_arc4) | 111 | if (priv->tfm_arc4) |
109 | crypto_free_tfm(priv->tfm_arc4); | 112 | crypto_free_blkcipher(priv->tfm_arc4); |
110 | kfree(priv); | 113 | kfree(priv); |
111 | } | 114 | } |
112 | 115 | ||
@@ -119,7 +122,7 @@ static void ieee80211_tkip_deinit(void *priv) | |||
119 | if (_priv && _priv->tfm_michael) | 122 | if (_priv && _priv->tfm_michael) |
120 | crypto_free_tfm(_priv->tfm_michael); | 123 | crypto_free_tfm(_priv->tfm_michael); |
121 | if (_priv && _priv->tfm_arc4) | 124 | if (_priv && _priv->tfm_arc4) |
122 | crypto_free_tfm(_priv->tfm_arc4); | 125 | crypto_free_blkcipher(_priv->tfm_arc4); |
123 | kfree(priv); | 126 | kfree(priv); |
124 | } | 127 | } |
125 | 128 | ||
@@ -318,6 +321,7 @@ static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, | |||
318 | static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | 321 | static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) |
319 | { | 322 | { |
320 | struct ieee80211_tkip_data *tkey = priv; | 323 | struct ieee80211_tkip_data *tkey = priv; |
324 | struct blkcipher_desc desc = { .tfm = tkey->tfm_arc4 }; | ||
321 | int len; | 325 | int len; |
322 | u8 rc4key[16], *pos, *icv; | 326 | u8 rc4key[16], *pos, *icv; |
323 | u32 crc; | 327 | u32 crc; |
@@ -351,18 +355,17 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
351 | icv[2] = crc >> 16; | 355 | icv[2] = crc >> 16; |
352 | icv[3] = crc >> 24; | 356 | icv[3] = crc >> 24; |
353 | 357 | ||
354 | crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); | 358 | crypto_blkcipher_setkey(tkey->tfm_arc4, rc4key, 16); |
355 | sg.page = virt_to_page(pos); | 359 | sg.page = virt_to_page(pos); |
356 | sg.offset = offset_in_page(pos); | 360 | sg.offset = offset_in_page(pos); |
357 | sg.length = len + 4; | 361 | sg.length = len + 4; |
358 | crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); | 362 | return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); |
359 | |||
360 | return 0; | ||
361 | } | 363 | } |
362 | 364 | ||
363 | static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | 365 | static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) |
364 | { | 366 | { |
365 | struct ieee80211_tkip_data *tkey = priv; | 367 | struct ieee80211_tkip_data *tkey = priv; |
368 | struct blkcipher_desc desc = { .tfm = tkey->tfm_arc4 }; | ||
366 | u8 rc4key[16]; | 369 | u8 rc4key[16]; |
367 | u8 keyidx, *pos; | 370 | u8 keyidx, *pos; |
368 | u32 iv32; | 371 | u32 iv32; |
@@ -434,11 +437,18 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
434 | 437 | ||
435 | plen = skb->len - hdr_len - 12; | 438 | plen = skb->len - hdr_len - 12; |
436 | 439 | ||
437 | crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); | 440 | crypto_blkcipher_setkey(tkey->tfm_arc4, rc4key, 16); |
438 | sg.page = virt_to_page(pos); | 441 | sg.page = virt_to_page(pos); |
439 | sg.offset = offset_in_page(pos); | 442 | sg.offset = offset_in_page(pos); |
440 | sg.length = plen + 4; | 443 | sg.length = plen + 4; |
441 | crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); | 444 | if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { |
445 | if (net_ratelimit()) { | ||
446 | printk(KERN_DEBUG ": TKIP: failed to decrypt " | ||
447 | "received packet from " MAC_FMT "\n", | ||
448 | MAC_ARG(hdr->addr2)); | ||
449 | } | ||
450 | return -7; | ||
451 | } | ||
442 | 452 | ||
443 | crc = ~crc32_le(~0, pos, plen); | 453 | crc = ~crc32_le(~0, pos, plen); |
444 | icv[0] = crc; | 454 | icv[0] = crc; |
@@ -619,7 +629,7 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv) | |||
619 | struct ieee80211_tkip_data *tkey = priv; | 629 | struct ieee80211_tkip_data *tkey = priv; |
620 | int keyidx; | 630 | int keyidx; |
621 | struct crypto_tfm *tfm = tkey->tfm_michael; | 631 | struct crypto_tfm *tfm = tkey->tfm_michael; |
622 | struct crypto_tfm *tfm2 = tkey->tfm_arc4; | 632 | struct crypto_blkcipher *tfm2 = tkey->tfm_arc4; |
623 | 633 | ||
624 | keyidx = tkey->key_idx; | 634 | keyidx = tkey->key_idx; |
625 | memset(tkey, 0, sizeof(*tkey)); | 635 | memset(tkey, 0, sizeof(*tkey)); |