[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:
Johannes Berg 2007-09-26 15:19:45 +02:00 коммит произвёл David S. Miller
Родитель fb1c1cd6c5
Коммит 50741ae05a
4 изменённых файлов: 21 добавлений и 8 удалений

Просмотреть файл

@ -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",