Date: Thu, 9 Dec 2004 23:18:01 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 66752 for review Message-ID: <200412092318.iB9NI1Nv095835@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=66752 Change 66752 by sam@sam_ebb on 2004/12/09 23:17:37 Fix WME+WPA operation. Atheros parts mark IEEE80211_F_DATAPAD which forces 32-bit alignment of the crypto payload but the cipher encap support wasn't taking the pad bytes into account. This didn't matter until QoS data frames were encrypted and required padding. o add ieee80211_hdrspace and ieee80211_anyhdrspace that work like ieee80211_hdrsize and ieee80211_anyhdrsize but consider padding requirements o sprinkle use of the above in the tx cipher paths (not need currently on rx because the QoS and pad bits are stripped early in ieee80211_input; this is likely to change) Also: make some inline's be __inline for portability. Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_crypto_ccmp.c#3 edit .. //depot/projects/wifi/sys/net80211/ieee80211_crypto_tkip.c#4 edit .. //depot/projects/wifi/sys/net80211/ieee80211_crypto_wep.c#3 edit .. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#10 edit .. //depot/projects/wifi/sys/net80211/ieee80211_var.h#19 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_crypto_ccmp.c#3 (text+ko) ==== @@ -136,10 +136,12 @@ static int ccmp_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid) { + struct ccmp_ctx *ctx = k->wk_private; + struct ieee80211com *ic = ctx->cc_ic; u_int8_t *ivp; int hdrlen; - hdrlen = ieee80211_hdrsize(mtod(m, void *)); + hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); /* * Copy down 802.11 header and add the IV, KeyID, and ExtIV. ==== //depot/projects/wifi/sys/net80211/ieee80211_crypto_tkip.c#4 (text+ko) ==== @@ -171,7 +171,7 @@ ic->ic_stats.is_crypto_tkipcm++; return 0; } - hdrlen = ieee80211_hdrsize(mtod(m, void *)); + hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); /* * Copy down 802.11 header and add the IV, KeyID, and ExtIV. @@ -215,10 +215,13 @@ if (k->wk_flags & IEEE80211_KEY_SWMIC) { struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); - int hdrlen = ieee80211_hdrsize(wh); + struct ieee80211com *ic = ctx->tc_ic; + int hdrlen; uint8_t mic[IEEE80211_WEP_MICLEN]; - ctx->tc_ic->ic_stats.is_crypto_tkipenmic++; + ic->ic_stats.is_crypto_tkipenmic++; + + hdrlen = ieee80211_hdrspace(ic, wh); michael_mic(ctx, k->wk_txmic, m, hdrlen, m->m_pkthdr.len - hdrlen, mic); ==== //depot/projects/wifi/sys/net80211/ieee80211_crypto_wep.c#3 (text+ko) ==== @@ -120,11 +120,12 @@ wep_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid) { struct wep_ctx *ctx = k->wk_private; + struct ieee80211com *ic = ctx->wc_ic; u_int32_t iv; u_int8_t *ivp; int hdrlen; - hdrlen = ieee80211_hdrsize(mtod(m, void *)); + hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); /* * Copy down 802.11 header and add the IV + KeyID. ==== //depot/projects/wifi/sys/net80211/ieee80211_proto.h#10 (text+ko) ==== @@ -81,7 +81,7 @@ /* * Return the size of the 802.11 header for a management or data frame. */ -static inline int +static __inline int ieee80211_hdrsize(const void *data) { const struct ieee80211_frame *wh = data; @@ -98,9 +98,9 @@ } /* - * Return the size of the 802.11 header; handles any type of frame. + * Like ieee80211_hdrsize, but handles any type of frame. */ -static inline int +static __inline int ieee80211_anyhdrsize(const void *data) { const struct ieee80211_frame *wh = data; ==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#19 (text+ko) ==== @@ -282,6 +282,36 @@ ic->ic_crypto.cs_key_update_end(ic); } +/* + * XXX these need to be here for IEEE80211_F_DATAPAD + */ + +/* + * Return the space occupied by the 802.11 header and any + * padding required by the driver. This works for a + * management or data frame. + */ +static __inline int +ieee80211_hdrspace(struct ieee80211com *ic, const void *data) +{ + int size = ieee80211_hdrsize(data); + if (ic->ic_flags & IEEE80211_F_DATAPAD) + size = roundup(size, sizeof(u_int32_t)); + return size; +} + +/* + * Like ieee80211_hdrspace, but handles any type of frame. + */ +static __inline int +ieee80211_anyhdrspace(struct ieee80211com *ic, const void *data) +{ + int size = ieee80211_anyhdrsize(data); + if (ic->ic_flags & IEEE80211_F_DATAPAD) + size = roundup(size, sizeof(u_int32_t)); + return size; +} + #define IEEE80211_MSG_DEBUG 0x40000000 /* IFF_DEBUG equivalent */ #define IEEE80211_MSG_DUMPPKTS 0x20000000 /* IFF_LINK2 equivalant */ #define IEEE80211_MSG_CRYPTO 0x10000000 /* crypto work */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200412092318.iB9NI1Nv095835>