diff options
-rw-r--r-- | net/mac80211/aes_cmac.c | 8 | ||||
-rw-r--r-- | net/mac80211/aes_cmac.h | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 13 | ||||
-rw-r--r-- | net/mac80211/debugfs_key.c | 7 | ||||
-rw-r--r-- | net/mac80211/key.h | 5 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 30 |
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 | ||
38 | static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch, | 38 | static 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 | ||
98 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, | 98 | void 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 | ||
14 | struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); | 14 | struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); |
15 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, | 15 | void 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); |
17 | void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); | 17 | void 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); | |||
78 | static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | 78 | static 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 | ||
526 | static 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 | |||
526 | static inline void bip_ipn_swap(u8 *d, const u8 *s) | 536 | static 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++; |