diff options
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 30 |
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 | ||
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++; |