diff options
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 84 |
1 files changed, 37 insertions, 47 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 70778694877b..0adbcc941ac9 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -9,10 +9,10 @@ | |||
9 | 9 | ||
10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/slab.h> | ||
13 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
14 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
15 | #include <linux/ieee80211.h> | 14 | #include <linux/ieee80211.h> |
15 | #include <linux/gfp.h> | ||
16 | #include <asm/unaligned.h> | 16 | #include <asm/unaligned.h> |
17 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
18 | 18 | ||
@@ -31,8 +31,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
31 | unsigned int hdrlen; | 31 | unsigned int hdrlen; |
32 | struct ieee80211_hdr *hdr; | 32 | struct ieee80211_hdr *hdr; |
33 | struct sk_buff *skb = tx->skb; | 33 | struct sk_buff *skb = tx->skb; |
34 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
34 | int authenticator; | 35 | int authenticator; |
35 | int wpa_test = 0; | ||
36 | int tail; | 36 | int tail; |
37 | 37 | ||
38 | hdr = (struct ieee80211_hdr *)skb->data; | 38 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -47,16 +47,15 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
47 | data = skb->data + hdrlen; | 47 | data = skb->data + hdrlen; |
48 | data_len = skb->len - hdrlen; | 48 | data_len = skb->len - hdrlen; |
49 | 49 | ||
50 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 50 | if (info->control.hw_key && |
51 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && | 51 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && |
52 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && | 52 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { |
53 | !wpa_test) { | 53 | /* hwaccel - with no need for SW-generated MMIC */ |
54 | /* hwaccel - with no need for preallocated room for MMIC */ | ||
55 | return TX_CONTINUE; | 54 | return TX_CONTINUE; |
56 | } | 55 | } |
57 | 56 | ||
58 | tail = MICHAEL_MIC_LEN; | 57 | tail = MICHAEL_MIC_LEN; |
59 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 58 | if (!info->control.hw_key) |
60 | tail += TKIP_ICV_LEN; | 59 | tail += TKIP_ICV_LEN; |
61 | 60 | ||
62 | if (WARN_ON(skb_tailroom(skb) < tail || | 61 | if (WARN_ON(skb_tailroom(skb) < tail || |
@@ -85,16 +84,16 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
85 | u8 *data, *key = NULL, key_offset; | 84 | u8 *data, *key = NULL, key_offset; |
86 | size_t data_len; | 85 | size_t data_len; |
87 | unsigned int hdrlen; | 86 | unsigned int hdrlen; |
88 | struct ieee80211_hdr *hdr; | ||
89 | u8 mic[MICHAEL_MIC_LEN]; | 87 | u8 mic[MICHAEL_MIC_LEN]; |
90 | struct sk_buff *skb = rx->skb; | 88 | struct sk_buff *skb = rx->skb; |
89 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
90 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
91 | int authenticator = 1, wpa_test = 0; | 91 | int authenticator = 1, wpa_test = 0; |
92 | 92 | ||
93 | /* No way to verify the MIC if the hardware stripped it */ | 93 | /* No way to verify the MIC if the hardware stripped it */ |
94 | if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) | 94 | if (status->flag & RX_FLAG_MMIC_STRIPPED) |
95 | return RX_CONTINUE; | 95 | return RX_CONTINUE; |
96 | 96 | ||
97 | hdr = (struct ieee80211_hdr *)skb->data; | ||
98 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || | 97 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || |
99 | !ieee80211_has_protected(hdr->frame_control) || | 98 | !ieee80211_has_protected(hdr->frame_control) || |
100 | !ieee80211_is_data_present(hdr->frame_control)) | 99 | !ieee80211_is_data_present(hdr->frame_control)) |
@@ -147,17 +146,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
147 | int len, tail; | 146 | int len, tail; |
148 | u8 *pos; | 147 | u8 *pos; |
149 | 148 | ||
150 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 149 | if (info->control.hw_key && |
151 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 150 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
152 | /* hwaccel - with no need for preallocated room for IV/ICV */ | 151 | /* hwaccel - with no need for software-generated IV */ |
153 | info->control.hw_key = &tx->key->conf; | ||
154 | return 0; | 152 | return 0; |
155 | } | 153 | } |
156 | 154 | ||
157 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 155 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
158 | len = skb->len - hdrlen; | 156 | len = skb->len - hdrlen; |
159 | 157 | ||
160 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 158 | if (info->control.hw_key) |
161 | tail = 0; | 159 | tail = 0; |
162 | else | 160 | else |
163 | tail = TKIP_ICV_LEN; | 161 | tail = TKIP_ICV_LEN; |
@@ -175,13 +173,11 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
175 | if (key->u.tkip.tx.iv16 == 0) | 173 | if (key->u.tkip.tx.iv16 == 0) |
176 | key->u.tkip.tx.iv32++; | 174 | key->u.tkip.tx.iv32++; |
177 | 175 | ||
178 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 176 | pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
179 | /* hwaccel - with preallocated room for IV */ | ||
180 | ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); | ||
181 | 177 | ||
182 | info->control.hw_key = &tx->key->conf; | 178 | /* hwaccel - with software IV */ |
179 | if (info->control.hw_key) | ||
183 | return 0; | 180 | return 0; |
184 | } | ||
185 | 181 | ||
186 | /* Add room for ICV */ | 182 | /* Add room for ICV */ |
187 | skb_put(skb, TKIP_ICV_LEN); | 183 | skb_put(skb, TKIP_ICV_LEN); |
@@ -216,6 +212,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
216 | int hdrlen, res, hwaccel = 0, wpa_test = 0; | 212 | int hdrlen, res, hwaccel = 0, wpa_test = 0; |
217 | struct ieee80211_key *key = rx->key; | 213 | struct ieee80211_key *key = rx->key; |
218 | struct sk_buff *skb = rx->skb; | 214 | struct sk_buff *skb = rx->skb; |
215 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
219 | 216 | ||
220 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 217 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
221 | 218 | ||
@@ -225,8 +222,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
225 | if (!rx->sta || skb->len - hdrlen < 12) | 222 | if (!rx->sta || skb->len - hdrlen < 12) |
226 | return RX_DROP_UNUSABLE; | 223 | return RX_DROP_UNUSABLE; |
227 | 224 | ||
228 | if (rx->status->flag & RX_FLAG_DECRYPTED) { | 225 | if (status->flag & RX_FLAG_DECRYPTED) { |
229 | if (rx->status->flag & RX_FLAG_IV_STRIPPED) { | 226 | if (status->flag & RX_FLAG_IV_STRIPPED) { |
230 | /* | 227 | /* |
231 | * Hardware took care of all processing, including | 228 | * Hardware took care of all processing, including |
232 | * replay protection, and stripped the ICV/IV so | 229 | * replay protection, and stripped the ICV/IV so |
@@ -362,24 +359,20 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
362 | int hdrlen, len, tail; | 359 | int hdrlen, len, tail; |
363 | u8 *pos, *pn; | 360 | u8 *pos, *pn; |
364 | int i; | 361 | int i; |
365 | bool skip_hw; | ||
366 | |||
367 | skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) && | ||
368 | ieee80211_is_mgmt(hdr->frame_control); | ||
369 | 362 | ||
370 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 363 | if (info->control.hw_key && |
371 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && | 364 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
372 | !skip_hw) { | 365 | /* |
373 | /* hwaccel - with no need for preallocated room for CCMP | 366 | * hwaccel has no need for preallocated room for CCMP |
374 | * header or MIC fields */ | 367 | * header or MIC fields |
375 | info->control.hw_key = &tx->key->conf; | 368 | */ |
376 | return 0; | 369 | return 0; |
377 | } | 370 | } |
378 | 371 | ||
379 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 372 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
380 | len = skb->len - hdrlen; | 373 | len = skb->len - hdrlen; |
381 | 374 | ||
382 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 375 | if (info->control.hw_key) |
383 | tail = 0; | 376 | tail = 0; |
384 | else | 377 | else |
385 | tail = CCMP_MIC_LEN; | 378 | tail = CCMP_MIC_LEN; |
@@ -404,11 +397,9 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
404 | 397 | ||
405 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); | 398 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); |
406 | 399 | ||
407 | if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) { | 400 | /* hwaccel - with software CCMP header */ |
408 | /* hwaccel - with preallocated room for CCMP header */ | 401 | if (info->control.hw_key) |
409 | info->control.hw_key = &tx->key->conf; | ||
410 | return 0; | 402 | return 0; |
411 | } | ||
412 | 403 | ||
413 | pos += CCMP_HDR_LEN; | 404 | pos += CCMP_HDR_LEN; |
414 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); | 405 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); |
@@ -442,6 +433,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
442 | int hdrlen; | 433 | int hdrlen; |
443 | struct ieee80211_key *key = rx->key; | 434 | struct ieee80211_key *key = rx->key; |
444 | struct sk_buff *skb = rx->skb; | 435 | struct sk_buff *skb = rx->skb; |
436 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
445 | u8 pn[CCMP_PN_LEN]; | 437 | u8 pn[CCMP_PN_LEN]; |
446 | int data_len; | 438 | int data_len; |
447 | 439 | ||
@@ -455,8 +447,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
455 | if (!rx->sta || data_len < 0) | 447 | if (!rx->sta || data_len < 0) |
456 | return RX_DROP_UNUSABLE; | 448 | return RX_DROP_UNUSABLE; |
457 | 449 | ||
458 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 450 | if ((status->flag & RX_FLAG_DECRYPTED) && |
459 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 451 | (status->flag & RX_FLAG_IV_STRIPPED)) |
460 | return RX_CONTINUE; | 452 | return RX_CONTINUE; |
461 | 453 | ||
462 | ccmp_hdr2pn(pn, skb->data + hdrlen); | 454 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
@@ -466,7 +458,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
466 | return RX_DROP_UNUSABLE; | 458 | return RX_DROP_UNUSABLE; |
467 | } | 459 | } |
468 | 460 | ||
469 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 461 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
470 | /* hardware didn't decrypt/verify MIC */ | 462 | /* hardware didn't decrypt/verify MIC */ |
471 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); | 463 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); |
472 | 464 | ||
@@ -523,11 +515,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) | |||
523 | u8 *pn, aad[20]; | 515 | u8 *pn, aad[20]; |
524 | int i; | 516 | int i; |
525 | 517 | ||
526 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 518 | if (info->control.hw_key) |
527 | /* hwaccel */ | ||
528 | info->control.hw_key = &tx->key->conf; | ||
529 | return 0; | 519 | return 0; |
530 | } | ||
531 | 520 | ||
532 | if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) | 521 | if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) |
533 | return TX_DROP; | 522 | return TX_DROP; |
@@ -563,6 +552,7 @@ ieee80211_rx_result | |||
563 | ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | 552 | ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) |
564 | { | 553 | { |
565 | struct sk_buff *skb = rx->skb; | 554 | struct sk_buff *skb = rx->skb; |
555 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
566 | struct ieee80211_key *key = rx->key; | 556 | struct ieee80211_key *key = rx->key; |
567 | struct ieee80211_mmie *mmie; | 557 | struct ieee80211_mmie *mmie; |
568 | u8 aad[20], mic[8], ipn[6]; | 558 | u8 aad[20], mic[8], ipn[6]; |
@@ -571,8 +561,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
571 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 561 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
572 | return RX_CONTINUE; | 562 | return RX_CONTINUE; |
573 | 563 | ||
574 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 564 | if ((status->flag & RX_FLAG_DECRYPTED) && |
575 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 565 | (status->flag & RX_FLAG_IV_STRIPPED)) |
576 | return RX_CONTINUE; | 566 | return RX_CONTINUE; |
577 | 567 | ||
578 | if (skb->len < 24 + sizeof(*mmie)) | 568 | if (skb->len < 24 + sizeof(*mmie)) |
@@ -591,7 +581,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
591 | return RX_DROP_UNUSABLE; | 581 | return RX_DROP_UNUSABLE; |
592 | } | 582 | } |
593 | 583 | ||
594 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 584 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
595 | /* hardware didn't decrypt/verify MIC */ | 585 | /* hardware didn't decrypt/verify MIC */ |
596 | bip_aad(skb, aad); | 586 | bip_aad(skb, aad); |
597 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, | 587 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, |