diff options
| -rw-r--r-- | net/mac80211/rx.c | 47 | ||||
| -rw-r--r-- | net/mac80211/wpa.c | 62 |
2 files changed, 48 insertions, 61 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b04a4378adcc..81241e18f3a4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2368,47 +2368,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
| 2368 | return RX_QUEUED; | 2368 | return RX_QUEUED; |
| 2369 | } | 2369 | } |
| 2370 | 2370 | ||
| 2371 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | ||
| 2372 | struct ieee80211_rx_data *rx) | ||
| 2373 | { | ||
| 2374 | int keyidx; | ||
| 2375 | unsigned int hdrlen; | ||
| 2376 | |||
| 2377 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
| 2378 | if (rx->skb->len >= hdrlen + 4) | ||
| 2379 | keyidx = rx->skb->data[hdrlen + 3] >> 6; | ||
| 2380 | else | ||
| 2381 | keyidx = -1; | ||
| 2382 | |||
| 2383 | if (!rx->sta) { | ||
| 2384 | /* | ||
| 2385 | * Some hardware seem to generate incorrect Michael MIC | ||
| 2386 | * reports; ignore them to avoid triggering countermeasures. | ||
| 2387 | */ | ||
| 2388 | return; | ||
| 2389 | } | ||
| 2390 | |||
| 2391 | if (!ieee80211_has_protected(hdr->frame_control)) | ||
| 2392 | return; | ||
| 2393 | |||
| 2394 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { | ||
| 2395 | /* | ||
| 2396 | * APs with pairwise keys should never receive Michael MIC | ||
| 2397 | * errors for non-zero keyidx because these are reserved for | ||
| 2398 | * group keys and only the AP is sending real multicast | ||
| 2399 | * frames in the BSS. | ||
| 2400 | */ | ||
| 2401 | return; | ||
| 2402 | } | ||
| 2403 | |||
| 2404 | if (!ieee80211_is_data(hdr->frame_control) && | ||
| 2405 | !ieee80211_is_auth(hdr->frame_control)) | ||
| 2406 | return; | ||
| 2407 | |||
| 2408 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, | ||
| 2409 | GFP_ATOMIC); | ||
| 2410 | } | ||
| 2411 | |||
| 2412 | /* TODO: use IEEE80211_RX_FRAGMENTED */ | 2371 | /* TODO: use IEEE80211_RX_FRAGMENTED */ |
| 2413 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | 2372 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, |
| 2414 | struct ieee80211_rate *rate) | 2373 | struct ieee80211_rate *rate) |
| @@ -2752,12 +2711,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
| 2752 | if (!prepares) | 2711 | if (!prepares) |
| 2753 | return false; | 2712 | return false; |
| 2754 | 2713 | ||
| 2755 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
| 2756 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) | ||
| 2757 | ieee80211_rx_michael_mic_report(hdr, rx); | ||
| 2758 | return false; | ||
| 2759 | } | ||
| 2760 | |||
| 2761 | if (!consume) { | 2714 | if (!consume) { |
| 2762 | skb = skb_copy(skb, GFP_ATOMIC); | 2715 | skb = skb_copy(skb, GFP_ATOMIC); |
| 2763 | if (!skb) { | 2716 | if (!skb) { |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f1765de2f4bf..9dc3b5f26e80 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
| @@ -87,42 +87,76 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
| 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 | 89 | ||
| 90 | /* No way to verify the MIC if the hardware stripped it */ | 90 | /* |
| 91 | if (status->flag & RX_FLAG_MMIC_STRIPPED) | 91 | * it makes no sense to check for MIC errors on anything other |
| 92 | * than data frames. | ||
| 93 | */ | ||
| 94 | if (!ieee80211_is_data_present(hdr->frame_control)) | ||
| 95 | return RX_CONTINUE; | ||
| 96 | |||
| 97 | /* | ||
| 98 | * No way to verify the MIC if the hardware stripped it or | ||
| 99 | * the IV with the key index. In this case we have solely rely | ||
| 100 | * on the driver to set RX_FLAG_MMIC_ERROR in the event of a | ||
| 101 | * MIC failure report. | ||
| 102 | */ | ||
| 103 | if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) { | ||
| 104 | if (status->flag & RX_FLAG_MMIC_ERROR) | ||
| 105 | goto mic_fail; | ||
| 106 | |||
| 107 | if (!(status->flag & RX_FLAG_IV_STRIPPED)) | ||
| 108 | goto update_iv; | ||
| 109 | |||
| 92 | return RX_CONTINUE; | 110 | return RX_CONTINUE; |
| 111 | } | ||
| 93 | 112 | ||
| 113 | /* | ||
| 114 | * Some hardware seems to generate Michael MIC failure reports; even | ||
| 115 | * though, the frame was not encrypted with TKIP and therefore has no | ||
| 116 | * MIC. Ignore the flag them to avoid triggering countermeasures. | ||
| 117 | */ | ||
| 94 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || | 118 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || |
| 95 | !ieee80211_has_protected(hdr->frame_control) || | 119 | !(status->flag & RX_FLAG_DECRYPTED)) |
| 96 | !ieee80211_is_data_present(hdr->frame_control)) | ||
| 97 | return RX_CONTINUE; | 120 | return RX_CONTINUE; |
| 98 | 121 | ||
| 122 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && rx->key->conf.keyidx) { | ||
| 123 | /* | ||
| 124 | * APs with pairwise keys should never receive Michael MIC | ||
| 125 | * errors for non-zero keyidx because these are reserved for | ||
| 126 | * group keys and only the AP is sending real multicast | ||
| 127 | * frames in the BSS. ( | ||
| 128 | */ | ||
| 129 | return RX_DROP_UNUSABLE; | ||
| 130 | } | ||
| 131 | |||
| 132 | if (status->flag & RX_FLAG_MMIC_ERROR) | ||
| 133 | goto mic_fail; | ||
| 134 | |||
| 99 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 135 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 100 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) | 136 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) |
| 101 | return RX_DROP_UNUSABLE; | 137 | return RX_DROP_UNUSABLE; |
| 102 | 138 | ||
| 103 | data = skb->data + hdrlen; | 139 | data = skb->data + hdrlen; |
| 104 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | 140 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; |
| 105 | |||
| 106 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; | 141 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; |
| 107 | michael_mic(key, hdr, data, data_len, mic); | 142 | michael_mic(key, hdr, data, data_len, mic); |
| 108 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) { | 143 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) |
| 109 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | 144 | goto mic_fail; |
| 110 | return RX_DROP_UNUSABLE; | ||
| 111 | |||
| 112 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | ||
| 113 | (void *) skb->data, NULL, | ||
| 114 | GFP_ATOMIC); | ||
| 115 | return RX_DROP_UNUSABLE; | ||
| 116 | } | ||
| 117 | 145 | ||
| 118 | /* remove Michael MIC from payload */ | 146 | /* remove Michael MIC from payload */ |
| 119 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | 147 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); |
| 120 | 148 | ||
| 149 | update_iv: | ||
| 121 | /* update IV in key information to be able to detect replays */ | 150 | /* update IV in key information to be able to detect replays */ |
| 122 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; | 151 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; |
| 123 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; | 152 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; |
| 124 | 153 | ||
| 125 | return RX_CONTINUE; | 154 | return RX_CONTINUE; |
| 155 | |||
| 156 | mic_fail: | ||
| 157 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | ||
| 158 | (void *) skb->data, NULL, GFP_ATOMIC); | ||
| 159 | return RX_DROP_UNUSABLE; | ||
| 126 | } | 160 | } |
| 127 | 161 | ||
| 128 | 162 | ||
