diff options
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 9dc3b5f26e80..8f6a302d2ac3 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -86,6 +86,11 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
86 | struct sk_buff *skb = rx->skb; | 86 | struct sk_buff *skb = rx->skb; |
87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
89 | int queue = rx->queue; | ||
90 | |||
91 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
92 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
93 | queue = 0; | ||
89 | 94 | ||
90 | /* | 95 | /* |
91 | * it makes no sense to check for MIC errors on anything other | 96 | * it makes no sense to check for MIC errors on anything other |
@@ -148,13 +153,19 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
148 | 153 | ||
149 | update_iv: | 154 | update_iv: |
150 | /* update IV in key information to be able to detect replays */ | 155 | /* update IV in key information to be able to detect replays */ |
151 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; | 156 | rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32; |
152 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; | 157 | rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16; |
153 | 158 | ||
154 | return RX_CONTINUE; | 159 | return RX_CONTINUE; |
155 | 160 | ||
156 | mic_fail: | 161 | mic_fail: |
157 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | 162 | /* |
163 | * In some cases the key can be unset - e.g. a multicast packet, in | ||
164 | * a driver that supports HW encryption. Send up the key idx only if | ||
165 | * the key is set. | ||
166 | */ | ||
167 | mac80211_ev_michael_mic_failure(rx->sdata, | ||
168 | rx->key ? rx->key->conf.keyidx : -1, | ||
158 | (void *) skb->data, NULL, GFP_ATOMIC); | 169 | (void *) skb->data, NULL, GFP_ATOMIC); |
159 | return RX_DROP_UNUSABLE; | 170 | return RX_DROP_UNUSABLE; |
160 | } | 171 | } |
@@ -235,6 +246,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
235 | struct ieee80211_key *key = rx->key; | 246 | struct ieee80211_key *key = rx->key; |
236 | struct sk_buff *skb = rx->skb; | 247 | struct sk_buff *skb = rx->skb; |
237 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 248 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
249 | int queue = rx->queue; | ||
250 | |||
251 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
252 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
253 | queue = 0; | ||
238 | 254 | ||
239 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 255 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
240 | 256 | ||
@@ -255,7 +271,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
255 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, | 271 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, |
256 | key, skb->data + hdrlen, | 272 | key, skb->data + hdrlen, |
257 | skb->len - hdrlen, rx->sta->sta.addr, | 273 | skb->len - hdrlen, rx->sta->sta.addr, |
258 | hdr->addr1, hwaccel, rx->queue, | 274 | hdr->addr1, hwaccel, queue, |
259 | &rx->tkip_iv32, | 275 | &rx->tkip_iv32, |
260 | &rx->tkip_iv16); | 276 | &rx->tkip_iv16); |
261 | if (res != TKIP_DECRYPT_OK) | 277 | if (res != TKIP_DECRYPT_OK) |