aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b3e161ffa4b3..b67221def584 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -846,7 +846,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
846 int keyidx; 846 int keyidx;
847 int hdrlen; 847 int hdrlen;
848 ieee80211_rx_result result = RX_DROP_UNUSABLE; 848 ieee80211_rx_result result = RX_DROP_UNUSABLE;
849 struct ieee80211_key *stakey = NULL; 849 struct ieee80211_key *sta_ptk = NULL;
850 int mmie_keyidx = -1; 850 int mmie_keyidx = -1;
851 __le16 fc; 851 __le16 fc;
852 852
@@ -888,15 +888,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
888 rx->key = NULL; 888 rx->key = NULL;
889 889
890 if (rx->sta) 890 if (rx->sta)
891 stakey = rcu_dereference(rx->sta->key); 891 sta_ptk = rcu_dereference(rx->sta->ptk);
892 892
893 fc = hdr->frame_control; 893 fc = hdr->frame_control;
894 894
895 if (!ieee80211_has_protected(fc)) 895 if (!ieee80211_has_protected(fc))
896 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); 896 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
897 897
898 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 898 if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
899 rx->key = stakey; 899 rx->key = sta_ptk;
900 if ((status->flag & RX_FLAG_DECRYPTED) && 900 if ((status->flag & RX_FLAG_DECRYPTED) &&
901 (status->flag & RX_FLAG_IV_STRIPPED)) 901 (status->flag & RX_FLAG_IV_STRIPPED))
902 return RX_CONTINUE; 902 return RX_CONTINUE;
@@ -912,7 +912,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
912 if (mmie_keyidx < NUM_DEFAULT_KEYS || 912 if (mmie_keyidx < NUM_DEFAULT_KEYS ||
913 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 913 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
914 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 914 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
915 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); 915 if (rx->sta)
916 rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]);
917 if (!rx->key)
918 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
916 } else if (!ieee80211_has_protected(fc)) { 919 } else if (!ieee80211_has_protected(fc)) {
917 /* 920 /*
918 * The frame was not protected, so skip decryption. However, we 921 * The frame was not protected, so skip decryption. However, we
@@ -955,17 +958,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
955 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); 958 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
956 keyidx = keyid >> 6; 959 keyidx = keyid >> 6;
957 960
958 rx->key = rcu_dereference(rx->sdata->keys[keyidx]); 961 /* check per-station GTK first, if multicast packet */
962 if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
963 rx->key = rcu_dereference(rx->sta->gtk[keyidx]);
959 964
960 /* 965 /* if not found, try default key */
961 * RSNA-protected unicast frames should always be sent with 966 if (!rx->key) {
962 * pairwise or station-to-station keys, but for WEP we allow 967 rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
963 * using a key index as well. 968
964 */ 969 /*
965 if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && 970 * RSNA-protected unicast frames should always be
966 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && 971 * sent with pairwise or station-to-station keys,
967 !is_multicast_ether_addr(hdr->addr1)) 972 * but for WEP we allow using a key index as well.
968 rx->key = NULL; 973 */
974 if (rx->key &&
975 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
976 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
977 !is_multicast_ether_addr(hdr->addr1))
978 rx->key = NULL;
979 }
969 } 980 }
970 981
971 if (rx->key) { 982 if (rx->key) {