Software TKIP group rekeying and phase1 issue

Bernhard Schmidt bschmidt at techwires.net
Sat Feb 6 22:39:49 UTC 2010


On Saturday 06 February 2010 22:56:15 Sam Leffler wrote:
> Bernhard Schmidt wrote:
> > Hi,
> >
> > When hostapd triggers rekeying of the group key, wpa_supplicant
> > successfully sets the correct new key. On first use of the new key
> > tkip_mixing_phase1() should be applied before decrypting any frames,
> > tkip_decrypt() does this as
> >
> > if (iv32 != (u32)(key->wk_keyrsc[tid] >> 16) || !ctx->rx_phase1_done) {
> > 	tkip_mixing_phase1(ctx->rx_ttak, key->wk_key,
> > 		wh->i_addr2, iv32);
> > 	ctx->rx_phase1_done = 1;
> > }
> >
> > But, after a rekeying event, neither of this condition match, especially
> > as rx_phase1_done is no longer zero, therefore tkip_mixing_phase1() isn't
> > called which leads to dropped frames with "TKIP ICV mismatch on decrypt"
> > messages.
> >
> > A working solution for that is to set rx_phase1_done to zero inside
> > tkip_setkey(). I'm not sure whether that is the best solution or if it is
> > better to set/reset the wk_keyrsc sequence, at least this diff works for
> > me and few other over at the Forums.
> >
> > Index: sys/net80211/ieee80211_crypto_tkip.c
> > ===================================================================
> > --- sys/net80211/ieee80211_crypto_tkip.c	(revision 203242)
> > +++ sys/net80211/ieee80211_crypto_tkip.c	(working copy)
> > @@ -144,6 +144,8 @@ tkip_setkey(struct ieee80211_key *k)
> >  		return 0;
> >  	}
> >  	k->wk_keytsc = 1;		/* TSC starts at 1 */
> > +	if (k->wk_flags & IEEE80211_KEY_GROUP)
> > +		ctx->rx_phase1_done = 0;
> >  	return 1;
> >  }
> 
> Reseting this flag in setkey looks right but why only for group keys?  I
> don't think you want to reset the keyrsc unless instructed; if I recall
> a new RSC may be sent down by the authenticator when plumbing a key--but
> it's been a while since I looked at this.
> 
> Have you looked at other implementations?

Doing that for all keys is probably right, have to test that.

I did look at other implementation, they do zero out (tkip_ctx *)ctx inside 
tkip_setkey() and restore part of its content from the key, which has the side 
effect that rx_phase1_done also zero. No one handles that case intentionally.

-- 
Bernhard


More information about the freebsd-net mailing list