diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/key.h | 8 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 38 |
2 files changed, 27 insertions, 19 deletions
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index a49f93b79e92..bdc2968c2bbe 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -59,11 +59,17 @@ enum ieee80211_internal_key_flags { | |||
59 | KEY_FLAG_TODO_DEFMGMTKEY = BIT(6), | 59 | KEY_FLAG_TODO_DEFMGMTKEY = BIT(6), |
60 | }; | 60 | }; |
61 | 61 | ||
62 | enum ieee80211_internal_tkip_state { | ||
63 | TKIP_STATE_NOT_INIT, | ||
64 | TKIP_STATE_PHASE1_DONE, | ||
65 | TKIP_STATE_PHASE1_HW_UPLOADED, | ||
66 | }; | ||
67 | |||
62 | struct tkip_ctx { | 68 | struct tkip_ctx { |
63 | u32 iv32; | 69 | u32 iv32; |
64 | u16 iv16; | 70 | u16 iv16; |
65 | u16 p1k[5]; | 71 | u16 p1k[5]; |
66 | int initialized; | 72 | enum ieee80211_internal_tkip_state state; |
67 | }; | 73 | }; |
68 | 74 | ||
69 | struct ieee80211_key { | 75 | struct ieee80211_key { |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 4921d724b6c7..b73454a507f9 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -100,7 +100,7 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, | |||
100 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); | 100 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); |
101 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; | 101 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
102 | } | 102 | } |
103 | ctx->initialized = 1; | 103 | ctx->state = TKIP_STATE_PHASE1_DONE; |
104 | } | 104 | } |
105 | 105 | ||
106 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, | 106 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, |
@@ -183,7 +183,7 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
183 | /* Update the p1k only when the iv16 in the packet wraps around, this | 183 | /* Update the p1k only when the iv16 in the packet wraps around, this |
184 | * might occur after the wrap around of iv16 in the key in case of | 184 | * might occur after the wrap around of iv16 in the key in case of |
185 | * fragmented packets. */ | 185 | * fragmented packets. */ |
186 | if (iv16 == 0 || !ctx->initialized) | 186 | if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) |
187 | tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); | 187 | tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); |
188 | 188 | ||
189 | if (type == IEEE80211_TKIP_P1_KEY) { | 189 | if (type == IEEE80211_TKIP_P1_KEY) { |
@@ -209,7 +209,7 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
209 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | 209 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; |
210 | 210 | ||
211 | /* Calculate per-packet key */ | 211 | /* Calculate per-packet key */ |
212 | if (ctx->iv16 == 0 || !ctx->initialized) | 212 | if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) |
213 | tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); | 213 | tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); |
214 | 214 | ||
215 | tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); | 215 | tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); |
@@ -259,7 +259,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
259 | if ((keyid >> 6) != key->conf.keyidx) | 259 | if ((keyid >> 6) != key->conf.keyidx) |
260 | return TKIP_DECRYPT_INVALID_KEYIDX; | 260 | return TKIP_DECRYPT_INVALID_KEYIDX; |
261 | 261 | ||
262 | if (key->u.tkip.rx[queue].initialized && | 262 | if (key->u.tkip.rx[queue].state != TKIP_STATE_NOT_INIT && |
263 | (iv32 < key->u.tkip.rx[queue].iv32 || | 263 | (iv32 < key->u.tkip.rx[queue].iv32 || |
264 | (iv32 == key->u.tkip.rx[queue].iv32 && | 264 | (iv32 == key->u.tkip.rx[queue].iv32 && |
265 | iv16 <= key->u.tkip.rx[queue].iv16))) { | 265 | iv16 <= key->u.tkip.rx[queue].iv16))) { |
@@ -275,11 +275,11 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
275 | 275 | ||
276 | if (only_iv) { | 276 | if (only_iv) { |
277 | res = TKIP_DECRYPT_OK; | 277 | res = TKIP_DECRYPT_OK; |
278 | key->u.tkip.rx[queue].initialized = 1; | 278 | key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED; |
279 | goto done; | 279 | goto done; |
280 | } | 280 | } |
281 | 281 | ||
282 | if (!key->u.tkip.rx[queue].initialized || | 282 | if (key->u.tkip.rx[queue].state == TKIP_STATE_NOT_INIT || |
283 | key->u.tkip.rx[queue].iv32 != iv32) { | 283 | key->u.tkip.rx[queue].iv32 != iv32) { |
284 | /* IV16 wrapped around - perform TKIP phase 1 */ | 284 | /* IV16 wrapped around - perform TKIP phase 1 */ |
285 | tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); | 285 | tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); |
@@ -299,18 +299,20 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
299 | printk("\n"); | 299 | printk("\n"); |
300 | } | 300 | } |
301 | #endif | 301 | #endif |
302 | if (key->local->ops->update_tkip_key && | 302 | } |
303 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 303 | if (key->local->ops->update_tkip_key && |
304 | static const u8 bcast[ETH_ALEN] = | 304 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
305 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 305 | key->u.tkip.rx[queue].state != TKIP_STATE_PHASE1_HW_UPLOADED) { |
306 | const u8 *sta_addr = key->sta->sta.addr; | 306 | static const u8 bcast[ETH_ALEN] = |
307 | 307 | {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | |
308 | if (is_multicast_ether_addr(ra)) | 308 | const u8 *sta_addr = key->sta->sta.addr; |
309 | sta_addr = bcast; | 309 | |
310 | 310 | if (is_multicast_ether_addr(ra)) | |
311 | drv_update_tkip_key(key->local, &key->conf, sta_addr, | 311 | sta_addr = bcast; |
312 | iv32, key->u.tkip.rx[queue].p1k); | 312 | |
313 | } | 313 | drv_update_tkip_key(key->local, &key->conf, sta_addr, |
314 | iv32, key->u.tkip.rx[queue].p1k); | ||
315 | key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED; | ||
314 | } | 316 | } |
315 | 317 | ||
316 | tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); | 318 | tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); |