diff options
Diffstat (limited to 'net/ieee80211/ieee80211_crypt_tkip.c')
-rw-r--r-- | net/ieee80211/ieee80211_crypt_tkip.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index 34dba0ba545d..407a17495b61 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,8 +53,8 @@ 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_hash *tfm_michael; |
57 | 58 | ||
58 | /* scratch buffers for virt_to_page() (crypto API) */ | 59 | /* scratch buffers for virt_to_page() (crypto API) */ |
59 | u8 rx_hdr[16], tx_hdr[16]; | 60 | u8 rx_hdr[16], tx_hdr[16]; |
@@ -85,17 +86,21 @@ 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 | ||
95 | priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0); | 98 | priv->tfm_michael = crypto_alloc_hash("michael_mic", 0, |
96 | if (priv->tfm_michael == NULL) { | 99 | CRYPTO_ALG_ASYNC); |
100 | if (IS_ERR(priv->tfm_michael)) { | ||
97 | printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " | 101 | printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " |
98 | "crypto API michael_mic\n"); | 102 | "crypto API michael_mic\n"); |
103 | priv->tfm_michael = NULL; | ||
99 | goto fail; | 104 | goto fail; |
100 | } | 105 | } |
101 | 106 | ||
@@ -104,9 +109,9 @@ static void *ieee80211_tkip_init(int key_idx) | |||
104 | fail: | 109 | fail: |
105 | if (priv) { | 110 | if (priv) { |
106 | if (priv->tfm_michael) | 111 | if (priv->tfm_michael) |
107 | crypto_free_tfm(priv->tfm_michael); | 112 | crypto_free_hash(priv->tfm_michael); |
108 | if (priv->tfm_arc4) | 113 | if (priv->tfm_arc4) |
109 | crypto_free_tfm(priv->tfm_arc4); | 114 | crypto_free_blkcipher(priv->tfm_arc4); |
110 | kfree(priv); | 115 | kfree(priv); |
111 | } | 116 | } |
112 | 117 | ||
@@ -117,9 +122,9 @@ static void ieee80211_tkip_deinit(void *priv) | |||
117 | { | 122 | { |
118 | struct ieee80211_tkip_data *_priv = priv; | 123 | struct ieee80211_tkip_data *_priv = priv; |
119 | if (_priv && _priv->tfm_michael) | 124 | if (_priv && _priv->tfm_michael) |
120 | crypto_free_tfm(_priv->tfm_michael); | 125 | crypto_free_hash(_priv->tfm_michael); |
121 | if (_priv && _priv->tfm_arc4) | 126 | if (_priv && _priv->tfm_arc4) |
122 | crypto_free_tfm(_priv->tfm_arc4); | 127 | crypto_free_blkcipher(_priv->tfm_arc4); |
123 | kfree(priv); | 128 | kfree(priv); |
124 | } | 129 | } |
125 | 130 | ||
@@ -318,6 +323,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) | 323 | static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) |
319 | { | 324 | { |
320 | struct ieee80211_tkip_data *tkey = priv; | 325 | struct ieee80211_tkip_data *tkey = priv; |
326 | struct blkcipher_desc desc = { .tfm = tkey->tfm_arc4 }; | ||
321 | int len; | 327 | int len; |
322 | u8 rc4key[16], *pos, *icv; | 328 | u8 rc4key[16], *pos, *icv; |
323 | u32 crc; | 329 | u32 crc; |
@@ -351,18 +357,17 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
351 | icv[2] = crc >> 16; | 357 | icv[2] = crc >> 16; |
352 | icv[3] = crc >> 24; | 358 | icv[3] = crc >> 24; |
353 | 359 | ||
354 | crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); | 360 | crypto_blkcipher_setkey(tkey->tfm_arc4, rc4key, 16); |
355 | sg.page = virt_to_page(pos); | 361 | sg.page = virt_to_page(pos); |
356 | sg.offset = offset_in_page(pos); | 362 | sg.offset = offset_in_page(pos); |
357 | sg.length = len + 4; | 363 | sg.length = len + 4; |
358 | crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); | 364 | return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); |
359 | |||
360 | return 0; | ||
361 | } | 365 | } |
362 | 366 | ||
363 | static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | 367 | static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) |
364 | { | 368 | { |
365 | struct ieee80211_tkip_data *tkey = priv; | 369 | struct ieee80211_tkip_data *tkey = priv; |
370 | struct blkcipher_desc desc = { .tfm = tkey->tfm_arc4 }; | ||
366 | u8 rc4key[16]; | 371 | u8 rc4key[16]; |
367 | u8 keyidx, *pos; | 372 | u8 keyidx, *pos; |
368 | u32 iv32; | 373 | u32 iv32; |
@@ -434,11 +439,18 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
434 | 439 | ||
435 | plen = skb->len - hdr_len - 12; | 440 | plen = skb->len - hdr_len - 12; |
436 | 441 | ||
437 | crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); | 442 | crypto_blkcipher_setkey(tkey->tfm_arc4, rc4key, 16); |
438 | sg.page = virt_to_page(pos); | 443 | sg.page = virt_to_page(pos); |
439 | sg.offset = offset_in_page(pos); | 444 | sg.offset = offset_in_page(pos); |
440 | sg.length = plen + 4; | 445 | sg.length = plen + 4; |
441 | crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); | 446 | if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { |
447 | if (net_ratelimit()) { | ||
448 | printk(KERN_DEBUG ": TKIP: failed to decrypt " | ||
449 | "received packet from " MAC_FMT "\n", | ||
450 | MAC_ARG(hdr->addr2)); | ||
451 | } | ||
452 | return -7; | ||
453 | } | ||
442 | 454 | ||
443 | crc = ~crc32_le(~0, pos, plen); | 455 | crc = ~crc32_le(~0, pos, plen); |
444 | icv[0] = crc; | 456 | icv[0] = crc; |
@@ -475,6 +487,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
475 | static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr, | 487 | static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr, |
476 | u8 * data, size_t data_len, u8 * mic) | 488 | u8 * data, size_t data_len, u8 * mic) |
477 | { | 489 | { |
490 | struct hash_desc desc; | ||
478 | struct scatterlist sg[2]; | 491 | struct scatterlist sg[2]; |
479 | 492 | ||
480 | if (tkey->tfm_michael == NULL) { | 493 | if (tkey->tfm_michael == NULL) { |
@@ -489,12 +502,12 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr, | |||
489 | sg[1].offset = offset_in_page(data); | 502 | sg[1].offset = offset_in_page(data); |
490 | sg[1].length = data_len; | 503 | sg[1].length = data_len; |
491 | 504 | ||
492 | crypto_digest_init(tkey->tfm_michael); | 505 | if (crypto_hash_setkey(tkey->tfm_michael, key, 8)) |
493 | crypto_digest_setkey(tkey->tfm_michael, key, 8); | 506 | return -1; |
494 | crypto_digest_update(tkey->tfm_michael, sg, 2); | ||
495 | crypto_digest_final(tkey->tfm_michael, mic); | ||
496 | 507 | ||
497 | return 0; | 508 | desc.tfm = tkey->tfm_michael; |
509 | desc.flags = 0; | ||
510 | return crypto_hash_digest(&desc, sg, data_len + 16, mic); | ||
498 | } | 511 | } |
499 | 512 | ||
500 | static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) | 513 | static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) |
@@ -618,8 +631,8 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv) | |||
618 | { | 631 | { |
619 | struct ieee80211_tkip_data *tkey = priv; | 632 | struct ieee80211_tkip_data *tkey = priv; |
620 | int keyidx; | 633 | int keyidx; |
621 | struct crypto_tfm *tfm = tkey->tfm_michael; | 634 | struct crypto_hash *tfm = tkey->tfm_michael; |
622 | struct crypto_tfm *tfm2 = tkey->tfm_arc4; | 635 | struct crypto_blkcipher *tfm2 = tkey->tfm_arc4; |
623 | 636 | ||
624 | keyidx = tkey->key_idx; | 637 | keyidx = tkey->key_idx; |
625 | memset(tkey, 0, sizeof(*tkey)); | 638 | memset(tkey, 0, sizeof(*tkey)); |