aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-09-26 09:19:45 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:53:16 -0400
commit50741ae05a4742cae99361f57d84b5f8d33822a4 (patch)
treee655586b7d22a9504aaad7aa79401e8ff1c71770
parentfb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6 (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>
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/tkip.c16
-rw-r--r--net/mac80211/tkip.h3
-rw-r--r--net/mac80211/wpa.c8
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,
238int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, 238int 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 {
31int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, 31int 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",