aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarvey Harrison <harvey.harrison@gmail.com>2008-07-02 14:05:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-08 14:16:01 -0400
commit8e8862b79d2ce9177bfddd85b8328a86a25c69b2 (patch)
tree595f0a47cf20800ee895c9cd6e98817ac1ff71ba
parentf14df8049f9c9f34164dd598772fecea83a394a2 (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.c20
-rw-r--r--net/mac80211/michael.h2
-rw-r--r--net/mac80211/wpa.c54
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
29static void michael_mic_hdr(struct michael_mic_ctx *mctx, 30static 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
46void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, 56void 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
21void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, 21void 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
24static 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
51ieee80211_tx_result 24ieee80211_tx_result
52ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) 25ieee80211_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)
106ieee80211_rx_result 86ieee80211_rx_result
107ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) 87ieee80211_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;