[PATCH] mac80211: fix TKIP IV update
The TKIP IV should be updated only after MMIC verification, this patch changes it to be at that spot. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
fb1c1cd6c5
Коммит
50741ae05a
|
@ -153,6 +153,8 @@ struct ieee80211_txrx_data {
|
||||||
int sent_ps_buffered;
|
int sent_ps_buffered;
|
||||||
int queue;
|
int queue;
|
||||||
int load;
|
int load;
|
||||||
|
u32 tkip_iv32;
|
||||||
|
u16 tkip_iv16;
|
||||||
} rx;
|
} rx;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
|
@ -238,7 +238,8 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
|
||||||
int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
|
int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
|
||||||
struct ieee80211_key *key,
|
struct ieee80211_key *key,
|
||||||
u8 *payload, size_t payload_len, u8 *ta,
|
u8 *payload, size_t payload_len, u8 *ta,
|
||||||
int only_iv, int queue)
|
int only_iv, int queue,
|
||||||
|
u32 *out_iv32, u16 *out_iv16)
|
||||||
{
|
{
|
||||||
u32 iv32;
|
u32 iv32;
|
||||||
u32 iv16;
|
u32 iv16;
|
||||||
|
@ -332,11 +333,14 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
|
||||||
res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12);
|
res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12);
|
||||||
done:
|
done:
|
||||||
if (res == TKIP_DECRYPT_OK) {
|
if (res == TKIP_DECRYPT_OK) {
|
||||||
/* FIX: these should be updated only after Michael MIC has been
|
/*
|
||||||
* verified */
|
* Record previously received IV, will be copied into the
|
||||||
/* Record previously received IV */
|
* key information after MIC verification. It is possible
|
||||||
key->u.tkip.iv32_rx[queue] = iv32;
|
* that we don't catch replays of fragments but that's ok
|
||||||
key->u.tkip.iv16_rx[queue] = iv16;
|
* because the Michael MIC verication will then fail.
|
||||||
|
*/
|
||||||
|
*out_iv32 = iv32;
|
||||||
|
*out_iv16 = iv16;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum {
|
||||||
int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
|
int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
|
||||||
struct ieee80211_key *key,
|
struct ieee80211_key *key,
|
||||||
u8 *payload, size_t payload_len, u8 *ta,
|
u8 *payload, size_t payload_len, u8 *ta,
|
||||||
int only_iv, int queue);
|
int only_iv, int queue,
|
||||||
|
u32 *out_iv32, u16 *out_iv16);
|
||||||
|
|
||||||
#endif /* TKIP_H */
|
#endif /* TKIP_H */
|
||||||
|
|
|
@ -175,6 +175,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
|
||||||
/* remove Michael MIC from payload */
|
/* remove Michael MIC from payload */
|
||||||
skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
|
skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
|
||||||
|
|
||||||
|
/* update IV in key information to be able to detect replays */
|
||||||
|
rx->key->u.tkip.iv32_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv32;
|
||||||
|
rx->key->u.tkip.iv16_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv16;
|
||||||
|
|
||||||
return TXRX_CONTINUE;
|
return TXRX_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +319,9 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
|
||||||
res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
|
res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
|
||||||
key, skb->data + hdrlen,
|
key, skb->data + hdrlen,
|
||||||
skb->len - hdrlen, rx->sta->addr,
|
skb->len - hdrlen, rx->sta->addr,
|
||||||
hwaccel, rx->u.rx.queue);
|
hwaccel, rx->u.rx.queue,
|
||||||
|
&rx->u.rx.tkip_iv32,
|
||||||
|
&rx->u.rx.tkip_iv16);
|
||||||
if (res != TKIP_DECRYPT_OK || wpa_test) {
|
if (res != TKIP_DECRYPT_OK || wpa_test) {
|
||||||
printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from "
|
printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from "
|
||||||
"%s (res=%d)\n",
|
"%s (res=%d)\n",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче