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.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 96b65c240109..ae654de9782a 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -394,7 +394,8 @@ static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr)
394} 394}
395 395
396 396
397static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) 397static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
398 unsigned int mic_len)
398{ 399{
399 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 400 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
400 struct ieee80211_key *key = tx->key; 401 struct ieee80211_key *key = tx->key;
@@ -425,7 +426,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
425 if (info->control.hw_key) 426 if (info->control.hw_key)
426 tail = 0; 427 tail = 0;
427 else 428 else
428 tail = IEEE80211_CCMP_MIC_LEN; 429 tail = mic_len;
429 430
430 if (WARN_ON(skb_tailroom(skb) < tail || 431 if (WARN_ON(skb_tailroom(skb) < tail ||
431 skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN)) 432 skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
@@ -460,21 +461,22 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
460 pos += IEEE80211_CCMP_HDR_LEN; 461 pos += IEEE80211_CCMP_HDR_LEN;
461 ccmp_special_blocks(skb, pn, b_0, aad); 462 ccmp_special_blocks(skb, pn, b_0, aad);
462 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, 463 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
463 skb_put(skb, IEEE80211_CCMP_MIC_LEN)); 464 skb_put(skb, mic_len), mic_len);
464 465
465 return 0; 466 return 0;
466} 467}
467 468
468 469
469ieee80211_tx_result 470ieee80211_tx_result
470ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) 471ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
472 unsigned int mic_len)
471{ 473{
472 struct sk_buff *skb; 474 struct sk_buff *skb;
473 475
474 ieee80211_tx_set_protected(tx); 476 ieee80211_tx_set_protected(tx);
475 477
476 skb_queue_walk(&tx->skbs, skb) { 478 skb_queue_walk(&tx->skbs, skb) {
477 if (ccmp_encrypt_skb(tx, skb) < 0) 479 if (ccmp_encrypt_skb(tx, skb, mic_len) < 0)
478 return TX_DROP; 480 return TX_DROP;
479 } 481 }
480 482
@@ -483,7 +485,8 @@ ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
483 485
484 486
485ieee80211_rx_result 487ieee80211_rx_result
486ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) 488ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
489 unsigned int mic_len)
487{ 490{
488 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 491 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
489 int hdrlen; 492 int hdrlen;
@@ -500,8 +503,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
500 !ieee80211_is_robust_mgmt_frame(skb)) 503 !ieee80211_is_robust_mgmt_frame(skb))
501 return RX_CONTINUE; 504 return RX_CONTINUE;
502 505
503 data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - 506 data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
504 IEEE80211_CCMP_MIC_LEN;
505 if (!rx->sta || data_len < 0) 507 if (!rx->sta || data_len < 0)
506 return RX_DROP_UNUSABLE; 508 return RX_DROP_UNUSABLE;
507 509
@@ -532,14 +534,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
532 key->u.ccmp.tfm, b_0, aad, 534 key->u.ccmp.tfm, b_0, aad,
533 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, 535 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
534 data_len, 536 data_len,
535 skb->data + skb->len - IEEE80211_CCMP_MIC_LEN)) 537 skb->data + skb->len - mic_len, mic_len))
536 return RX_DROP_UNUSABLE; 538 return RX_DROP_UNUSABLE;
537 } 539 }
538 540
539 memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); 541 memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
540 542
541 /* Remove CCMP header and MIC */ 543 /* Remove CCMP header and MIC */
542 if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN)) 544 if (pskb_trim(skb, skb->len - mic_len))
543 return RX_DROP_UNUSABLE; 545 return RX_DROP_UNUSABLE;
544 memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen); 546 memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
545 skb_pull(skb, IEEE80211_CCMP_HDR_LEN); 547 skb_pull(skb, IEEE80211_CCMP_HDR_LEN);