aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/aes_cmac.c8
-rw-r--r--net/mac80211/aes_cmac.h2
-rw-r--r--net/mac80211/cfg.c13
-rw-r--r--net/mac80211/debugfs_key.c7
-rw-r--r--net/mac80211/key.h5
-rw-r--r--net/mac80211/wpa.c30
6 files changed, 33 insertions, 32 deletions
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index d502b2684a66..08b0f1768aad 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -35,10 +35,10 @@ static void gf_mulx(u8 *pad)
35} 35}
36 36
37 37
38static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch, 38static void aes_128_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
39 size_t num_elem,
40 const u8 *addr[], const size_t *len, u8 *mac) 39 const u8 *addr[], const size_t *len, u8 *mac)
41{ 40{
41 u8 scratch[2 * AES_BLOCK_SIZE];
42 u8 *cbc, *pad; 42 u8 *cbc, *pad;
43 const u8 *pos, *end; 43 const u8 *pos, *end;
44 size_t i, e, left, total_len; 44 size_t i, e, left, total_len;
@@ -95,7 +95,7 @@ static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch,
95} 95}
96 96
97 97
98void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, 98void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
99 const u8 *data, size_t data_len, u8 *mic) 99 const u8 *data, size_t data_len, u8 *mic)
100{ 100{
101 const u8 *addr[3]; 101 const u8 *addr[3];
@@ -110,7 +110,7 @@ void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad,
110 addr[2] = zero; 110 addr[2] = zero;
111 len[2] = CMAC_TLEN; 111 len[2] = CMAC_TLEN;
112 112
113 aes_128_cmac_vector(tfm, scratch, 3, addr, len, mic); 113 aes_128_cmac_vector(tfm, 3, addr, len, mic);
114} 114}
115 115
116 116
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h
index 0eb9a4831508..20785a647254 100644
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
@@ -12,7 +12,7 @@
12#include <linux/crypto.h> 12#include <linux/crypto.h>
13 13
14struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); 14struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]);
15void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, 15void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
16 const u8 *data, size_t data_len, u8 *mic); 16 const u8 *data, size_t data_len, u8 *mic);
17void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); 17void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm);
18 18
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 3000b4c3b525..bfc36e904764 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -268,12 +268,13 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
268 params.seq_len = 6; 268 params.seq_len = 6;
269 break; 269 break;
270 case WLAN_CIPHER_SUITE_AES_CMAC: 270 case WLAN_CIPHER_SUITE_AES_CMAC:
271 seq[0] = key->u.aes_cmac.tx_pn[5]; 271 pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
272 seq[1] = key->u.aes_cmac.tx_pn[4]; 272 seq[0] = pn64;
273 seq[2] = key->u.aes_cmac.tx_pn[3]; 273 seq[1] = pn64 >> 8;
274 seq[3] = key->u.aes_cmac.tx_pn[2]; 274 seq[2] = pn64 >> 16;
275 seq[4] = key->u.aes_cmac.tx_pn[1]; 275 seq[3] = pn64 >> 24;
276 seq[5] = key->u.aes_cmac.tx_pn[0]; 276 seq[4] = pn64 >> 32;
277 seq[5] = pn64 >> 40;
277 params.seq = seq; 278 params.seq = seq;
278 params.seq_len = 6; 279 params.seq_len = 6;
279 break; 280 break;
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 4433760db4c7..38e6101190d9 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -78,7 +78,6 @@ KEY_OPS(algorithm);
78static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, 78static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
79 size_t count, loff_t *ppos) 79 size_t count, loff_t *ppos)
80{ 80{
81 const u8 *tpn;
82 u64 pn; 81 u64 pn;
83 char buf[20]; 82 char buf[20];
84 int len; 83 int len;
@@ -101,10 +100,10 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
101 (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); 100 (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
102 break; 101 break;
103 case WLAN_CIPHER_SUITE_AES_CMAC: 102 case WLAN_CIPHER_SUITE_AES_CMAC:
104 tpn = key->u.aes_cmac.tx_pn; 103 pn = atomic64_read(&key->u.aes_cmac.tx_pn);
105 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", 104 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
106 tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], 105 (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
107 tpn[5]); 106 (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
108 break; 107 break;
109 default: 108 default:
110 return 0; 109 return 0;
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 05ce4c0203fc..fcb52eb2f92f 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -97,14 +97,11 @@ struct ieee80211_key {
97#endif 97#endif
98 } ccmp; 98 } ccmp;
99 struct { 99 struct {
100 u8 tx_pn[6]; 100 atomic64_t tx_pn;
101 u8 rx_pn[6]; 101 u8 rx_pn[6];
102 struct crypto_cipher *tfm; 102 struct crypto_cipher *tfm;
103 u32 replays; /* dot11RSNAStatsCMACReplays */ 103 u32 replays; /* dot11RSNAStatsCMACReplays */
104 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ 104 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
105 /* scratch buffers for virt_to_page() (crypto API) */
106 u8 tx_crypto_buf[2 * AES_BLOCK_LEN];
107 u8 rx_crypto_buf[2 * AES_BLOCK_LEN];
108 } aes_cmac; 105 } aes_cmac;
109 } u; 106 } u;
110 107
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 7691e4edc74a..3452d5e0a3cb 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -523,6 +523,16 @@ static void bip_aad(struct sk_buff *skb, u8 *aad)
523} 523}
524 524
525 525
526static inline void bip_ipn_set64(u8 *d, u64 pn)
527{
528 *d++ = pn;
529 *d++ = pn >> 8;
530 *d++ = pn >> 16;
531 *d++ = pn >> 24;
532 *d++ = pn >> 32;
533 *d = pn >> 40;
534}
535
526static inline void bip_ipn_swap(u8 *d, const u8 *s) 536static inline void bip_ipn_swap(u8 *d, const u8 *s)
527{ 537{
528 *d++ = s[5]; 538 *d++ = s[5];
@@ -541,8 +551,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
541 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 551 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
542 struct ieee80211_key *key = tx->key; 552 struct ieee80211_key *key = tx->key;
543 struct ieee80211_mmie *mmie; 553 struct ieee80211_mmie *mmie;
544 u8 *pn, aad[20]; 554 u8 aad[20];
545 int i; 555 u64 pn64;
546 556
547 if (info->control.hw_key) 557 if (info->control.hw_key)
548 return 0; 558 return 0;
@@ -556,22 +566,17 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
556 mmie->key_id = cpu_to_le16(key->conf.keyidx); 566 mmie->key_id = cpu_to_le16(key->conf.keyidx);
557 567
558 /* PN = PN + 1 */ 568 /* PN = PN + 1 */
559 pn = key->u.aes_cmac.tx_pn; 569 pn64 = atomic64_inc_return(&key->u.aes_cmac.tx_pn);
560 570
561 for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) { 571 bip_ipn_set64(mmie->sequence_number, pn64);
562 pn[i]++;
563 if (pn[i])
564 break;
565 }
566 bip_ipn_swap(mmie->sequence_number, pn);
567 572
568 bip_aad(skb, aad); 573 bip_aad(skb, aad);
569 574
570 /* 575 /*
571 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) 576 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
572 */ 577 */
573 ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf, 578 ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
574 aad, skb->data + 24, skb->len - 24, mmie->mic); 579 skb->data + 24, skb->len - 24, mmie->mic);
575 580
576 return TX_CONTINUE; 581 return TX_CONTINUE;
577} 582}
@@ -609,8 +614,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
609 if (!(status->flag & RX_FLAG_DECRYPTED)) { 614 if (!(status->flag & RX_FLAG_DECRYPTED)) {
610 /* hardware didn't decrypt/verify MIC */ 615 /* hardware didn't decrypt/verify MIC */
611 bip_aad(skb, aad); 616 bip_aad(skb, aad);
612 ieee80211_aes_cmac(key->u.aes_cmac.tfm, 617 ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
613 key->u.aes_cmac.rx_crypto_buf, aad,
614 skb->data + 24, skb->len - 24, mic); 618 skb->data + 24, skb->len - 24, mic);
615 if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { 619 if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
616 key->u.aes_cmac.icverrors++; 620 key->u.aes_cmac.icverrors++;