The mac80211 tkip code won't call update_tkip_key, if some rx packets get received without KEY_FLAG_UPLOADED_TO_HARDWARE. This can happen on first packet because the hardware key stuff is called asynchronously with todo workqueue. This patch workaround that by always calling once update_tkip_key if the packet wasn't decrypted by the hardware. Signed-off-by: Gregor Kowski Index: linux-2.6/net/mac80211/tkip.c =================================================================== --- linux-2.6.orig/net/mac80211/tkip.c 2009-06-10 20:12:32.000000000 +0000 +++ linux-2.6/net/mac80211/tkip.c 2009-06-12 20:31:35.000000000 +0000 @@ -19,6 +19,12 @@ #define PHASE1_LOOP_COUNT 8 +enum { + INITIALIZED_NONE, + INITIALIZED_PHASE1, + INITIALIZED_UPDATE_KEY, +}; + /* * 2-byte by 2-byte subset of the full AES S-box table; second part of this * table is identical to first part but byte-swapped @@ -99,7 +105,7 @@ p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; } - ctx->initialized = 1; + ctx->initialized = INITIALIZED_PHASE1; } static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, @@ -182,7 +188,7 @@ /* Update the p1k only when the iv16 in the packet wraps around, this * might occur after the wrap around of iv16 in the key in case of * fragmented packets. */ - if (iv16 == 0 || !ctx->initialized) + if (iv16 == 0 || ctx->initialized == INITIALIZED_NONE) tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); if (type == IEEE80211_TKIP_P1_KEY) { @@ -208,7 +214,7 @@ const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; /* Calculate per-packet key */ - if (ctx->iv16 == 0 || !ctx->initialized) + if (ctx->iv16 == 0 || ctx->initialized == INITIALIZED_NONE) tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); @@ -258,7 +264,7 @@ if ((keyid >> 6) != key->conf.keyidx) return TKIP_DECRYPT_INVALID_KEYIDX; - if (key->u.tkip.rx[queue].initialized && + if (key->u.tkip.rx[queue].initialized != INITIALIZED_NONE && (iv32 < key->u.tkip.rx[queue].iv32 || (iv32 == key->u.tkip.rx[queue].iv32 && iv16 <= key->u.tkip.rx[queue].iv16))) { @@ -274,11 +280,11 @@ if (only_iv) { res = TKIP_DECRYPT_OK; - key->u.tkip.rx[queue].initialized = 1; + key->u.tkip.rx[queue].initialized = INITIALIZED_UPDATE_KEY; goto done; } - if (!key->u.tkip.rx[queue].initialized || + if (key->u.tkip.rx[queue].initialized == INITIALIZED_NONE || key->u.tkip.rx[queue].iv32 != iv32) { /* IV16 wrapped around - perform TKIP phase 1 */ tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); @@ -298,19 +304,21 @@ printk("\n"); } #endif - if (key->local->ops->update_tkip_key && - key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { - u8 bcast[ETH_ALEN] = - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 *sta_addr = key->sta->sta.addr; - - if (is_multicast_ether_addr(ra)) - sta_addr = bcast; - - key->local->ops->update_tkip_key( - local_to_hw(key->local), &key->conf, - sta_addr, iv32, key->u.tkip.rx[queue].p1k); - } + } + if (key->local->ops->update_tkip_key && + key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && + key->u.tkip.rx[queue].initialized != INITIALIZED_UPDATE_KEY) { + u8 bcast[ETH_ALEN] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 *sta_addr = key->sta->sta.addr; + + if (is_multicast_ether_addr(ra)) + sta_addr = bcast; + + key->local->ops->update_tkip_key( + local_to_hw(key->local), &key->conf, + sta_addr, iv32, key->u.tkip.rx[queue].p1k); + key->u.tkip.rx[queue].initialized = INITIALIZED_UPDATE_KEY; } tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key);