Commit 8e8862b79d2ce9177bfddd85b8328a86a25c69b2

Authored by Harvey Harrison
Committed by John W. Linville
1 parent f14df8049f

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>

Showing 3 changed files with 35 additions and 41 deletions Side-by-side Diff

net/mac80211/michael.c
... ... @@ -8,6 +8,7 @@
8 8 */
9 9 #include <linux/types.h>
10 10 #include <linux/bitops.h>
  11 +#include <linux/ieee80211.h>
11 12 #include <asm/unaligned.h>
12 13  
13 14 #include "michael.h"
14 15  
... ... @@ -26,9 +27,18 @@
26 27 mctx->l += mctx->r;
27 28 }
28 29  
29   -static void michael_mic_hdr(struct michael_mic_ctx *mctx,
30   - const u8 *key, const u8 *da, const u8 *sa, u8 priority)
  30 +static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key,
  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 42 mctx->l = get_unaligned_le32(key);
33 43 mctx->r = get_unaligned_le32(key + 4);
34 44  
35 45  
36 46  
... ... @@ -40,17 +50,17 @@
40 50 michael_block(mctx, get_unaligned_le16(&da[4]) |
41 51 (get_unaligned_le16(sa) << 16));
42 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 57 const u8 *data, size_t data_len, u8 *mic)
48 58 {
49 59 u32 val;
50 60 size_t block, blocks, left;
51 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 65 /* Real data */
56 66 blocks = data_len / 4;
net/mac80211/michael.h
... ... @@ -18,7 +18,7 @@
18 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 22 const u8 *data, size_t data_len, u8 *mic);
23 23  
24 24 #endif /* MICHAEL_H */
... ... @@ -21,38 +21,13 @@
21 21 #include "aes_ccm.h"
22 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 24 ieee80211_tx_result
52 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 28 size_t data_len;
  29 + unsigned int hdrlen;
  30 + struct ieee80211_hdr *hdr;
56 31 u16 fc;
57 32 struct sk_buff *skb = tx->skb;
58 33 int authenticator;
59 34  
... ... @@ -65,9 +40,14 @@
65 40 !WLAN_FC_DATA_PRESENT(fc))
66 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 46 return TX_DROP;
70 47  
  48 + data = skb->data + hdrlen;
  49 + data_len = skb->len - hdrlen;
  50 +
71 51 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
72 52 !(tx->flags & IEEE80211_TX_FRAGMENTED) &&
73 53 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
... ... @@ -97,7 +77,7 @@
97 77 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
98 78 key = &tx->key->conf.key[key_offset];
99 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 82 return TX_CONTINUE;
103 83 }
104 84  
... ... @@ -106,8 +86,10 @@
106 86 ieee80211_rx_result
107 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 90 size_t data_len;
  91 + unsigned int hdrlen;
  92 + struct ieee80211_hdr *hdr;
111 93 u16 fc;
112 94 u8 mic[MICHAEL_MIC_LEN];
113 95 struct sk_buff *skb = rx->skb;
114 96  
... ... @@ -126,11 +108,13 @@
126 108 !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc))
127 109 return RX_CONTINUE;
128 110  
129   - if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)
130   - || data_len < MICHAEL_MIC_LEN)
  111 + hdr = (struct ieee80211_hdr *)skb->data;
  112 + hdrlen = ieee80211_hdrlen(hdr->frame_control);
  113 + if (skb->len < hdrlen + MICHAEL_MIC_LEN)
131 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 119 #if 0
136 120 authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */
... ... @@ -143,7 +127,7 @@
143 127 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY :
144 128 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
145 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 131 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
148 132 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
149 133 return RX_DROP_UNUSABLE;