diff options
author | Harvey Harrison <harvey.harrison@gmail.com> | 2008-07-02 14:05:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-08 14:16:00 -0400 |
commit | f14df8049f9c9f34164dd598772fecea83a394a2 (patch) | |
tree | 3f13b28d569b69246e2a66bc6e9a9faf54c1f46b /net/mac80211/wpa.c | |
parent | 73e1f7c823252d671361cddde0b498bf2c0fe4e1 (diff) |
mac80211: remove one user of ieee80211_get_hdr_info
ccmp_special_blocks was only using it to calculate data_len,
calculate that directly.
Use unaligned helpers rather than masking/shifting.
Use symbolic constants for the masked frame_control, and do it directly
on a le16 value.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 222001c47d89..919e30ce2980 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
13 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
14 | #include <linux/ieee80211.h> | ||
15 | #include <asm/unaligned.h> | ||
14 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
15 | 17 | ||
16 | #include "ieee80211_i.h" | 18 | #include "ieee80211_i.h" |
@@ -296,67 +298,61 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
296 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, | 298 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, |
297 | int encrypted) | 299 | int encrypted) |
298 | { | 300 | { |
299 | u16 fc; | 301 | __le16 mask_fc; |
300 | int a4_included, qos_included; | 302 | int a4_included; |
301 | u8 qos_tid, *fc_pos, *data, *sa, *da; | 303 | u8 qos_tid; |
302 | int len_a; | 304 | u16 data_len, len_a; |
303 | size_t data_len; | 305 | unsigned int hdrlen; |
304 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 306 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
305 | 307 | ||
306 | fc_pos = (u8 *) &hdr->frame_control; | 308 | /* |
307 | fc = fc_pos[0] ^ (fc_pos[1] << 8); | 309 | * Mask FC: zero subtype b4 b5 b6 |
308 | a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | 310 | * Retry, PwrMgt, MoreData; set Protected |
309 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 311 | */ |
310 | 312 | mask_fc = hdr->frame_control; | |
311 | ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len); | 313 | mask_fc &= ~cpu_to_le16(0x0070 | IEEE80211_FCTL_RETRY | |
312 | data_len -= CCMP_HDR_LEN + (encrypted ? CCMP_MIC_LEN : 0); | 314 | IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA); |
313 | if (qos_tid & 0x80) { | 315 | mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
314 | qos_included = 1; | 316 | |
315 | qos_tid &= IEEE80211_QOS_CTL_TID_MASK; | 317 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
316 | } else | 318 | len_a = hdrlen - 2; |
317 | qos_included = 0; | 319 | a4_included = ieee80211_has_a4(hdr->frame_control); |
318 | /* First block, b_0 */ | ||
319 | 320 | ||
321 | if (ieee80211_is_data_qos(hdr->frame_control)) | ||
322 | qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | ||
323 | else | ||
324 | qos_tid = 0; | ||
325 | |||
326 | data_len = skb->len - hdrlen - CCMP_HDR_LEN; | ||
327 | if (encrypted) | ||
328 | data_len -= CCMP_MIC_LEN; | ||
329 | |||
330 | /* First block, b_0 */ | ||
320 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ | 331 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ |
321 | /* Nonce: QoS Priority | A2 | PN */ | 332 | /* Nonce: QoS Priority | A2 | PN */ |
322 | b_0[1] = qos_tid; | 333 | b_0[1] = qos_tid; |
323 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); | 334 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); |
324 | memcpy(&b_0[8], pn, CCMP_PN_LEN); | 335 | memcpy(&b_0[8], pn, CCMP_PN_LEN); |
325 | /* l(m) */ | 336 | /* l(m) */ |
326 | b_0[14] = (data_len >> 8) & 0xff; | 337 | put_unaligned_be16(data_len, &b_0[14]); |
327 | b_0[15] = data_len & 0xff; | ||
328 | |||
329 | 338 | ||
330 | /* AAD (extra authenticate-only data) / masked 802.11 header | 339 | /* AAD (extra authenticate-only data) / masked 802.11 header |
331 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ | 340 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ |
332 | 341 | put_unaligned_be16(len_a, &aad[0]); | |
333 | len_a = a4_included ? 28 : 22; | 342 | put_unaligned(mask_fc, (__le16 *)&aad[2]); |
334 | if (qos_included) | ||
335 | len_a += IEEE80211_QOS_CTL_LEN; | ||
336 | |||
337 | aad[0] = 0; /* (len_a >> 8) & 0xff; */ | ||
338 | aad[1] = len_a & 0xff; | ||
339 | /* Mask FC: zero subtype b4 b5 b6 */ | ||
340 | aad[2] = fc_pos[0] & ~(BIT(4) | BIT(5) | BIT(6)); | ||
341 | /* Retry, PwrMgt, MoreData; set Protected */ | ||
342 | aad[3] = (fc_pos[1] & ~(BIT(3) | BIT(4) | BIT(5))) | BIT(6); | ||
343 | memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); | 343 | memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); |
344 | 344 | ||
345 | /* Mask Seq#, leave Frag# */ | 345 | /* Mask Seq#, leave Frag# */ |
346 | aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; | 346 | aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; |
347 | aad[23] = 0; | 347 | aad[23] = 0; |
348 | |||
348 | if (a4_included) { | 349 | if (a4_included) { |
349 | memcpy(&aad[24], hdr->addr4, ETH_ALEN); | 350 | memcpy(&aad[24], hdr->addr4, ETH_ALEN); |
350 | aad[30] = 0; | 351 | aad[30] = qos_tid; |
351 | aad[31] = 0; | 352 | aad[31] = 0; |
352 | } else | 353 | } else { |
353 | memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); | 354 | memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); |
354 | if (qos_included) { | 355 | aad[24] = qos_tid; |
355 | u8 *dpos = &aad[a4_included ? 30 : 24]; | ||
356 | |||
357 | /* Mask QoS Control field */ | ||
358 | dpos[0] = qos_tid; | ||
359 | dpos[1] = 0; | ||
360 | } | 356 | } |
361 | } | 357 | } |
362 | 358 | ||