diff options
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 22 |
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 | ||
397 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | 397 | static 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 | ||
469 | ieee80211_tx_result | 470 | ieee80211_tx_result |
470 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | 471 | ieee80211_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 | ||
485 | ieee80211_rx_result | 487 | ieee80211_rx_result |
486 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | 488 | ieee80211_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); |