aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_crypt_tkip.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211/ieee80211_crypt_tkip.c')
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c128
1 files changed, 93 insertions, 35 deletions
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 3fa5df2e1f0b..4200ec509866 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.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>
@@ -53,8 +53,10 @@ struct ieee80211_tkip_data {
53 53
54 int key_idx; 54 int key_idx;
55 55
56 struct crypto_tfm *tfm_arc4; 56 struct crypto_blkcipher *rx_tfm_arc4;
57 struct crypto_tfm *tfm_michael; 57 struct crypto_hash *rx_tfm_michael;
58 struct crypto_blkcipher *tx_tfm_arc4;
59 struct crypto_hash *tx_tfm_michael;
58 60
59 /* scratch buffers for virt_to_page() (crypto API) */ 61 /* scratch buffers for virt_to_page() (crypto API) */
60 u8 rx_hdr[16], tx_hdr[16]; 62 u8 rx_hdr[16], tx_hdr[16];
@@ -86,17 +88,39 @@ static void *ieee80211_tkip_init(int key_idx)
86 88
87 priv->key_idx = key_idx; 89 priv->key_idx = key_idx;
88 90
89 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); 91 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
90 if (priv->tfm_arc4 == NULL) { 92 CRYPTO_ALG_ASYNC);
93 if (IS_ERR(priv->tx_tfm_arc4)) {
91 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 94 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
92 "crypto API arc4\n"); 95 "crypto API arc4\n");
96 priv->tx_tfm_arc4 = NULL;
93 goto fail; 97 goto fail;
94 } 98 }
95 99
96 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0); 100 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
97 if (priv->tfm_michael == NULL) { 101 CRYPTO_ALG_ASYNC);
102 if (IS_ERR(priv->tx_tfm_michael)) {
98 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 103 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
99 "crypto API michael_mic\n"); 104 "crypto API michael_mic\n");
105 priv->tx_tfm_michael = NULL;
106 goto fail;
107 }
108
109 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
110 CRYPTO_ALG_ASYNC);
111 if (IS_ERR(priv->rx_tfm_arc4)) {
112 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
113 "crypto API arc4\n");
114 priv->rx_tfm_arc4 = NULL;
115 goto fail;
116 }
117
118 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
119 CRYPTO_ALG_ASYNC);
120 if (IS_ERR(priv->rx_tfm_michael)) {
121 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
122 "crypto API michael_mic\n");
123 priv->rx_tfm_michael = NULL;
100 goto fail; 124 goto fail;
101 } 125 }
102 126
@@ -104,10 +128,14 @@ static void *ieee80211_tkip_init(int key_idx)
104 128
105 fail: 129 fail:
106 if (priv) { 130 if (priv) {
107 if (priv->tfm_michael) 131 if (priv->tx_tfm_michael)
108 crypto_free_tfm(priv->tfm_michael); 132 crypto_free_hash(priv->tx_tfm_michael);
109 if (priv->tfm_arc4) 133 if (priv->tx_tfm_arc4)
110 crypto_free_tfm(priv->tfm_arc4); 134 crypto_free_blkcipher(priv->tx_tfm_arc4);
135 if (priv->rx_tfm_michael)
136 crypto_free_hash(priv->rx_tfm_michael);
137 if (priv->rx_tfm_arc4)
138 crypto_free_blkcipher(priv->rx_tfm_arc4);
111 kfree(priv); 139 kfree(priv);
112 } 140 }
113 141
@@ -117,10 +145,16 @@ static void *ieee80211_tkip_init(int key_idx)
117static void ieee80211_tkip_deinit(void *priv) 145static void ieee80211_tkip_deinit(void *priv)
118{ 146{
119 struct ieee80211_tkip_data *_priv = priv; 147 struct ieee80211_tkip_data *_priv = priv;
120 if (_priv && _priv->tfm_michael) 148 if (_priv) {
121 crypto_free_tfm(_priv->tfm_michael); 149 if (_priv->tx_tfm_michael)
122 if (_priv && _priv->tfm_arc4) 150 crypto_free_hash(_priv->tx_tfm_michael);
123 crypto_free_tfm(_priv->tfm_arc4); 151 if (_priv->tx_tfm_arc4)
152 crypto_free_blkcipher(_priv->tx_tfm_arc4);
153 if (_priv->rx_tfm_michael)
154 crypto_free_hash(_priv->rx_tfm_michael);
155 if (_priv->rx_tfm_arc4)
156 crypto_free_blkcipher(_priv->rx_tfm_arc4);
157 }
124 kfree(priv); 158 kfree(priv);
125} 159}
126 160
@@ -319,6 +353,7 @@ static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
319static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 353static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
320{ 354{
321 struct ieee80211_tkip_data *tkey = priv; 355 struct ieee80211_tkip_data *tkey = priv;
356 struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
322 int len; 357 int len;
323 u8 rc4key[16], *pos, *icv; 358 u8 rc4key[16], *pos, *icv;
324 u32 crc; 359 u32 crc;
@@ -352,18 +387,30 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
352 icv[2] = crc >> 16; 387 icv[2] = crc >> 16;
353 icv[3] = crc >> 24; 388 icv[3] = crc >> 24;
354 389
355 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); 390 crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
356 sg.page = virt_to_page(pos); 391 sg.page = virt_to_page(pos);
357 sg.offset = offset_in_page(pos); 392 sg.offset = offset_in_page(pos);
358 sg.length = len + 4; 393 sg.length = len + 4;
359 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); 394 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
395}
360 396
397/*
398 * deal with seq counter wrapping correctly.
399 * refer to timer_after() for jiffies wrapping handling
400 */
401static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
402 u32 iv32_o, u16 iv16_o)
403{
404 if ((s32)iv32_n - (s32)iv32_o < 0 ||
405 (iv32_n == iv32_o && iv16_n <= iv16_o))
406 return 1;
361 return 0; 407 return 0;
362} 408}
363 409
364static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 410static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
365{ 411{
366 struct ieee80211_tkip_data *tkey = priv; 412 struct ieee80211_tkip_data *tkey = priv;
413 struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
367 u8 rc4key[16]; 414 u8 rc4key[16];
368 u8 keyidx, *pos; 415 u8 keyidx, *pos;
369 u32 iv32; 416 u32 iv32;
@@ -415,8 +462,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
415 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); 462 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
416 pos += 8; 463 pos += 8;
417 464
418 if (iv32 < tkey->rx_iv32 || 465 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
419 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
420 if (net_ratelimit()) { 466 if (net_ratelimit()) {
421 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT 467 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
422 " previous TSC %08x%04x received TSC " 468 " previous TSC %08x%04x received TSC "
@@ -435,11 +481,18 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
435 481
436 plen = skb->len - hdr_len - 12; 482 plen = skb->len - hdr_len - 12;
437 483
438 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); 484 crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
439 sg.page = virt_to_page(pos); 485 sg.page = virt_to_page(pos);
440 sg.offset = offset_in_page(pos); 486 sg.offset = offset_in_page(pos);
441 sg.length = plen + 4; 487 sg.length = plen + 4;
442 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); 488 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
489 if (net_ratelimit()) {
490 printk(KERN_DEBUG ": TKIP: failed to decrypt "
491 "received packet from " MAC_FMT "\n",
492 MAC_ARG(hdr->addr2));
493 }
494 return -7;
495 }
443 496
444 crc = ~crc32_le(~0, pos, plen); 497 crc = ~crc32_le(~0, pos, plen);
445 icv[0] = crc; 498 icv[0] = crc;
@@ -473,12 +526,13 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
473 return keyidx; 526 return keyidx;
474} 527}
475 528
476static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr, 529static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
477 u8 * data, size_t data_len, u8 * mic) 530 u8 * data, size_t data_len, u8 * mic)
478{ 531{
532 struct hash_desc desc;
479 struct scatterlist sg[2]; 533 struct scatterlist sg[2];
480 534
481 if (tkey->tfm_michael == NULL) { 535 if (tfm_michael == NULL) {
482 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); 536 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
483 return -1; 537 return -1;
484 } 538 }
@@ -490,12 +544,12 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
490 sg[1].offset = offset_in_page(data); 544 sg[1].offset = offset_in_page(data);
491 sg[1].length = data_len; 545 sg[1].length = data_len;
492 546
493 crypto_digest_init(tkey->tfm_michael); 547 if (crypto_hash_setkey(tfm_michael, key, 8))
494 crypto_digest_setkey(tkey->tfm_michael, key, 8); 548 return -1;
495 crypto_digest_update(tkey->tfm_michael, sg, 2);
496 crypto_digest_final(tkey->tfm_michael, mic);
497 549
498 return 0; 550 desc.tfm = tfm_michael;
551 desc.flags = 0;
552 return crypto_hash_digest(&desc, sg, data_len + 16, mic);
499} 553}
500 554
501static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) 555static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
@@ -529,7 +583,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
529 if (stype & IEEE80211_STYPE_QOS_DATA) { 583 if (stype & IEEE80211_STYPE_QOS_DATA) {
530 const struct ieee80211_hdr_3addrqos *qoshdr = 584 const struct ieee80211_hdr_3addrqos *qoshdr =
531 (struct ieee80211_hdr_3addrqos *)skb->data; 585 (struct ieee80211_hdr_3addrqos *)skb->data;
532 hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID; 586 hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID);
533 } else 587 } else
534 hdr[12] = 0; /* priority */ 588 hdr[12] = 0; /* priority */
535 589
@@ -551,7 +605,7 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
551 605
552 michael_mic_hdr(skb, tkey->tx_hdr); 606 michael_mic_hdr(skb, tkey->tx_hdr);
553 pos = skb_put(skb, 8); 607 pos = skb_put(skb, 8);
554 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr, 608 if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
555 skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) 609 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
556 return -1; 610 return -1;
557 611
@@ -589,7 +643,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
589 return -1; 643 return -1;
590 644
591 michael_mic_hdr(skb, tkey->rx_hdr); 645 michael_mic_hdr(skb, tkey->rx_hdr);
592 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr, 646 if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
593 skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) 647 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
594 return -1; 648 return -1;
595 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { 649 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
@@ -619,14 +673,18 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
619{ 673{
620 struct ieee80211_tkip_data *tkey = priv; 674 struct ieee80211_tkip_data *tkey = priv;
621 int keyidx; 675 int keyidx;
622 struct crypto_tfm *tfm = tkey->tfm_michael; 676 struct crypto_hash *tfm = tkey->tx_tfm_michael;
623 struct crypto_tfm *tfm2 = tkey->tfm_arc4; 677 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
678 struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
679 struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
624 680
625 keyidx = tkey->key_idx; 681 keyidx = tkey->key_idx;
626 memset(tkey, 0, sizeof(*tkey)); 682 memset(tkey, 0, sizeof(*tkey));
627 tkey->key_idx = keyidx; 683 tkey->key_idx = keyidx;
628 tkey->tfm_michael = tfm; 684 tkey->tx_tfm_michael = tfm;
629 tkey->tfm_arc4 = tfm2; 685 tkey->tx_tfm_arc4 = tfm2;
686 tkey->rx_tfm_michael = tfm3;
687 tkey->rx_tfm_arc4 = tfm4;
630 if (len == TKIP_KEY_LEN) { 688 if (len == TKIP_KEY_LEN) {
631 memcpy(tkey->key, key, TKIP_KEY_LEN); 689 memcpy(tkey->key, key, TKIP_KEY_LEN);
632 tkey->key_set = 1; 690 tkey->key_set = 1;