diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-09-26 09:19:45 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:53:16 -0400 |
commit | 50741ae05a4742cae99361f57d84b5f8d33822a4 (patch) | |
tree | e655586b7d22a9504aaad7aa79401e8ff1c71770 /net/mac80211 | |
parent | fb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6 (diff) |
[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>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 16 | ||||
-rw-r--r-- | net/mac80211/tkip.h | 3 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 8 |
4 files changed, 21 insertions, 8 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 636de70cd85d..32d19bbf522c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -153,6 +153,8 @@ struct ieee80211_txrx_data { | |||
153 | int sent_ps_buffered; | 153 | int sent_ps_buffered; |
154 | int queue; | 154 | int queue; |
155 | int load; | 155 | int load; |
156 | u32 tkip_iv32; | ||
157 | u16 tkip_iv16; | ||
156 | } rx; | 158 | } rx; |
157 | } u; | 159 | } u; |
158 | }; | 160 | }; |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 5b11f14abfba..3abe194e4d55 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -238,7 +238,8 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
238 | int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | 238 | int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, |
239 | struct ieee80211_key *key, | 239 | struct ieee80211_key *key, |
240 | u8 *payload, size_t payload_len, u8 *ta, | 240 | u8 *payload, size_t payload_len, u8 *ta, |
241 | int only_iv, int queue) | 241 | int only_iv, int queue, |
242 | u32 *out_iv32, u16 *out_iv16) | ||
242 | { | 243 | { |
243 | u32 iv32; | 244 | u32 iv32; |
244 | u32 iv16; | 245 | u32 iv16; |
@@ -332,11 +333,14 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
332 | res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); | 333 | res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); |
333 | done: | 334 | done: |
334 | if (res == TKIP_DECRYPT_OK) { | 335 | if (res == TKIP_DECRYPT_OK) { |
335 | /* FIX: these should be updated only after Michael MIC has been | 336 | /* |
336 | * verified */ | 337 | * Record previously received IV, will be copied into the |
337 | /* Record previously received IV */ | 338 | * key information after MIC verification. It is possible |
338 | key->u.tkip.iv32_rx[queue] = iv32; | 339 | * that we don't catch replays of fragments but that's ok |
339 | key->u.tkip.iv16_rx[queue] = iv16; | 340 | * because the Michael MIC verication will then fail. |
341 | */ | ||
342 | *out_iv32 = iv32; | ||
343 | *out_iv16 = iv16; | ||
340 | } | 344 | } |
341 | 345 | ||
342 | return res; | 346 | return res; |
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index a0d181a18049..73d8ef2a93b0 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h | |||
@@ -31,6 +31,7 @@ enum { | |||
31 | int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | 31 | int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, |
32 | struct ieee80211_key *key, | 32 | struct ieee80211_key *key, |
33 | u8 *payload, size_t payload_len, u8 *ta, | 33 | u8 *payload, size_t payload_len, u8 *ta, |
34 | int only_iv, int queue); | 34 | int only_iv, int queue, |
35 | u32 *out_iv32, u16 *out_iv16); | ||
35 | 36 | ||
36 | #endif /* TKIP_H */ | 37 | #endif /* TKIP_H */ |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index a07fd7484cdf..6695efba57ec 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -175,6 +175,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
175 | /* remove Michael MIC from payload */ | 175 | /* remove Michael MIC from payload */ |
176 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | 176 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); |
177 | 177 | ||
178 | /* update IV in key information to be able to detect replays */ | ||
179 | rx->key->u.tkip.iv32_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv32; | ||
180 | rx->key->u.tkip.iv16_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv16; | ||
181 | |||
178 | return TXRX_CONTINUE; | 182 | return TXRX_CONTINUE; |
179 | } | 183 | } |
180 | 184 | ||
@@ -315,7 +319,9 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) | |||
315 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, | 319 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, |
316 | key, skb->data + hdrlen, | 320 | key, skb->data + hdrlen, |
317 | skb->len - hdrlen, rx->sta->addr, | 321 | skb->len - hdrlen, rx->sta->addr, |
318 | hwaccel, rx->u.rx.queue); | 322 | hwaccel, rx->u.rx.queue, |
323 | &rx->u.rx.tkip_iv32, | ||
324 | &rx->u.rx.tkip_iv16); | ||
319 | if (res != TKIP_DECRYPT_OK || wpa_test) { | 325 | if (res != TKIP_DECRYPT_OK || wpa_test) { |
320 | printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from " | 326 | printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from " |
321 | "%s (res=%d)\n", | 327 | "%s (res=%d)\n", |