summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Wetzel <alexander@wetzel-home.de>2019-03-19 16:34:08 -0400
committerJohannes Berg <johannes.berg@intel.com>2019-04-26 07:02:11 -0400
commit96fc6efb9ad9d0cd8cbb4462f0eb2a07092649e6 (patch)
tree5c17bac2a0df2ddcc155aaaa158c32ab5f87f4bd
parent6cdd3979a2bdc16116c5b2eb09475abf54ba9e70 (diff)
mac80211: IEEE 802.11 Extended Key ID support
Add support for Extended Key ID as defined in IEEE 802.11-2016. - Implement the nl80211 API for Extended Key ID - Extend mac80211 API to allow drivers to support Extended Key ID - Enable Extended Key ID by default for drivers only supporting SW crypto (e.g. mac80211_hwsim) - Allow unicast Tx usage to be supressed (IEEE80211_KEY_FLAG_NO_AUTO_TX) - Select the decryption key based on the MPDU keyid - Enforce existing assumptions in the code that rekeys don't change the cipher Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> [remove module parameter] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h6
-rw-r--r--net/mac80211/cfg.c36
-rw-r--r--net/mac80211/debugfs.c1
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/key.c63
-rw-r--r--net/mac80211/key.h2
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/rx.c74
-rw-r--r--net/mac80211/sta_info.c9
-rw-r--r--net/mac80211/tx.c13
10 files changed, 151 insertions, 60 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ac2ed8ec662b..c10abca55fde 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1697,6 +1697,7 @@ struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif);
1697 * @IEEE80211_KEY_FLAG_PUT_MIC_SPACE: This flag should be set by the driver for 1697 * @IEEE80211_KEY_FLAG_PUT_MIC_SPACE: This flag should be set by the driver for
1698 * a TKIP key if it only requires MIC space. Do not set together with 1698 * a TKIP key if it only requires MIC space. Do not set together with
1699 * @IEEE80211_KEY_FLAG_GENERATE_MMIC on the same key. 1699 * @IEEE80211_KEY_FLAG_GENERATE_MMIC on the same key.
1700 * @IEEE80211_KEY_FLAG_NO_AUTO_TX: Key needs explicit Tx activation.
1700 */ 1701 */
1701enum ieee80211_key_flags { 1702enum ieee80211_key_flags {
1702 IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0), 1703 IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0),
@@ -1708,6 +1709,7 @@ enum ieee80211_key_flags {
1708 IEEE80211_KEY_FLAG_RX_MGMT = BIT(6), 1709 IEEE80211_KEY_FLAG_RX_MGMT = BIT(6),
1709 IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(7), 1710 IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(7),
1710 IEEE80211_KEY_FLAG_PUT_MIC_SPACE = BIT(8), 1711 IEEE80211_KEY_FLAG_PUT_MIC_SPACE = BIT(8),
1712 IEEE80211_KEY_FLAG_NO_AUTO_TX = BIT(9),
1711}; 1713};
1712 1714
1713/** 1715/**
@@ -2243,6 +2245,9 @@ struct ieee80211_txq {
2243 * @IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID: Hardware supports multi BSSID 2245 * @IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID: Hardware supports multi BSSID
2244 * only for HE APs. Applies if @IEEE80211_HW_SUPPORTS_MULTI_BSSID is set. 2246 * only for HE APs. Applies if @IEEE80211_HW_SUPPORTS_MULTI_BSSID is set.
2245 * 2247 *
2248 * @IEEE80211_HW_EXT_KEY_ID_NATIVE: Driver and hardware are supporting Extended
2249 * Key ID and can handle two unicast keys per station for Rx and Tx.
2250 *
2246 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays 2251 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
2247 */ 2252 */
2248enum ieee80211_hw_flags { 2253enum ieee80211_hw_flags {
@@ -2294,6 +2299,7 @@ enum ieee80211_hw_flags {
2294 IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN, 2299 IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
2295 IEEE80211_HW_SUPPORTS_MULTI_BSSID, 2300 IEEE80211_HW_SUPPORTS_MULTI_BSSID,
2296 IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID, 2301 IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
2302 IEEE80211_HW_EXT_KEY_ID_NATIVE,
2297 2303
2298 /* keep last, obviously */ 2304 /* keep last, obviously */
2299 NUM_IEEE80211_HW_FLAGS 2305 NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 09dd1c2860fc..14bbb7e8ad0e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -351,6 +351,36 @@ static int ieee80211_set_noack_map(struct wiphy *wiphy,
351 return 0; 351 return 0;
352} 352}
353 353
354static int ieee80211_set_tx(struct ieee80211_sub_if_data *sdata,
355 const u8 *mac_addr, u8 key_idx)
356{
357 struct ieee80211_local *local = sdata->local;
358 struct ieee80211_key *key;
359 struct sta_info *sta;
360 int ret = -EINVAL;
361
362 if (!wiphy_ext_feature_isset(local->hw.wiphy,
363 NL80211_EXT_FEATURE_EXT_KEY_ID))
364 return -EINVAL;
365
366 sta = sta_info_get_bss(sdata, mac_addr);
367
368 if (!sta)
369 return -EINVAL;
370
371 if (sta->ptk_idx == key_idx)
372 return 0;
373
374 mutex_lock(&local->key_mtx);
375 key = key_mtx_dereference(local, sta->ptk[key_idx]);
376
377 if (key && key->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)
378 ret = ieee80211_set_tx_key(key);
379
380 mutex_unlock(&local->key_mtx);
381 return ret;
382}
383
354static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 384static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
355 u8 key_idx, bool pairwise, const u8 *mac_addr, 385 u8 key_idx, bool pairwise, const u8 *mac_addr,
356 struct key_params *params) 386 struct key_params *params)
@@ -365,6 +395,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
365 if (!ieee80211_sdata_running(sdata)) 395 if (!ieee80211_sdata_running(sdata))
366 return -ENETDOWN; 396 return -ENETDOWN;
367 397
398 if (pairwise && params->mode == NL80211_KEY_SET_TX)
399 return ieee80211_set_tx(sdata, mac_addr, key_idx);
400
368 /* reject WEP and TKIP keys if WEP failed to initialize */ 401 /* reject WEP and TKIP keys if WEP failed to initialize */
369 switch (params->cipher) { 402 switch (params->cipher) {
370 case WLAN_CIPHER_SUITE_WEP40: 403 case WLAN_CIPHER_SUITE_WEP40:
@@ -396,6 +429,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
396 if (pairwise) 429 if (pairwise)
397 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; 430 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
398 431
432 if (params->mode == NL80211_KEY_NO_TX)
433 key->conf.flags |= IEEE80211_KEY_FLAG_NO_AUTO_TX;
434
399 mutex_lock(&local->sta_mtx); 435 mutex_lock(&local->sta_mtx);
400 436
401 if (mac_addr) { 437 if (mac_addr) {
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 2d43bc127043..aa6f23e1a457 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -221,6 +221,7 @@ static const char *hw_flag_names[] = {
221 FLAG(TX_STATUS_NO_AMPDU_LEN), 221 FLAG(TX_STATUS_NO_AMPDU_LEN),
222 FLAG(SUPPORTS_MULTI_BSSID), 222 FLAG(SUPPORTS_MULTI_BSSID),
223 FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID), 223 FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
224 FLAG(EXT_KEY_ID_NATIVE),
224#undef FLAG 225#undef FLAG
225}; 226};
226 227
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c5708f8a7401..32094e2ac0cb 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1269,7 +1269,7 @@ struct ieee80211_local {
1269 1269
1270 /* 1270 /*
1271 * Key mutex, protects sdata's key_list and sta_info's 1271 * Key mutex, protects sdata's key_list and sta_info's
1272 * key pointers (write access, they're RCU.) 1272 * key pointers and ptk_idx (write access, they're RCU.)
1273 */ 1273 */
1274 struct mutex key_mtx; 1274 struct mutex key_mtx;
1275 1275
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 41b8db37c7c1..42d52cded4c1 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -265,9 +265,24 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
265 sta ? sta->sta.addr : bcast_addr, ret); 265 sta ? sta->sta.addr : bcast_addr, ret);
266} 266}
267 267
268int ieee80211_set_tx_key(struct ieee80211_key *key)
269{
270 struct sta_info *sta = key->sta;
271 struct ieee80211_local *local = key->local;
272 struct ieee80211_key *old;
273
274 assert_key_lock(local);
275
276 old = key_mtx_dereference(local, sta->ptk[sta->ptk_idx]);
277 sta->ptk_idx = key->conf.keyidx;
278 ieee80211_check_fast_xmit(sta);
279
280 return 0;
281}
282
268static int ieee80211_hw_key_replace(struct ieee80211_key *old_key, 283static int ieee80211_hw_key_replace(struct ieee80211_key *old_key,
269 struct ieee80211_key *new_key, 284 struct ieee80211_key *new_key,
270 bool ptk0rekey) 285 bool pairwise)
271{ 286{
272 struct ieee80211_sub_if_data *sdata; 287 struct ieee80211_sub_if_data *sdata;
273 struct ieee80211_local *local; 288 struct ieee80211_local *local;
@@ -284,8 +299,9 @@ static int ieee80211_hw_key_replace(struct ieee80211_key *old_key,
284 assert_key_lock(old_key->local); 299 assert_key_lock(old_key->local);
285 sta = old_key->sta; 300 sta = old_key->sta;
286 301
287 /* PTK only using key ID 0 needs special handling on rekey */ 302 /* Unicast rekey without Extended Key ID needs special handling */
288 if (new_key && sta && ptk0rekey) { 303 if (new_key && sta && pairwise &&
304 rcu_access_pointer(sta->ptk[sta->ptk_idx]) == old_key) {
289 local = old_key->local; 305 local = old_key->local;
290 sdata = old_key->sdata; 306 sdata = old_key->sdata;
291 307
@@ -401,10 +417,6 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
401 417
402 if (old) { 418 if (old) {
403 idx = old->conf.keyidx; 419 idx = old->conf.keyidx;
404 /* TODO: proper implement and test "Extended Key ID for
405 * Individually Addressed Frames" from IEEE 802.11-2016.
406 * Till then always assume only key ID 0 is used for
407 * pairwise keys.*/
408 ret = ieee80211_hw_key_replace(old, new, pairwise); 420 ret = ieee80211_hw_key_replace(old, new, pairwise);
409 } else { 421 } else {
410 /* new must be provided in case old is not */ 422 /* new must be provided in case old is not */
@@ -421,15 +433,20 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
421 if (sta) { 433 if (sta) {
422 if (pairwise) { 434 if (pairwise) {
423 rcu_assign_pointer(sta->ptk[idx], new); 435 rcu_assign_pointer(sta->ptk[idx], new);
424 sta->ptk_idx = idx; 436 if (new &&
425 if (new) { 437 !(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)) {
438 sta->ptk_idx = idx;
426 clear_sta_flag(sta, WLAN_STA_BLOCK_BA); 439 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
427 ieee80211_check_fast_xmit(sta); 440 ieee80211_check_fast_xmit(sta);
428 } 441 }
429 } else { 442 } else {
430 rcu_assign_pointer(sta->gtk[idx], new); 443 rcu_assign_pointer(sta->gtk[idx], new);
431 } 444 }
432 if (new) 445 /* Only needed for transition from no key -> key.
446 * Still triggers unnecessary when using Extended Key ID
447 * and installing the second key ID the first time.
448 */
449 if (new && !old)
433 ieee80211_check_fast_rx(sta); 450 ieee80211_check_fast_rx(sta);
434 } else { 451 } else {
435 defunikey = old && 452 defunikey = old &&
@@ -745,16 +762,34 @@ int ieee80211_key_link(struct ieee80211_key *key,
745 * can cause warnings to appear. 762 * can cause warnings to appear.
746 */ 763 */
747 bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; 764 bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION;
748 int ret; 765 int ret = -EOPNOTSUPP;
749 766
750 mutex_lock(&sdata->local->key_mtx); 767 mutex_lock(&sdata->local->key_mtx);
751 768
752 if (sta && pairwise) 769 if (sta && pairwise) {
770 struct ieee80211_key *alt_key;
771
753 old_key = key_mtx_dereference(sdata->local, sta->ptk[idx]); 772 old_key = key_mtx_dereference(sdata->local, sta->ptk[idx]);
754 else if (sta) 773 alt_key = key_mtx_dereference(sdata->local, sta->ptk[idx ^ 1]);
774
775 /* The rekey code assumes that the old and new key are using
776 * the same cipher. Enforce the assumption for pairwise keys.
777 */
778 if (key &&
779 ((alt_key && alt_key->conf.cipher != key->conf.cipher) ||
780 (old_key && old_key->conf.cipher != key->conf.cipher)))
781 goto out;
782 } else if (sta) {
755 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]); 783 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
756 else 784 } else {
757 old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]); 785 old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
786 }
787
788 /* Non-pairwise keys must also not switch the cipher on rekey */
789 if (!pairwise) {
790 if (key && old_key && old_key->conf.cipher != key->conf.cipher)
791 goto out;
792 }
758 793
759 /* 794 /*
760 * Silently accept key re-installation without really installing the 795 * Silently accept key re-installation without really installing the
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index ebdb80b85dc3..f06fbd03d235 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -18,6 +18,7 @@
18 18
19#define NUM_DEFAULT_KEYS 4 19#define NUM_DEFAULT_KEYS 4
20#define NUM_DEFAULT_MGMT_KEYS 2 20#define NUM_DEFAULT_MGMT_KEYS 2
21#define INVALID_PTK_KEYIDX 2 /* Keyidx always pointing to a NULL key for PTK */
21 22
22struct ieee80211_local; 23struct ieee80211_local;
23struct ieee80211_sub_if_data; 24struct ieee80211_sub_if_data;
@@ -146,6 +147,7 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
146int ieee80211_key_link(struct ieee80211_key *key, 147int ieee80211_key_link(struct ieee80211_key *key,
147 struct ieee80211_sub_if_data *sdata, 148 struct ieee80211_sub_if_data *sdata,
148 struct sta_info *sta); 149 struct sta_info *sta);
150int ieee80211_set_tx_key(struct ieee80211_key *key);
149void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom); 151void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
150void ieee80211_key_free_unused(struct ieee80211_key *key); 152void ieee80211_key_free_unused(struct ieee80211_key *key);
151void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, 153void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 800e67615e2a..5d6b93050c0b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1051,6 +1051,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1051 } 1051 }
1052 } 1052 }
1053 1053
1054 if (!local->ops->set_key ||
1055 ieee80211_hw_check(&local->hw, EXT_KEY_ID_NATIVE))
1056 wiphy_ext_feature_set(local->hw.wiphy,
1057 NL80211_EXT_FEATURE_EXT_KEY_ID);
1058
1054 /* 1059 /*
1055 * Calculate scan IE length -- we need this to alloc 1060 * Calculate scan IE length -- we need this to alloc
1056 * memory and to subtract from the driver limit. It 1061 * memory and to subtract from the driver limit. It
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 7f8d93401ce0..4a03c18b39a8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1005,23 +1005,43 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
1005 return -1; 1005 return -1;
1006} 1006}
1007 1007
1008static int ieee80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs, 1008static int ieee80211_get_keyid(struct sk_buff *skb,
1009 struct sk_buff *skb) 1009 const struct ieee80211_cipher_scheme *cs)
1010{ 1010{
1011 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1011 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1012 __le16 fc; 1012 __le16 fc;
1013 int hdrlen; 1013 int hdrlen;
1014 int minlen;
1015 u8 key_idx_off;
1016 u8 key_idx_shift;
1014 u8 keyid; 1017 u8 keyid;
1015 1018
1016 fc = hdr->frame_control; 1019 fc = hdr->frame_control;
1017 hdrlen = ieee80211_hdrlen(fc); 1020 hdrlen = ieee80211_hdrlen(fc);
1018 1021
1019 if (skb->len < hdrlen + cs->hdr_len) 1022 if (cs) {
1023 minlen = hdrlen + cs->hdr_len;
1024 key_idx_off = hdrlen + cs->key_idx_off;
1025 key_idx_shift = cs->key_idx_shift;
1026 } else {
1027 /* WEP, TKIP, CCMP and GCMP */
1028 minlen = hdrlen + IEEE80211_WEP_IV_LEN;
1029 key_idx_off = hdrlen + 3;
1030 key_idx_shift = 6;
1031 }
1032
1033 if (unlikely(skb->len < minlen))
1020 return -EINVAL; 1034 return -EINVAL;
1021 1035
1022 skb_copy_bits(skb, hdrlen + cs->key_idx_off, &keyid, 1); 1036 skb_copy_bits(skb, key_idx_off, &keyid, 1);
1023 keyid &= cs->key_idx_mask; 1037
1024 keyid >>= cs->key_idx_shift; 1038 if (cs)
1039 keyid &= cs->key_idx_mask;
1040 keyid >>= key_idx_shift;
1041
1042 /* cs could use more than the usual two bits for the keyid */
1043 if (unlikely(keyid >= NUM_DEFAULT_KEYS))
1044 return -EINVAL;
1025 1045
1026 return keyid; 1046 return keyid;
1027} 1047}
@@ -1852,9 +1872,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1852 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 1872 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
1853 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1873 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1854 int keyidx; 1874 int keyidx;
1855 int hdrlen;
1856 ieee80211_rx_result result = RX_DROP_UNUSABLE; 1875 ieee80211_rx_result result = RX_DROP_UNUSABLE;
1857 struct ieee80211_key *sta_ptk = NULL; 1876 struct ieee80211_key *sta_ptk = NULL;
1877 struct ieee80211_key *ptk_idx = NULL;
1858 int mmie_keyidx = -1; 1878 int mmie_keyidx = -1;
1859 __le16 fc; 1879 __le16 fc;
1860 const struct ieee80211_cipher_scheme *cs = NULL; 1880 const struct ieee80211_cipher_scheme *cs = NULL;
@@ -1892,21 +1912,24 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1892 1912
1893 if (rx->sta) { 1913 if (rx->sta) {
1894 int keyid = rx->sta->ptk_idx; 1914 int keyid = rx->sta->ptk_idx;
1915 sta_ptk = rcu_dereference(rx->sta->ptk[keyid]);
1895 1916
1896 if (ieee80211_has_protected(fc) && rx->sta->cipher_scheme) { 1917 if (ieee80211_has_protected(fc)) {
1897 cs = rx->sta->cipher_scheme; 1918 cs = rx->sta->cipher_scheme;
1898 keyid = ieee80211_get_cs_keyid(cs, rx->skb); 1919 keyid = ieee80211_get_keyid(rx->skb, cs);
1920
1899 if (unlikely(keyid < 0)) 1921 if (unlikely(keyid < 0))
1900 return RX_DROP_UNUSABLE; 1922 return RX_DROP_UNUSABLE;
1923
1924 ptk_idx = rcu_dereference(rx->sta->ptk[keyid]);
1901 } 1925 }
1902 sta_ptk = rcu_dereference(rx->sta->ptk[keyid]);
1903 } 1926 }
1904 1927
1905 if (!ieee80211_has_protected(fc)) 1928 if (!ieee80211_has_protected(fc))
1906 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); 1929 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
1907 1930
1908 if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { 1931 if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
1909 rx->key = sta_ptk; 1932 rx->key = ptk_idx ? ptk_idx : sta_ptk;
1910 if ((status->flag & RX_FLAG_DECRYPTED) && 1933 if ((status->flag & RX_FLAG_DECRYPTED) &&
1911 (status->flag & RX_FLAG_IV_STRIPPED)) 1934 (status->flag & RX_FLAG_IV_STRIPPED))
1912 return RX_CONTINUE; 1935 return RX_CONTINUE;
@@ -1966,8 +1989,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1966 } 1989 }
1967 return RX_CONTINUE; 1990 return RX_CONTINUE;
1968 } else { 1991 } else {
1969 u8 keyid;
1970
1971 /* 1992 /*
1972 * The device doesn't give us the IV so we won't be 1993 * The device doesn't give us the IV so we won't be
1973 * able to look up the key. That's ok though, we 1994 * able to look up the key. That's ok though, we
@@ -1981,23 +2002,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1981 (status->flag & RX_FLAG_IV_STRIPPED)) 2002 (status->flag & RX_FLAG_IV_STRIPPED))
1982 return RX_CONTINUE; 2003 return RX_CONTINUE;
1983 2004
1984 hdrlen = ieee80211_hdrlen(fc); 2005 keyidx = ieee80211_get_keyid(rx->skb, cs);
1985
1986 if (cs) {
1987 keyidx = ieee80211_get_cs_keyid(cs, rx->skb);
1988 2006
1989 if (unlikely(keyidx < 0)) 2007 if (unlikely(keyidx < 0))
1990 return RX_DROP_UNUSABLE; 2008 return RX_DROP_UNUSABLE;
1991 } else {
1992 if (rx->skb->len < 8 + hdrlen)
1993 return RX_DROP_UNUSABLE; /* TODO: count this? */
1994 /*
1995 * no need to call ieee80211_wep_get_keyidx,
1996 * it verifies a bunch of things we've done already
1997 */
1998 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
1999 keyidx = keyid >> 6;
2000 }
2001 2009
2002 /* check per-station GTK first, if multicast packet */ 2010 /* check per-station GTK first, if multicast packet */
2003 if (is_multicast_ether_addr(hdr->addr1) && rx->sta) 2011 if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
@@ -4042,12 +4050,8 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
4042 case WLAN_CIPHER_SUITE_GCMP_256: 4050 case WLAN_CIPHER_SUITE_GCMP_256:
4043 break; 4051 break;
4044 default: 4052 default:
4045 /* we also don't want to deal with WEP or cipher scheme 4053 /* We also don't want to deal with
4046 * since those require looking up the key idx in the 4054 * WEP or cipher scheme.
4047 * frame, rather than assuming the PTK is used
4048 * (we need to revisit this once we implement the real
4049 * PTK index, which is now valid in the spec, but we
4050 * haven't implemented that part yet)
4051 */ 4055 */
4052 goto clear_rcu; 4056 goto clear_rcu;
4053 } 4057 }
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index a81e1279a76d..a4932ee3595c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -347,6 +347,15 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
347 sta->sta.max_rx_aggregation_subframes = 347 sta->sta.max_rx_aggregation_subframes =
348 local->hw.max_rx_aggregation_subframes; 348 local->hw.max_rx_aggregation_subframes;
349 349
350 /* Extended Key ID needs to install keys for keyid 0 and 1 Rx-only.
351 * The Tx path starts to use a key as soon as the key slot ptk_idx
352 * references to is not NULL. To not use the initial Rx-only key
353 * prematurely for Tx initialize ptk_idx to an impossible PTK keyid
354 * which always will refer to a NULL key.
355 */
356 BUILD_BUG_ON(ARRAY_SIZE(sta->ptk) <= INVALID_PTK_KEYIDX);
357 sta->ptk_idx = INVALID_PTK_KEYIDX;
358
350 sta->local = local; 359 sta->local = local;
351 sta->sdata = sdata; 360 sta->sdata = sdata;
352 sta->rx_stats.last_rx = jiffies; 361 sta->rx_stats.last_rx = jiffies;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index a3c6053cdffe..c49fd1e961d0 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3001,23 +3001,15 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
3001 switch (build.key->conf.cipher) { 3001 switch (build.key->conf.cipher) {
3002 case WLAN_CIPHER_SUITE_CCMP: 3002 case WLAN_CIPHER_SUITE_CCMP:
3003 case WLAN_CIPHER_SUITE_CCMP_256: 3003 case WLAN_CIPHER_SUITE_CCMP_256:
3004 /* add fixed key ID */ 3004 if (gen_iv)
3005 if (gen_iv) {
3006 (build.hdr + build.hdr_len)[3] =
3007 0x20 | (build.key->conf.keyidx << 6);
3008 build.pn_offs = build.hdr_len; 3005 build.pn_offs = build.hdr_len;
3009 }
3010 if (gen_iv || iv_spc) 3006 if (gen_iv || iv_spc)
3011 build.hdr_len += IEEE80211_CCMP_HDR_LEN; 3007 build.hdr_len += IEEE80211_CCMP_HDR_LEN;
3012 break; 3008 break;
3013 case WLAN_CIPHER_SUITE_GCMP: 3009 case WLAN_CIPHER_SUITE_GCMP:
3014 case WLAN_CIPHER_SUITE_GCMP_256: 3010 case WLAN_CIPHER_SUITE_GCMP_256:
3015 /* add fixed key ID */ 3011 if (gen_iv)
3016 if (gen_iv) {
3017 (build.hdr + build.hdr_len)[3] =
3018 0x20 | (build.key->conf.keyidx << 6);
3019 build.pn_offs = build.hdr_len; 3012 build.pn_offs = build.hdr_len;
3020 }
3021 if (gen_iv || iv_spc) 3013 if (gen_iv || iv_spc)
3022 build.hdr_len += IEEE80211_GCMP_HDR_LEN; 3014 build.hdr_len += IEEE80211_GCMP_HDR_LEN;
3023 break; 3015 break;
@@ -3388,6 +3380,7 @@ static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
3388 pn = atomic64_inc_return(&key->conf.tx_pn); 3380 pn = atomic64_inc_return(&key->conf.tx_pn);
3389 crypto_hdr[0] = pn; 3381 crypto_hdr[0] = pn;
3390 crypto_hdr[1] = pn >> 8; 3382 crypto_hdr[1] = pn >> 8;
3383 crypto_hdr[3] = 0x20 | (key->conf.keyidx << 6);
3391 crypto_hdr[4] = pn >> 16; 3384 crypto_hdr[4] = pn >> 16;
3392 crypto_hdr[5] = pn >> 24; 3385 crypto_hdr[5] = pn >> 24;
3393 crypto_hdr[6] = pn >> 32; 3386 crypto_hdr[6] = pn >> 32;