aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wpa.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-07-06 16:00:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-08 11:11:20 -0400
commit75396ae6d433b49482e377e6f8dbf1f42ad53f3a (patch)
tree07fb506f08f3cca7d67d2fd365cc059240b6957b /net/mac80211/wpa.c
parentaba83a0b301c32dbb91c017f33307611e1a1d384 (diff)
mac80211: fix CMAC races
Just like TKIP and CCMP, CMAC has the PN race. It might not actually be possible to hit it now since there aren't multiple ACs for management frames, but fix it anyway. Also move scratch buffers onto the stack. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r--net/mac80211/wpa.c30
1 files changed, 17 insertions, 13 deletions
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++;