aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2016-02-24 04:49:45 -0500
committerJohannes Berg <johannes.berg@intel.com>2016-04-05 04:48:56 -0400
commitf980ebc058c2fa2a552e495db1de0b330082ab70 (patch)
treeaa224a4750de5e222ea022eab28b146921ba9679 /net/mac80211
parent162dd6a7253ab009c6335c21ce6b80cf227ddda4 (diff)
mac80211: allow not sending MIC up from driver for HW crypto
When HW crypto is used, there's no need for the CCMP/GCMP MIC to be available to mac80211, and the hardware might have removed it already after checking. The MIC is also useless to have when the frame is already decrypted, so allow indicating that it's not present. Since we are running out of bits in mac80211_rx_flags, make the flags field a u64. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/util.c5
-rw-r--r--net/mac80211/wpa.c26
2 files changed, 17 insertions, 14 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7390de4946a9..0319d6d4f863 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2724,8 +2724,9 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2724 2724
2725 rate = cfg80211_calculate_bitrate(&ri); 2725 rate = cfg80211_calculate_bitrate(&ri);
2726 if (WARN_ONCE(!rate, 2726 if (WARN_ONCE(!rate,
2727 "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n", 2727 "Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n",
2728 status->flag, status->rate_idx, status->vht_nss)) 2728 (unsigned long long)status->flag, status->rate_idx,
2729 status->vht_nss))
2729 return 0; 2730 return 0;
2730 2731
2731 /* rewind from end of MPDU */ 2732 /* rewind from end of MPDU */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 18848258adde..7e4f2652bca7 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -504,18 +504,20 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
504 !ieee80211_is_robust_mgmt_frame(skb)) 504 !ieee80211_is_robust_mgmt_frame(skb))
505 return RX_CONTINUE; 505 return RX_CONTINUE;
506 506
507 data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
508 if (!rx->sta || data_len < 0)
509 return RX_DROP_UNUSABLE;
510
511 if (status->flag & RX_FLAG_DECRYPTED) { 507 if (status->flag & RX_FLAG_DECRYPTED) {
512 if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN)) 508 if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
513 return RX_DROP_UNUSABLE; 509 return RX_DROP_UNUSABLE;
510 if (status->flag & RX_FLAG_MIC_STRIPPED)
511 mic_len = 0;
514 } else { 512 } else {
515 if (skb_linearize(rx->skb)) 513 if (skb_linearize(rx->skb))
516 return RX_DROP_UNUSABLE; 514 return RX_DROP_UNUSABLE;
517 } 515 }
518 516
517 data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
518 if (!rx->sta || data_len < 0)
519 return RX_DROP_UNUSABLE;
520
519 if (!(status->flag & RX_FLAG_PN_VALIDATED)) { 521 if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
520 ccmp_hdr2pn(pn, skb->data + hdrlen); 522 ccmp_hdr2pn(pn, skb->data + hdrlen);
521 523
@@ -720,8 +722,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
720 struct sk_buff *skb = rx->skb; 722 struct sk_buff *skb = rx->skb;
721 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 723 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
722 u8 pn[IEEE80211_GCMP_PN_LEN]; 724 u8 pn[IEEE80211_GCMP_PN_LEN];
723 int data_len; 725 int data_len, queue, mic_len = IEEE80211_GCMP_MIC_LEN;
724 int queue;
725 726
726 hdrlen = ieee80211_hdrlen(hdr->frame_control); 727 hdrlen = ieee80211_hdrlen(hdr->frame_control);
727 728
@@ -729,19 +730,20 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
729 !ieee80211_is_robust_mgmt_frame(skb)) 730 !ieee80211_is_robust_mgmt_frame(skb))
730 return RX_CONTINUE; 731 return RX_CONTINUE;
731 732
732 data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN -
733 IEEE80211_GCMP_MIC_LEN;
734 if (!rx->sta || data_len < 0)
735 return RX_DROP_UNUSABLE;
736
737 if (status->flag & RX_FLAG_DECRYPTED) { 733 if (status->flag & RX_FLAG_DECRYPTED) {
738 if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN)) 734 if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
739 return RX_DROP_UNUSABLE; 735 return RX_DROP_UNUSABLE;
736 if (status->flag & RX_FLAG_MIC_STRIPPED)
737 mic_len = 0;
740 } else { 738 } else {
741 if (skb_linearize(rx->skb)) 739 if (skb_linearize(rx->skb))
742 return RX_DROP_UNUSABLE; 740 return RX_DROP_UNUSABLE;
743 } 741 }
744 742
743 data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len;
744 if (!rx->sta || data_len < 0)
745 return RX_DROP_UNUSABLE;
746
745 if (!(status->flag & RX_FLAG_PN_VALIDATED)) { 747 if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
746 gcmp_hdr2pn(pn, skb->data + hdrlen); 748 gcmp_hdr2pn(pn, skb->data + hdrlen);
747 749
@@ -772,7 +774,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
772 } 774 }
773 775
774 /* Remove GCMP header and MIC */ 776 /* Remove GCMP header and MIC */
775 if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN)) 777 if (pskb_trim(skb, skb->len - mic_len))
776 return RX_DROP_UNUSABLE; 778 return RX_DROP_UNUSABLE;
777 memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen); 779 memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
778 skb_pull(skb, IEEE80211_GCMP_HDR_LEN); 780 skb_pull(skb, IEEE80211_GCMP_HDR_LEN);