diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0b0e83ebe3d5..b67221def584 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -819,6 +819,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
819 | if (unlikely((ieee80211_is_data(hdr->frame_control) || | 819 | if (unlikely((ieee80211_is_data(hdr->frame_control) || |
820 | ieee80211_is_pspoll(hdr->frame_control)) && | 820 | ieee80211_is_pspoll(hdr->frame_control)) && |
821 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 821 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
822 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && | ||
822 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 823 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
823 | if ((!ieee80211_has_fromds(hdr->frame_control) && | 824 | if ((!ieee80211_has_fromds(hdr->frame_control) && |
824 | !ieee80211_has_tods(hdr->frame_control) && | 825 | !ieee80211_has_tods(hdr->frame_control) && |
@@ -845,7 +846,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
845 | int keyidx; | 846 | int keyidx; |
846 | int hdrlen; | 847 | int hdrlen; |
847 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 848 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
848 | struct ieee80211_key *stakey = NULL; | 849 | struct ieee80211_key *sta_ptk = NULL; |
849 | int mmie_keyidx = -1; | 850 | int mmie_keyidx = -1; |
850 | __le16 fc; | 851 | __le16 fc; |
851 | 852 | ||
@@ -887,15 +888,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
887 | rx->key = NULL; | 888 | rx->key = NULL; |
888 | 889 | ||
889 | if (rx->sta) | 890 | if (rx->sta) |
890 | stakey = rcu_dereference(rx->sta->key); | 891 | sta_ptk = rcu_dereference(rx->sta->ptk); |
891 | 892 | ||
892 | fc = hdr->frame_control; | 893 | fc = hdr->frame_control; |
893 | 894 | ||
894 | if (!ieee80211_has_protected(fc)) | 895 | if (!ieee80211_has_protected(fc)) |
895 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | 896 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); |
896 | 897 | ||
897 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { | 898 | if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { |
898 | rx->key = stakey; | 899 | rx->key = sta_ptk; |
899 | if ((status->flag & RX_FLAG_DECRYPTED) && | 900 | if ((status->flag & RX_FLAG_DECRYPTED) && |
900 | (status->flag & RX_FLAG_IV_STRIPPED)) | 901 | (status->flag & RX_FLAG_IV_STRIPPED)) |
901 | return RX_CONTINUE; | 902 | return RX_CONTINUE; |
@@ -911,7 +912,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
911 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | 912 | if (mmie_keyidx < NUM_DEFAULT_KEYS || |
912 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | 913 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) |
913 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | 914 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ |
914 | 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]); | ||
915 | } else if (!ieee80211_has_protected(fc)) { | 919 | } else if (!ieee80211_has_protected(fc)) { |
916 | /* | 920 | /* |
917 | * The frame was not protected, so skip decryption. However, we | 921 | * The frame was not protected, so skip decryption. However, we |
@@ -954,17 +958,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
954 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); | 958 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); |
955 | keyidx = keyid >> 6; | 959 | keyidx = keyid >> 6; |
956 | 960 | ||
957 | 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]); | ||
958 | 964 | ||
959 | /* | 965 | /* if not found, try default key */ |
960 | * RSNA-protected unicast frames should always be sent with | 966 | if (!rx->key) { |
961 | * pairwise or station-to-station keys, but for WEP we allow | 967 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); |
962 | * using a key index as well. | 968 | |
963 | */ | 969 | /* |
964 | if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && | 970 | * RSNA-protected unicast frames should always be |
965 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && | 971 | * sent with pairwise or station-to-station keys, |
966 | !is_multicast_ether_addr(hdr->addr1)) | 972 | * but for WEP we allow using a key index as well. |
967 | 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 | } | ||
968 | } | 980 | } |
969 | 981 | ||
970 | if (rx->key) { | 982 | if (rx->key) { |