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:01 -0400 |
commit | 8e8862b79d2ce9177bfddd85b8328a86a25c69b2 (patch) | |
tree | 595f0a47cf20800ee895c9cd6e98817ac1ff71ba | |
parent | f14df8049f9c9f34164dd598772fecea83a394a2 (diff) |
mac80211: remove ieee80211_get_hdr_info
Do the check for sufficient skb->len explicitly and pass a pointer
to the struct ieee80211_hdr directly to the michael_mic calculation.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | net/mac80211/michael.c | 20 | ||||
-rw-r--r-- | net/mac80211/michael.h | 2 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 54 |
3 files changed, 35 insertions, 41 deletions
diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c index 1fcdf38cf60c..408649bd4702 100644 --- a/net/mac80211/michael.c +++ b/net/mac80211/michael.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
11 | #include <linux/ieee80211.h> | ||
11 | #include <asm/unaligned.h> | 12 | #include <asm/unaligned.h> |
12 | 13 | ||
13 | #include "michael.h" | 14 | #include "michael.h" |
@@ -26,9 +27,18 @@ static void michael_block(struct michael_mic_ctx *mctx, u32 val) | |||
26 | mctx->l += mctx->r; | 27 | mctx->l += mctx->r; |
27 | } | 28 | } |
28 | 29 | ||
29 | static void michael_mic_hdr(struct michael_mic_ctx *mctx, | 30 | static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key, |
30 | const u8 *key, const u8 *da, const u8 *sa, u8 priority) | 31 | struct ieee80211_hdr *hdr) |
31 | { | 32 | { |
33 | u8 *da, *sa, tid; | ||
34 | |||
35 | da = ieee80211_get_DA(hdr); | ||
36 | sa = ieee80211_get_SA(hdr); | ||
37 | if (ieee80211_is_data_qos(hdr->frame_control)) | ||
38 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | ||
39 | else | ||
40 | tid = 0; | ||
41 | |||
32 | mctx->l = get_unaligned_le32(key); | 42 | mctx->l = get_unaligned_le32(key); |
33 | mctx->r = get_unaligned_le32(key + 4); | 43 | mctx->r = get_unaligned_le32(key + 4); |
34 | 44 | ||
@@ -40,17 +50,17 @@ static void michael_mic_hdr(struct michael_mic_ctx *mctx, | |||
40 | michael_block(mctx, get_unaligned_le16(&da[4]) | | 50 | michael_block(mctx, get_unaligned_le16(&da[4]) | |
41 | (get_unaligned_le16(sa) << 16)); | 51 | (get_unaligned_le16(sa) << 16)); |
42 | michael_block(mctx, get_unaligned_le32(&sa[2])); | 52 | michael_block(mctx, get_unaligned_le32(&sa[2])); |
43 | michael_block(mctx, priority); | 53 | michael_block(mctx, tid); |
44 | } | 54 | } |
45 | 55 | ||
46 | void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, | 56 | void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, |
47 | const u8 *data, size_t data_len, u8 *mic) | 57 | const u8 *data, size_t data_len, u8 *mic) |
48 | { | 58 | { |
49 | u32 val; | 59 | u32 val; |
50 | size_t block, blocks, left; | 60 | size_t block, blocks, left; |
51 | struct michael_mic_ctx mctx; | 61 | struct michael_mic_ctx mctx; |
52 | 62 | ||
53 | michael_mic_hdr(&mctx, key, da, sa, priority); | 63 | michael_mic_hdr(&mctx, key, hdr); |
54 | 64 | ||
55 | /* Real data */ | 65 | /* Real data */ |
56 | blocks = data_len / 4; | 66 | blocks = data_len / 4; |
diff --git a/net/mac80211/michael.h b/net/mac80211/michael.h index 69b4501f13ba..3b848dad9587 100644 --- a/net/mac80211/michael.h +++ b/net/mac80211/michael.h | |||
@@ -18,7 +18,7 @@ struct michael_mic_ctx { | |||
18 | u32 l, r; | 18 | u32 l, r; |
19 | }; | 19 | }; |
20 | 20 | ||
21 | void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, | 21 | void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, |
22 | const u8 *data, size_t data_len, u8 *mic); | 22 | const u8 *data, size_t data_len, u8 *mic); |
23 | 23 | ||
24 | #endif /* MICHAEL_H */ | 24 | #endif /* MICHAEL_H */ |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 919e30ce2980..241c932d3b6c 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -21,38 +21,13 @@ | |||
21 | #include "aes_ccm.h" | 21 | #include "aes_ccm.h" |
22 | #include "wpa.h" | 22 | #include "wpa.h" |
23 | 23 | ||
24 | static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, | ||
25 | u8 *qos_tid, u8 **data, size_t *data_len) | ||
26 | { | ||
27 | struct ieee80211_hdr *hdr; | ||
28 | size_t hdrlen; | ||
29 | __le16 fc; | ||
30 | |||
31 | hdr = (struct ieee80211_hdr *)skb->data; | ||
32 | fc = hdr->frame_control; | ||
33 | |||
34 | hdrlen = ieee80211_hdrlen(fc); | ||
35 | |||
36 | *sa = ieee80211_get_SA(hdr); | ||
37 | *da = ieee80211_get_DA(hdr); | ||
38 | |||
39 | *data = skb->data + hdrlen; | ||
40 | *data_len = skb->len - hdrlen; | ||
41 | |||
42 | if (ieee80211_is_data_qos(fc)) | ||
43 | *qos_tid = (*ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK) | 0x80; | ||
44 | else | ||
45 | *qos_tid = 0; | ||
46 | |||
47 | return skb->len < hdrlen ? -1 : 0; | ||
48 | } | ||
49 | |||
50 | |||
51 | ieee80211_tx_result | 24 | ieee80211_tx_result |
52 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | 25 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) |
53 | { | 26 | { |
54 | u8 *data, *sa, *da, *key, *mic, qos_tid, key_offset; | 27 | u8 *data, *key, *mic, key_offset; |
55 | size_t data_len; | 28 | size_t data_len; |
29 | unsigned int hdrlen; | ||
30 | struct ieee80211_hdr *hdr; | ||
56 | u16 fc; | 31 | u16 fc; |
57 | struct sk_buff *skb = tx->skb; | 32 | struct sk_buff *skb = tx->skb; |
58 | int authenticator; | 33 | int authenticator; |
@@ -65,9 +40,14 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
65 | !WLAN_FC_DATA_PRESENT(fc)) | 40 | !WLAN_FC_DATA_PRESENT(fc)) |
66 | return TX_CONTINUE; | 41 | return TX_CONTINUE; |
67 | 42 | ||
68 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) | 43 | hdr = (struct ieee80211_hdr *)skb->data; |
44 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
45 | if (skb->len < hdrlen) | ||
69 | return TX_DROP; | 46 | return TX_DROP; |
70 | 47 | ||
48 | data = skb->data + hdrlen; | ||
49 | data_len = skb->len - hdrlen; | ||
50 | |||
71 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 51 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
72 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && | 52 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && |
73 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && | 53 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && |
@@ -97,7 +77,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
97 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | 77 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; |
98 | key = &tx->key->conf.key[key_offset]; | 78 | key = &tx->key->conf.key[key_offset]; |
99 | mic = skb_put(skb, MICHAEL_MIC_LEN); | 79 | mic = skb_put(skb, MICHAEL_MIC_LEN); |
100 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); | 80 | michael_mic(key, hdr, data, data_len, mic); |
101 | 81 | ||
102 | return TX_CONTINUE; | 82 | return TX_CONTINUE; |
103 | } | 83 | } |
@@ -106,8 +86,10 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
106 | ieee80211_rx_result | 86 | ieee80211_rx_result |
107 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | 87 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) |
108 | { | 88 | { |
109 | u8 *data, *sa, *da, *key = NULL, qos_tid, key_offset; | 89 | u8 *data, *key = NULL, key_offset; |
110 | size_t data_len; | 90 | size_t data_len; |
91 | unsigned int hdrlen; | ||
92 | struct ieee80211_hdr *hdr; | ||
111 | u16 fc; | 93 | u16 fc; |
112 | u8 mic[MICHAEL_MIC_LEN]; | 94 | u8 mic[MICHAEL_MIC_LEN]; |
113 | struct sk_buff *skb = rx->skb; | 95 | struct sk_buff *skb = rx->skb; |
@@ -126,11 +108,13 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
126 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) | 108 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) |
127 | return RX_CONTINUE; | 109 | return RX_CONTINUE; |
128 | 110 | ||
129 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) | 111 | hdr = (struct ieee80211_hdr *)skb->data; |
130 | || data_len < MICHAEL_MIC_LEN) | 112 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
113 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) | ||
131 | return RX_DROP_UNUSABLE; | 114 | return RX_DROP_UNUSABLE; |
132 | 115 | ||
133 | data_len -= MICHAEL_MIC_LEN; | 116 | data = skb->data + hdrlen; |
117 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | ||
134 | 118 | ||
135 | #if 0 | 119 | #if 0 |
136 | authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ | 120 | authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ |
@@ -143,7 +127,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
143 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : | 127 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : |
144 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | 128 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; |
145 | key = &rx->key->conf.key[key_offset]; | 129 | key = &rx->key->conf.key[key_offset]; |
146 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); | 130 | michael_mic(key, hdr, data, data_len, mic); |
147 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { | 131 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { |
148 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 132 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
149 | return RX_DROP_UNUSABLE; | 133 | return RX_DROP_UNUSABLE; |