aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/key.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r--net/mac80211/key.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 1208a7878bfd..739bee13e813 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -369,6 +369,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
369 get_unaligned_le16(seq); 369 get_unaligned_le16(seq);
370 } 370 }
371 } 371 }
372 spin_lock_init(&key->u.tkip.txlock);
372 break; 373 break;
373 case WLAN_CIPHER_SUITE_CCMP: 374 case WLAN_CIPHER_SUITE_CCMP:
374 key->conf.iv_len = CCMP_HDR_LEN; 375 key->conf.iv_len = CCMP_HDR_LEN;
@@ -625,3 +626,77 @@ void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid,
625 cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp); 626 cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp);
626} 627}
627EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify); 628EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify);
629
630void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf,
631 struct ieee80211_key_seq *seq)
632{
633 struct ieee80211_key *key;
634 u64 pn64;
635
636 if (WARN_ON(!(keyconf->flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
637 return;
638
639 key = container_of(keyconf, struct ieee80211_key, conf);
640
641 switch (key->conf.cipher) {
642 case WLAN_CIPHER_SUITE_TKIP:
643 seq->tkip.iv32 = key->u.tkip.tx.iv32;
644 seq->tkip.iv16 = key->u.tkip.tx.iv16;
645 break;
646 case WLAN_CIPHER_SUITE_CCMP:
647 pn64 = atomic64_read(&key->u.ccmp.tx_pn);
648 seq->ccmp.pn[5] = pn64;
649 seq->ccmp.pn[4] = pn64 >> 8;
650 seq->ccmp.pn[3] = pn64 >> 16;
651 seq->ccmp.pn[2] = pn64 >> 24;
652 seq->ccmp.pn[1] = pn64 >> 32;
653 seq->ccmp.pn[0] = pn64 >> 40;
654 break;
655 case WLAN_CIPHER_SUITE_AES_CMAC:
656 pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
657 seq->ccmp.pn[5] = pn64;
658 seq->ccmp.pn[4] = pn64 >> 8;
659 seq->ccmp.pn[3] = pn64 >> 16;
660 seq->ccmp.pn[2] = pn64 >> 24;
661 seq->ccmp.pn[1] = pn64 >> 32;
662 seq->ccmp.pn[0] = pn64 >> 40;
663 break;
664 default:
665 WARN_ON(1);
666 }
667}
668EXPORT_SYMBOL(ieee80211_get_key_tx_seq);
669
670void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
671 int tid, struct ieee80211_key_seq *seq)
672{
673 struct ieee80211_key *key;
674 const u8 *pn;
675
676 key = container_of(keyconf, struct ieee80211_key, conf);
677
678 switch (key->conf.cipher) {
679 case WLAN_CIPHER_SUITE_TKIP:
680 if (WARN_ON(tid < 0 || tid >= NUM_RX_DATA_QUEUES))
681 return;
682 seq->tkip.iv32 = key->u.tkip.rx[tid].iv32;
683 seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
684 break;
685 case WLAN_CIPHER_SUITE_CCMP:
686 if (WARN_ON(tid < -1 || tid >= NUM_RX_DATA_QUEUES))
687 return;
688 if (tid < 0)
689 pn = key->u.ccmp.rx_pn[NUM_RX_DATA_QUEUES];
690 else
691 pn = key->u.ccmp.rx_pn[tid];
692 memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN);
693 break;
694 case WLAN_CIPHER_SUITE_AES_CMAC:
695 if (WARN_ON(tid != 0))
696 return;
697 pn = key->u.aes_cmac.rx_pn;
698 memcpy(seq->aes_cmac.pn, pn, CMAC_PN_LEN);
699 break;
700 }
701}
702EXPORT_SYMBOL(ieee80211_get_key_rx_seq);