aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wpa.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r--net/mac80211/wpa.c198
1 files changed, 74 insertions, 124 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 45709ada8fee..345e10e9b313 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -24,46 +24,22 @@ static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da,
24{ 24{
25 struct ieee80211_hdr *hdr; 25 struct ieee80211_hdr *hdr;
26 size_t hdrlen; 26 size_t hdrlen;
27 u16 fc; 27 __le16 fc;
28 int a4_included;
29 u8 *pos;
30 28
31 hdr = (struct ieee80211_hdr *) skb->data; 29 hdr = (struct ieee80211_hdr *)skb->data;
32 fc = le16_to_cpu(hdr->frame_control); 30 fc = hdr->frame_control;
33
34 hdrlen = 24;
35 if ((fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) ==
36 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
37 hdrlen += ETH_ALEN;
38 *sa = hdr->addr4;
39 *da = hdr->addr3;
40 } else if (fc & IEEE80211_FCTL_FROMDS) {
41 *sa = hdr->addr3;
42 *da = hdr->addr1;
43 } else if (fc & IEEE80211_FCTL_TODS) {
44 *sa = hdr->addr2;
45 *da = hdr->addr3;
46 } else {
47 *sa = hdr->addr2;
48 *da = hdr->addr1;
49 }
50 31
51 if (fc & 0x80) 32 hdrlen = ieee80211_hdrlen(fc);
52 hdrlen += 2; 33
34 *sa = ieee80211_get_SA(hdr);
35 *da = ieee80211_get_DA(hdr);
53 36
54 *data = skb->data + hdrlen; 37 *data = skb->data + hdrlen;
55 *data_len = skb->len - hdrlen; 38 *data_len = skb->len - hdrlen;
56 39
57 a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 40 if (ieee80211_is_data_qos(fc))
58 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); 41 *qos_tid = (*ieee80211_get_qos_ctl(hdr) & 0x0f) | 0x80;
59 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && 42 else
60 fc & IEEE80211_STYPE_QOS_DATA) {
61 pos = (u8 *) &hdr->addr4;
62 if (a4_included)
63 pos += 6;
64 *qos_tid = pos[0] & 0x0f;
65 *qos_tid |= 0x80; /* qos_included flag */
66 } else
67 *qos_tid = 0; 43 *qos_tid = 0;
68 44
69 return skb->len < hdrlen ? -1 : 0; 45 return skb->len < hdrlen ? -1 : 0;
@@ -79,6 +55,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
79 struct sk_buff *skb = tx->skb; 55 struct sk_buff *skb = tx->skb;
80 int authenticator; 56 int authenticator;
81 int wpa_test = 0; 57 int wpa_test = 0;
58 int tail;
82 59
83 fc = tx->fc; 60 fc = tx->fc;
84 61
@@ -98,16 +75,13 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
98 return TX_CONTINUE; 75 return TX_CONTINUE;
99 } 76 }
100 77
101 if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { 78 tail = MICHAEL_MIC_LEN;
102 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 79 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
103 if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, 80 tail += TKIP_ICV_LEN;
104 MICHAEL_MIC_LEN + TKIP_ICV_LEN, 81
105 GFP_ATOMIC))) { 82 if (WARN_ON(skb_tailroom(skb) < tail ||
106 printk(KERN_DEBUG "%s: failed to allocate more memory " 83 skb_headroom(skb) < TKIP_IV_LEN))
107 "for Michael MIC\n", tx->dev->name); 84 return TX_DROP;
108 return TX_DROP;
109 }
110 }
111 85
112#if 0 86#if 0
113 authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ 87 authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */
@@ -176,59 +150,58 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
176 skb_trim(skb, skb->len - MICHAEL_MIC_LEN); 150 skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
177 151
178 /* update IV in key information to be able to detect replays */ 152 /* update IV in key information to be able to detect replays */
179 rx->key->u.tkip.iv32_rx[rx->queue] = rx->tkip_iv32; 153 rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
180 rx->key->u.tkip.iv16_rx[rx->queue] = rx->tkip_iv16; 154 rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
181 155
182 return RX_CONTINUE; 156 return RX_CONTINUE;
183} 157}
184 158
185 159
186static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, 160static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
187 struct sk_buff *skb, int test)
188{ 161{
189 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 162 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
190 struct ieee80211_key *key = tx->key; 163 struct ieee80211_key *key = tx->key;
191 int hdrlen, len, tailneed; 164 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
192 u16 fc; 165 unsigned int hdrlen;
166 int len, tail;
193 u8 *pos; 167 u8 *pos;
194 168
195 fc = le16_to_cpu(hdr->frame_control); 169 info->control.icv_len = TKIP_ICV_LEN;
196 hdrlen = ieee80211_get_hdrlen(fc); 170 info->control.iv_len = TKIP_IV_LEN;
171
172 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
173 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
174 /* hwaccel - with no need for preallocated room for IV/ICV */
175 info->control.hw_key = &tx->key->conf;
176 return 0;
177 }
178
179 hdrlen = ieee80211_hdrlen(hdr->frame_control);
197 len = skb->len - hdrlen; 180 len = skb->len - hdrlen;
198 181
199 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 182 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
200 tailneed = 0; 183 tail = 0;
201 else 184 else
202 tailneed = TKIP_ICV_LEN; 185 tail = TKIP_ICV_LEN;
203 186
204 if ((skb_headroom(skb) < TKIP_IV_LEN || 187 if (WARN_ON(skb_tailroom(skb) < tail ||
205 skb_tailroom(skb) < tailneed)) { 188 skb_headroom(skb) < TKIP_IV_LEN))
206 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 189 return -1;
207 if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed,
208 GFP_ATOMIC)))
209 return -1;
210 }
211 190
212 pos = skb_push(skb, TKIP_IV_LEN); 191 pos = skb_push(skb, TKIP_IV_LEN);
213 memmove(pos, pos + TKIP_IV_LEN, hdrlen); 192 memmove(pos, pos + TKIP_IV_LEN, hdrlen);
214 pos += hdrlen; 193 pos += hdrlen;
215 194
216 /* Increase IV for the frame */ 195 /* Increase IV for the frame */
217 key->u.tkip.iv16++; 196 key->u.tkip.tx.iv16++;
218 if (key->u.tkip.iv16 == 0) 197 if (key->u.tkip.tx.iv16 == 0)
219 key->u.tkip.iv32++; 198 key->u.tkip.tx.iv32++;
220 199
221 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 200 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
222 hdr = (struct ieee80211_hdr *)skb->data;
223
224 /* hwaccel - with preallocated room for IV */ 201 /* hwaccel - with preallocated room for IV */
225 ieee80211_tkip_add_iv(pos, key, 202 ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
226 (u8) (key->u.tkip.iv16 >> 8),
227 (u8) (((key->u.tkip.iv16 >> 8) | 0x20) &
228 0x7f),
229 (u8) key->u.tkip.iv16);
230 203
231 tx->control->key_idx = tx->key->conf.hw_key_idx; 204 info->control.hw_key = &tx->key->conf;
232 return 0; 205 return 0;
233 } 206 }
234 207
@@ -246,28 +219,16 @@ ieee80211_tx_result
246ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) 219ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
247{ 220{
248 struct sk_buff *skb = tx->skb; 221 struct sk_buff *skb = tx->skb;
249 int wpa_test = 0, test = 0;
250 222
251 tx->control->icv_len = TKIP_ICV_LEN;
252 tx->control->iv_len = TKIP_IV_LEN;
253 ieee80211_tx_set_protected(tx); 223 ieee80211_tx_set_protected(tx);
254 224
255 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 225 if (tkip_encrypt_skb(tx, skb) < 0)
256 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
257 !wpa_test) {
258 /* hwaccel - with no need for preallocated room for IV/ICV */
259 tx->control->key_idx = tx->key->conf.hw_key_idx;
260 return TX_CONTINUE;
261 }
262
263 if (tkip_encrypt_skb(tx, skb, test) < 0)
264 return TX_DROP; 226 return TX_DROP;
265 227
266 if (tx->extra_frag) { 228 if (tx->extra_frag) {
267 int i; 229 int i;
268 for (i = 0; i < tx->num_extra_frag; i++) { 230 for (i = 0; i < tx->num_extra_frag; i++) {
269 if (tkip_encrypt_skb(tx, tx->extra_frag[i], test) 231 if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0)
270 < 0)
271 return TX_DROP; 232 return TX_DROP;
272 } 233 }
273 } 234 }
@@ -280,14 +241,12 @@ ieee80211_rx_result
280ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) 241ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
281{ 242{
282 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 243 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
283 u16 fc;
284 int hdrlen, res, hwaccel = 0, wpa_test = 0; 244 int hdrlen, res, hwaccel = 0, wpa_test = 0;
285 struct ieee80211_key *key = rx->key; 245 struct ieee80211_key *key = rx->key;
286 struct sk_buff *skb = rx->skb; 246 struct sk_buff *skb = rx->skb;
287 DECLARE_MAC_BUF(mac); 247 DECLARE_MAC_BUF(mac);
288 248
289 fc = le16_to_cpu(hdr->frame_control); 249 hdrlen = ieee80211_hdrlen(hdr->frame_control);
290 hdrlen = ieee80211_get_hdrlen(fc);
291 250
292 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) 251 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
293 return RX_CONTINUE; 252 return RX_CONTINUE;
@@ -429,36 +388,41 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr)
429} 388}
430 389
431 390
432static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, 391static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
433 struct sk_buff *skb, int test)
434{ 392{
435 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 393 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
436 struct ieee80211_key *key = tx->key; 394 struct ieee80211_key *key = tx->key;
437 int hdrlen, len, tailneed; 395 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
438 u16 fc; 396 int hdrlen, len, tail;
439 u8 *pos, *pn, *b_0, *aad, *scratch; 397 u8 *pos, *pn, *b_0, *aad, *scratch;
440 int i; 398 int i;
441 399
400 info->control.icv_len = CCMP_MIC_LEN;
401 info->control.iv_len = CCMP_HDR_LEN;
402
403 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
404 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
405 /* hwaccel - with no need for preallocated room for CCMP "
406 * header or MIC fields */
407 info->control.hw_key = &tx->key->conf;
408 return 0;
409 }
410
442 scratch = key->u.ccmp.tx_crypto_buf; 411 scratch = key->u.ccmp.tx_crypto_buf;
443 b_0 = scratch + 3 * AES_BLOCK_LEN; 412 b_0 = scratch + 3 * AES_BLOCK_LEN;
444 aad = scratch + 4 * AES_BLOCK_LEN; 413 aad = scratch + 4 * AES_BLOCK_LEN;
445 414
446 fc = le16_to_cpu(hdr->frame_control); 415 hdrlen = ieee80211_hdrlen(hdr->frame_control);
447 hdrlen = ieee80211_get_hdrlen(fc);
448 len = skb->len - hdrlen; 416 len = skb->len - hdrlen;
449 417
450 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 418 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
451 tailneed = 0; 419 tail = 0;
452 else 420 else
453 tailneed = CCMP_MIC_LEN; 421 tail = CCMP_MIC_LEN;
454 422
455 if ((skb_headroom(skb) < CCMP_HDR_LEN || 423 if (WARN_ON(skb_tailroom(skb) < tail ||
456 skb_tailroom(skb) < tailneed)) { 424 skb_headroom(skb) < CCMP_HDR_LEN))
457 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 425 return -1;
458 if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed,
459 GFP_ATOMIC)))
460 return -1;
461 }
462 426
463 pos = skb_push(skb, CCMP_HDR_LEN); 427 pos = skb_push(skb, CCMP_HDR_LEN);
464 memmove(pos, pos + CCMP_HDR_LEN, hdrlen); 428 memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
@@ -478,7 +442,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx,
478 442
479 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 443 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
480 /* hwaccel - with preallocated room for CCMP header */ 444 /* hwaccel - with preallocated room for CCMP header */
481 tx->control->key_idx = key->conf.hw_key_idx; 445 info->control.hw_key = &tx->key->conf;
482 return 0; 446 return 0;
483 } 447 }
484 448
@@ -495,28 +459,16 @@ ieee80211_tx_result
495ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) 459ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
496{ 460{
497 struct sk_buff *skb = tx->skb; 461 struct sk_buff *skb = tx->skb;
498 int test = 0;
499 462
500 tx->control->icv_len = CCMP_MIC_LEN;
501 tx->control->iv_len = CCMP_HDR_LEN;
502 ieee80211_tx_set_protected(tx); 463 ieee80211_tx_set_protected(tx);
503 464
504 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 465 if (ccmp_encrypt_skb(tx, skb) < 0)
505 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
506 /* hwaccel - with no need for preallocated room for CCMP "
507 * header or MIC fields */
508 tx->control->key_idx = tx->key->conf.hw_key_idx;
509 return TX_CONTINUE;
510 }
511
512 if (ccmp_encrypt_skb(tx, skb, test) < 0)
513 return TX_DROP; 466 return TX_DROP;
514 467
515 if (tx->extra_frag) { 468 if (tx->extra_frag) {
516 int i; 469 int i;
517 for (i = 0; i < tx->num_extra_frag; i++) { 470 for (i = 0; i < tx->num_extra_frag; i++) {
518 if (ccmp_encrypt_skb(tx, tx->extra_frag[i], test) 471 if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0)
519 < 0)
520 return TX_DROP; 472 return TX_DROP;
521 } 473 }
522 } 474 }
@@ -529,7 +481,6 @@ ieee80211_rx_result
529ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) 481ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
530{ 482{
531 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 483 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
532 u16 fc;
533 int hdrlen; 484 int hdrlen;
534 struct ieee80211_key *key = rx->key; 485 struct ieee80211_key *key = rx->key;
535 struct sk_buff *skb = rx->skb; 486 struct sk_buff *skb = rx->skb;
@@ -537,8 +488,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
537 int data_len; 488 int data_len;
538 DECLARE_MAC_BUF(mac); 489 DECLARE_MAC_BUF(mac);
539 490
540 fc = le16_to_cpu(hdr->frame_control); 491 hdrlen = ieee80211_hdrlen(hdr->frame_control);
541 hdrlen = ieee80211_get_hdrlen(fc);
542 492
543 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) 493 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
544 return RX_CONTINUE; 494 return RX_CONTINUE;