Index: head/sys/net80211/ieee80211_crypto.h =================================================================== --- head/sys/net80211/ieee80211_crypto.h +++ head/sys/net80211/ieee80211_crypto.h @@ -178,6 +178,7 @@ void* (*ic_attach)(struct ieee80211vap *, struct ieee80211_key *); void (*ic_detach)(struct ieee80211_key *); int (*ic_setkey)(struct ieee80211_key *); + void (*ic_setiv)(struct ieee80211_key *, uint8_t *); int (*ic_encap)(struct ieee80211_key *, struct mbuf *); int (*ic_decap)(struct ieee80211_key *, struct mbuf *, int); int (*ic_enmic)(struct ieee80211_key *, struct mbuf *, int); Index: head/sys/net80211/ieee80211_crypto_ccmp.c =================================================================== --- head/sys/net80211/ieee80211_crypto_ccmp.c +++ head/sys/net80211/ieee80211_crypto_ccmp.c @@ -63,6 +63,7 @@ static void *ccmp_attach(struct ieee80211vap *, struct ieee80211_key *); static void ccmp_detach(struct ieee80211_key *); static int ccmp_setkey(struct ieee80211_key *); +static void ccmp_setiv(struct ieee80211_key *, uint8_t *); static int ccmp_encap(struct ieee80211_key *, struct mbuf *); static int ccmp_decap(struct ieee80211_key *, struct mbuf *, int); static int ccmp_enmic(struct ieee80211_key *, struct mbuf *, int); @@ -78,6 +79,7 @@ .ic_attach = ccmp_attach, .ic_detach = ccmp_detach, .ic_setkey = ccmp_setkey, + .ic_setiv = ccmp_setiv, .ic_encap = ccmp_encap, .ic_decap = ccmp_decap, .ic_enmic = ccmp_enmic, @@ -134,6 +136,26 @@ return 1; } +static void +ccmp_setiv(struct ieee80211_key *k, uint8_t *ivp) +{ + struct ccmp_ctx *ctx = k->wk_private; + struct ieee80211vap *vap = ctx->cc_vap; + uint8_t keyid; + + keyid = ieee80211_crypto_get_keyid(vap, k) << 6; + + k->wk_keytsc++; + ivp[0] = k->wk_keytsc >> 0; /* PN0 */ + ivp[1] = k->wk_keytsc >> 8; /* PN1 */ + ivp[2] = 0; /* Reserved */ + ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ + ivp[4] = k->wk_keytsc >> 16; /* PN2 */ + ivp[5] = k->wk_keytsc >> 24; /* PN3 */ + ivp[6] = k->wk_keytsc >> 32; /* PN4 */ + ivp[7] = k->wk_keytsc >> 40; /* PN5 */ +} + /* * Add privacy headers appropriate for the specified key. */ @@ -142,9 +164,7 @@ { struct ccmp_ctx *ctx = k->wk_private; struct ieee80211com *ic = ctx->cc_ic; - struct ieee80211vap *vap = ctx->cc_vap; uint8_t *ivp; - uint8_t keyid; int hdrlen; hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); @@ -159,17 +179,7 @@ ovbcopy(ivp + ccmp.ic_header, ivp, hdrlen); ivp += hdrlen; - keyid = ieee80211_crypto_get_keyid(vap, k) << 6; - - k->wk_keytsc++; /* XXX wrap at 48 bits */ - ivp[0] = k->wk_keytsc >> 0; /* PN0 */ - ivp[1] = k->wk_keytsc >> 8; /* PN1 */ - ivp[2] = 0; /* Reserved */ - ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ - ivp[4] = k->wk_keytsc >> 16; /* PN2 */ - ivp[5] = k->wk_keytsc >> 24; /* PN3 */ - ivp[6] = k->wk_keytsc >> 32; /* PN4 */ - ivp[7] = k->wk_keytsc >> 40; /* PN5 */ + ccmp_setiv(k, ivp); /* * Finally, do software encrypt if needed. Index: head/sys/net80211/ieee80211_crypto_none.c =================================================================== --- head/sys/net80211/ieee80211_crypto_none.c +++ head/sys/net80211/ieee80211_crypto_none.c @@ -48,6 +48,7 @@ static void *none_attach(struct ieee80211vap *, struct ieee80211_key *); static void none_detach(struct ieee80211_key *); static int none_setkey(struct ieee80211_key *); +static void none_setiv(struct ieee80211_key *, uint8_t *); static int none_encap(struct ieee80211_key *, struct mbuf *); static int none_decap(struct ieee80211_key *, struct mbuf *, int); static int none_enmic(struct ieee80211_key *, struct mbuf *, int); @@ -62,6 +63,7 @@ .ic_attach = none_attach, .ic_detach = none_detach, .ic_setkey = none_setkey, + .ic_setiv = none_setiv, .ic_encap = none_encap, .ic_decap = none_decap, .ic_enmic = none_enmic, @@ -87,6 +89,11 @@ return 1; } +static void +none_setiv(struct ieee80211_key *k, uint8_t *ivp) +{ +} + static int none_encap(struct ieee80211_key *k, struct mbuf *m) { Index: head/sys/net80211/ieee80211_crypto_tkip.c =================================================================== --- head/sys/net80211/ieee80211_crypto_tkip.c +++ head/sys/net80211/ieee80211_crypto_tkip.c @@ -54,6 +54,7 @@ static void *tkip_attach(struct ieee80211vap *, struct ieee80211_key *); static void tkip_detach(struct ieee80211_key *); static int tkip_setkey(struct ieee80211_key *); +static void tkip_setiv(struct ieee80211_key *, uint8_t *); static int tkip_encap(struct ieee80211_key *, struct mbuf *); static int tkip_enmic(struct ieee80211_key *, struct mbuf *, int); static int tkip_decap(struct ieee80211_key *, struct mbuf *, int); @@ -69,6 +70,7 @@ .ic_attach = tkip_attach, .ic_detach = tkip_detach, .ic_setkey = tkip_setkey, + .ic_setiv = tkip_setiv, .ic_encap = tkip_encap, .ic_decap = tkip_decap, .ic_enmic = tkip_enmic, @@ -146,6 +148,26 @@ return 1; } +static void +tkip_setiv(struct ieee80211_key *k, uint8_t *ivp) +{ + struct tkip_ctx *ctx = k->wk_private; + struct ieee80211vap *vap = ctx->tc_vap; + uint8_t keyid; + + keyid = ieee80211_crypto_get_keyid(vap, k) << 6; + + k->wk_keytsc++; + ivp[0] = k->wk_keytsc >> 8; /* TSC1 */ + ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */ + ivp[2] = k->wk_keytsc >> 0; /* TSC0 */ + ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ + ivp[4] = k->wk_keytsc >> 16; /* TSC2 */ + ivp[5] = k->wk_keytsc >> 24; /* TSC3 */ + ivp[6] = k->wk_keytsc >> 32; /* TSC4 */ + ivp[7] = k->wk_keytsc >> 40; /* TSC5 */ +} + /* * Add privacy headers and do any s/w encryption required. */ @@ -156,7 +178,6 @@ struct ieee80211vap *vap = ctx->tc_vap; struct ieee80211com *ic = vap->iv_ic; uint8_t *ivp; - uint8_t keyid; int hdrlen; /* @@ -184,17 +205,7 @@ memmove(ivp, ivp + tkip.ic_header, hdrlen); ivp += hdrlen; - keyid = ieee80211_crypto_get_keyid(vap, k) << 6; - - k->wk_keytsc++; - ivp[0] = k->wk_keytsc >> 8; /* TSC1 */ - ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */ - ivp[2] = k->wk_keytsc >> 0; /* TSC0 */ - ivp[3] = keyid | IEEE80211_WEP_EXTIV; /* KeyID | ExtID */ - ivp[4] = k->wk_keytsc >> 16; /* TSC2 */ - ivp[5] = k->wk_keytsc >> 24; /* TSC3 */ - ivp[6] = k->wk_keytsc >> 32; /* TSC4 */ - ivp[7] = k->wk_keytsc >> 40; /* TSC5 */ + tkip_setiv(k, ivp); /* * Finally, do software encrypt if needed. Index: head/sys/net80211/ieee80211_crypto_wep.c =================================================================== --- head/sys/net80211/ieee80211_crypto_wep.c +++ head/sys/net80211/ieee80211_crypto_wep.c @@ -50,8 +50,9 @@ static void *wep_attach(struct ieee80211vap *, struct ieee80211_key *); static void wep_detach(struct ieee80211_key *); static int wep_setkey(struct ieee80211_key *); +static void wep_setiv(struct ieee80211_key *, uint8_t *); static int wep_encap(struct ieee80211_key *, struct mbuf *); -static int wep_decap(struct ieee80211_key *, struct mbuf *, int hdrlen); +static int wep_decap(struct ieee80211_key *, struct mbuf *, int); static int wep_enmic(struct ieee80211_key *, struct mbuf *, int); static int wep_demic(struct ieee80211_key *, struct mbuf *, int); @@ -64,6 +65,7 @@ .ic_attach = wep_attach, .ic_detach = wep_detach, .ic_setkey = wep_setkey, + .ic_setiv = wep_setiv, .ic_encap = wep_encap, .ic_decap = wep_decap, .ic_enmic = wep_enmic, @@ -117,31 +119,13 @@ return k->wk_keylen >= 40/NBBY; } -/* - * Add privacy headers appropriate for the specified key. - */ -static int -wep_encap(struct ieee80211_key *k, struct mbuf *m) +static void +wep_setiv(struct ieee80211_key *k, uint8_t *ivp) { struct wep_ctx *ctx = k->wk_private; struct ieee80211vap *vap = ctx->wc_vap; - struct ieee80211com *ic = ctx->wc_ic; uint32_t iv; - uint8_t *ivp; uint8_t keyid; - int hdrlen; - - hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); - - /* - * Copy down 802.11 header and add the IV + KeyID. - */ - M_PREPEND(m, wep.ic_header, M_NOWAIT); - if (m == NULL) - return 0; - ivp = mtod(m, uint8_t *); - ovbcopy(ivp + wep.ic_header, ivp, hdrlen); - ivp += hdrlen; keyid = ieee80211_crypto_get_keyid(vap, k) << 6; @@ -186,6 +170,32 @@ ivp[0] = iv >> 16; #endif ivp[3] = keyid; +} + +/* + * Add privacy headers appropriate for the specified key. + */ +static int +wep_encap(struct ieee80211_key *k, struct mbuf *m) +{ + struct wep_ctx *ctx = k->wk_private; + struct ieee80211com *ic = ctx->wc_ic; + uint8_t *ivp; + int hdrlen; + + hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); + + /* + * Copy down 802.11 header and add the IV + KeyID. + */ + M_PREPEND(m, wep.ic_header, M_NOWAIT); + if (m == NULL) + return 0; + ivp = mtod(m, uint8_t *); + ovbcopy(ivp + wep.ic_header, ivp, hdrlen); + ivp += hdrlen; + + wep_setiv(k, ivp); /* * Finally, do software encrypt if needed.