]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 May 2018 20:59:23 +0000 (13:59 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 May 2018 20:59:23 +0000 (13:59 -0700)
added patches:
ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch
ath10k-rebuild-crypto-header-in-rx-data-frames.patch
mac80211-add-rx-flag-to-indicate-icv-stripped.patch
mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch
mac80211-allow-same-pn-for-amsdu-sub-frames.patch

queue-4.4/ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch [new file with mode: 0644]
queue-4.4/ath10k-rebuild-crypto-header-in-rx-data-frames.patch [new file with mode: 0644]
queue-4.4/mac80211-add-rx-flag-to-indicate-icv-stripped.patch [new file with mode: 0644]
queue-4.4/mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch [new file with mode: 0644]
queue-4.4/mac80211-allow-same-pn-for-amsdu-sub-frames.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch b/queue-4.4/ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch
new file mode 100644 (file)
index 0000000..b2fbc66
--- /dev/null
@@ -0,0 +1,105 @@
+From 2f38c3c01de945234d23dd163e3528ccb413066d Mon Sep 17 00:00:00 2001
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Date: Mon, 26 Sep 2016 21:56:24 +0300
+Subject: ath10k: fix rfc1042 header retrieval in QCA4019 with eth decap mode
+
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+
+commit 2f38c3c01de945234d23dd163e3528ccb413066d upstream.
+
+Chipset from QCA99X0 onwards (QCA99X0, QCA9984, QCA4019 & future)
+rx_hdr_status is not padded to align in 4-byte boundary. Define a
+new hw_params field to handle different alignment behaviour between
+different hw. This patch fixes improper retrieval of rfc1042 header
+with QCA4019. This patch along with "ath10k: Properly remove padding
+from the start of rx payload" will fix traffic failure in ethernet
+decap mode for QCA4019.
+
+Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/ath/ath10k/core.c |    8 ++++++++
+ drivers/net/wireless/ath/ath10k/core.h |    4 ++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -67,6 +67,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA988X_BOARD_DATA_SZ,
+                       .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_2_1_VERSION,
+@@ -85,6 +86,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_2_1_VERSION,
+@@ -103,6 +105,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_3_0_VERSION,
+@@ -121,6 +124,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_3_2_VERSION,
+@@ -140,6 +144,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA99X0_HW_2_0_DEV_VERSION,
+@@ -159,6 +164,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA99X0_BOARD_DATA_SZ,
+                       .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 1,
+       },
+       {
+               .id = QCA9377_HW_1_0_DEV_VERSION,
+@@ -177,6 +183,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA9377_BOARD_DATA_SZ,
+                       .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -195,6 +202,7 @@ static const struct ath10k_hw_params ath
+                       .board_size = QCA9377_BOARD_DATA_SZ,
+                       .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+ };
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -670,6 +670,10 @@ struct ath10k {
+                       size_t board_size;
+                       size_t board_ext_size;
+               } fw;
++
++              /* Number of bytes used for alignment in rx_hdr_status */
++              int decap_align_bytes;
++
+       } hw_params;
+       const struct firmware *board;
diff --git a/queue-4.4/ath10k-rebuild-crypto-header-in-rx-data-frames.patch b/queue-4.4/ath10k-rebuild-crypto-header-in-rx-data-frames.patch
new file mode 100644 (file)
index 0000000..fe6fd8e
--- /dev/null
@@ -0,0 +1,284 @@
+From 7eccb738fce57cbe53ed903ccf43f9ab257b15b3 Mon Sep 17 00:00:00 2001
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Date: Fri, 27 Oct 2017 18:35:31 +0300
+Subject: ath10k: rebuild crypto header in rx data frames
+
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+
+commit 7eccb738fce57cbe53ed903ccf43f9ab257b15b3 upstream.
+
+Rx data frames notified through HTT_T2H_MSG_TYPE_RX_IND and
+HTT_T2H_MSG_TYPE_RX_FRAG_IND expect PN/TSC check to be done
+on host (mac80211) rather than firmware. Rebuild cipher header
+in every received data frames (that are notified through those
+HTT interfaces) from the rx_hdr_status tlv available in the
+rx descriptor of the first msdu. Skip setting RX_FLAG_IV_STRIPPED
+flag for the packets which requires mac80211 PN/TSC check support
+and set appropriate RX_FLAG for stripped crypto tail. Hw QCA988X,
+QCA9887, QCA99X0, QCA9984, QCA9888 and QCA4019 currently need the
+rebuilding of cipher header to perform PN/TSC check for replay
+attack.
+
+Please note that removing crypto tail for CCMP-256, GCMP and GCMP-256 ciphers
+in raw mode needs to be fixed. Since Rx with these ciphers in raw
+mode does not work in the current form even without this patch and
+removing crypto tail for these chipers needs clean up, raw mode related
+issues in CCMP-256, GCMP and GCMP-256 can be addressed in follow up
+patches.
+
+Tested-by: Manikanta Pubbisetty <mpubbise@qti.qualcomm.com>
+Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/ath/ath10k/htt_rx.c |   98 +++++++++++++++++++++++++------
+ 1 file changed, 82 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -1076,7 +1076,21 @@ static void ath10k_htt_rx_h_undecap_raw(
+       hdr = (void *)msdu->data;
+       /* Tail */
+-      skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      if (status->flag & RX_FLAG_IV_STRIPPED) {
++              skb_trim(msdu, msdu->len -
++                       ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      } else {
++              /* MIC */
++              if ((status->flag & RX_FLAG_MIC_STRIPPED) &&
++                  enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
++                      skb_trim(msdu, msdu->len - 8);
++
++              /* ICV */
++              if (status->flag & RX_FLAG_ICV_STRIPPED &&
++                  enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
++                      skb_trim(msdu, msdu->len -
++                               ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      }
+       /* MMIC */
+       if (!ieee80211_has_morefrags(hdr->frame_control) &&
+@@ -1095,12 +1109,14 @@ static void ath10k_htt_rx_h_undecap_raw(
+ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
+                                         struct sk_buff *msdu,
+                                         struct ieee80211_rx_status *status,
+-                                        const u8 first_hdr[64])
++                                        const u8 first_hdr[64],
++                                        enum htt_rx_mpdu_encrypt_type enctype)
+ {
+       struct ieee80211_hdr *hdr;
+       size_t hdr_len;
+       u8 da[ETH_ALEN];
+       u8 sa[ETH_ALEN];
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+       /* Delivered decapped frame:
+        * [nwifi 802.11 header] <-- replaced with 802.11 hdr
+@@ -1123,6 +1139,14 @@ static void ath10k_htt_rx_h_undecap_nwif
+       /* push original 802.11 header */
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+       /* original 802.11 header has a different DA and in
+@@ -1180,6 +1204,7 @@ static void ath10k_htt_rx_h_undecap_eth(
+       void *rfc1042;
+       u8 da[ETH_ALEN];
+       u8 sa[ETH_ALEN];
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+       /* Delivered decapped frame:
+        * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
+@@ -1203,6 +1228,14 @@ static void ath10k_htt_rx_h_undecap_eth(
+       /* push original 802.11 header */
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+       /* original 802.11 header has a different DA and in
+@@ -1216,10 +1249,12 @@ static void ath10k_htt_rx_h_undecap_eth(
+ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
+                                        struct sk_buff *msdu,
+                                        struct ieee80211_rx_status *status,
+-                                       const u8 first_hdr[64])
++                                       const u8 first_hdr[64],
++                                       enum htt_rx_mpdu_encrypt_type enctype)
+ {
+       struct ieee80211_hdr *hdr;
+       size_t hdr_len;
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+       /* Delivered decapped frame:
+        * [amsdu header] <-- replaced with 802.11 hdr
+@@ -1231,6 +1266,14 @@ static void ath10k_htt_rx_h_undecap_snap
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+ }
+@@ -1265,13 +1308,15 @@ static void ath10k_htt_rx_h_undecap(stru
+                                           is_decrypted);
+               break;
+       case RX_MSDU_DECAP_NATIVE_WIFI:
+-              ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr);
++              ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr,
++                                            enctype);
+               break;
+       case RX_MSDU_DECAP_ETHERNET2_DIX:
+               ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype);
+               break;
+       case RX_MSDU_DECAP_8023_SNAP_LLC:
+-              ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr);
++              ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr,
++                                           enctype);
+               break;
+       }
+ }
+@@ -1314,7 +1359,8 @@ static void ath10k_htt_rx_h_csum_offload
+ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
+                                struct sk_buff_head *amsdu,
+-                               struct ieee80211_rx_status *status)
++                               struct ieee80211_rx_status *status,
++                               bool fill_crypt_header)
+ {
+       struct sk_buff *first;
+       struct sk_buff *last;
+@@ -1324,7 +1370,6 @@ static void ath10k_htt_rx_h_mpdu(struct
+       enum htt_rx_mpdu_encrypt_type enctype;
+       u8 first_hdr[64];
+       u8 *qos;
+-      size_t hdr_len;
+       bool has_fcs_err;
+       bool has_crypto_err;
+       bool has_tkip_err;
+@@ -1345,15 +1390,17 @@ static void ath10k_htt_rx_h_mpdu(struct
+        * decapped header. It'll be used for undecapping of each MSDU.
+        */
+       hdr = (void *)rxd->rx_hdr_status;
+-      hdr_len = ieee80211_hdrlen(hdr->frame_control);
+-      memcpy(first_hdr, hdr, hdr_len);
++      memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
+       /* Each A-MSDU subframe will use the original header as the base and be
+        * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl.
+        */
+       hdr = (void *)first_hdr;
+-      qos = ieee80211_get_qos_ctl(hdr);
+-      qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
++
++      if (ieee80211_is_data_qos(hdr->frame_control)) {
++              qos = ieee80211_get_qos_ctl(hdr);
++              qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
++      }
+       /* Some attention flags are valid only in the last MSDU. */
+       last = skb_peek_tail(amsdu);
+@@ -1387,11 +1434,17 @@ static void ath10k_htt_rx_h_mpdu(struct
+       if (has_tkip_err)
+               status->flag |= RX_FLAG_MMIC_ERROR;
+-      if (is_decrypted)
++      if (is_decrypted) {
+               status->flag |= RX_FLAG_DECRYPTED |
+-                              RX_FLAG_IV_STRIPPED |
+                               RX_FLAG_MMIC_STRIPPED;
++              if (fill_crypt_header)
++                      status->flag |= RX_FLAG_MIC_STRIPPED |
++                                      RX_FLAG_ICV_STRIPPED;
++              else
++                      status->flag |= RX_FLAG_IV_STRIPPED;
++      }
++
+       skb_queue_walk(amsdu, msdu) {
+               ath10k_htt_rx_h_csum_offload(msdu);
+               ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype,
+@@ -1404,6 +1457,9 @@ static void ath10k_htt_rx_h_mpdu(struct
+               if (!is_decrypted)
+                       continue;
++              if (fill_crypt_header)
++                      continue;
++
+               hdr = (void *)msdu->data;
+               hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+       }
+@@ -1414,6 +1470,9 @@ static void ath10k_htt_rx_h_deliver(stru
+                                   struct ieee80211_rx_status *status)
+ {
+       struct sk_buff *msdu;
++      struct sk_buff *first_subframe;
++
++      first_subframe = skb_peek(amsdu);
+       while ((msdu = __skb_dequeue(amsdu))) {
+               /* Setup per-MSDU flags */
+@@ -1422,6 +1481,13 @@ static void ath10k_htt_rx_h_deliver(stru
+               else
+                       status->flag |= RX_FLAG_AMSDU_MORE;
++              if (msdu == first_subframe) {
++                      first_subframe = NULL;
++                      status->flag &= ~RX_FLAG_ALLOW_SAME_PN;
++              } else {
++                      status->flag |= RX_FLAG_ALLOW_SAME_PN;
++              }
++
+               ath10k_process_rx(ar, status, msdu);
+       }
+ }
+@@ -1607,7 +1673,7 @@ static void ath10k_htt_rx_handler(struct
+               ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
+               ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0);
+               ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
+-              ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
++              ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true);
+               ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status);
+       }
+@@ -1653,7 +1719,7 @@ static void ath10k_htt_rx_frag_handler(s
+       ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
+       ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
+-      ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
++      ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true);
+       ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status);
+       if (fw_desc_len > 0) {
+@@ -1952,7 +2018,7 @@ static void ath10k_htt_rx_in_ord_ind(str
+                        */
+                       ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
+                       ath10k_htt_rx_h_filter(ar, &amsdu, status);
+-                      ath10k_htt_rx_h_mpdu(ar, &amsdu, status);
++                      ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false);
+                       ath10k_htt_rx_h_deliver(ar, &amsdu, status);
+                       break;
+               case -EAGAIN:
diff --git a/queue-4.4/mac80211-add-rx-flag-to-indicate-icv-stripped.patch b/queue-4.4/mac80211-add-rx-flag-to-indicate-icv-stripped.patch
new file mode 100644 (file)
index 0000000..de674dc
--- /dev/null
@@ -0,0 +1,76 @@
+From cef0acd4d7d4811d2d19cd0195031bf0dfe41249 Mon Sep 17 00:00:00 2001
+From: David Spinadel <david.spinadel@intel.com>
+Date: Mon, 21 Nov 2016 16:58:40 +0200
+Subject: mac80211: Add RX flag to indicate ICV stripped
+
+From: David Spinadel <david.spinadel@intel.com>
+
+commit cef0acd4d7d4811d2d19cd0195031bf0dfe41249 upstream.
+
+Add a flag that indicates that the WEP ICV was stripped from an
+RX packet, allowing the device to not transfer that if it's
+already checked.
+
+Signed-off-by: David Spinadel <david.spinadel@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Cc: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h |    5 ++++-
+ net/mac80211/wep.c     |    3 ++-
+ net/mac80211/wpa.c     |    3 ++-
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -975,7 +975,7 @@ ieee80211_tx_info_clear_status(struct ie
+  * @RX_FLAG_DECRYPTED: This frame was decrypted in hardware.
+  * @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame,
+  *    verification has been done by the hardware.
+- * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame.
++ * @RX_FLAG_IV_STRIPPED: The IV and ICV are stripped from this frame.
+  *    If this flag is set, the stack cannot do any replay detection
+  *    hence the driver or hardware will have to do that.
+  * @RX_FLAG_PN_VALIDATED: Currently only valid for CCMP/GCMP frames, this
+@@ -1034,6 +1034,8 @@ ieee80211_tx_info_clear_status(struct ie
+  * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before.
+  *    This is used for AMSDU subframes which can have the same PN as
+  *    the first subframe.
++ * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must
++ *    be done in the hardware.
+  */
+ enum mac80211_rx_flags {
+       RX_FLAG_MMIC_ERROR              = BIT(0),
+@@ -1066,6 +1068,7 @@ enum mac80211_rx_flags {
+       RX_FLAG_RADIOTAP_VENDOR_DATA    = BIT(31),
+       RX_FLAG_MIC_STRIPPED            = BIT_ULL(32),
+       RX_FLAG_ALLOW_SAME_PN           = BIT_ULL(33),
++      RX_FLAG_ICV_STRIPPED            = BIT_ULL(34),
+ };
+ #define RX_FLAG_STBC_SHIFT            26
+--- a/net/mac80211/wep.c
++++ b/net/mac80211/wep.c
+@@ -293,7 +293,8 @@ ieee80211_crypto_wep_decrypt(struct ieee
+                       return RX_DROP_UNUSABLE;
+               ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
+               /* remove ICV */
+-              if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
++              if (!(status->flag & RX_FLAG_ICV_STRIPPED) &&
++                  pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
+                       return RX_DROP_UNUSABLE;
+       }
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -298,7 +298,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
+               return RX_DROP_UNUSABLE;
+       /* Trim ICV */
+-      skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
++      if (!(status->flag & RX_FLAG_ICV_STRIPPED))
++              skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
+       /* Remove IV */
+       memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
diff --git a/queue-4.4/mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch b/queue-4.4/mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch
new file mode 100644 (file)
index 0000000..993ddfe
--- /dev/null
@@ -0,0 +1,168 @@
+From f980ebc058c2fa2a552e495db1de0b330082ab70 Mon Sep 17 00:00:00 2001
+From: Sara Sharon <sara.sharon@intel.com>
+Date: Wed, 24 Feb 2016 11:49:45 +0200
+Subject: mac80211: allow not sending MIC up from driver for HW crypto
+
+From: Sara Sharon <sara.sharon@intel.com>
+
+commit f980ebc058c2fa2a552e495db1de0b330082ab70 upstream.
+
+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>
+Cc: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath10k/htt_rx.c |    2 +-
+ drivers/net/wireless/ath/wcn36xx/txrx.c  |    2 +-
+ include/net/mac80211.h                   |    5 ++++-
+ net/mac80211/util.c                      |    5 +++--
+ net/mac80211/wpa.c                       |   26 ++++++++++++++------------
+ 5 files changed, 23 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -979,7 +979,7 @@ static void ath10k_process_rx(struct ath
+       *status = *rx_status;
+       ath10k_dbg(ar, ATH10K_DBG_DATA,
+-                 "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
++                 "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
+                  skb,
+                  skb->len,
+                  ieee80211_get_SA(hdr),
+--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
++++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
+@@ -57,7 +57,7 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn,
+                      RX_FLAG_MMIC_STRIPPED |
+                      RX_FLAG_DECRYPTED;
+-      wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x\n", status.flag);
++      wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%llx\n", status.flag);
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1013,6 +1013,8 @@ ieee80211_tx_info_clear_status(struct ie
+  *    on this subframe
+  * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
+  *    is stored in the @ampdu_delimiter_crc field)
++ * @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was
++ *    done by the hardware
+  * @RX_FLAG_LDPC: LDPC was used
+  * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
+  * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
+@@ -1059,6 +1061,7 @@ enum mac80211_rx_flags {
+       RX_FLAG_5MHZ                    = BIT(29),
+       RX_FLAG_AMSDU_MORE              = BIT(30),
+       RX_FLAG_RADIOTAP_VENDOR_DATA    = BIT(31),
++      RX_FLAG_MIC_STRIPPED            = BIT_ULL(32),
+ };
+ #define RX_FLAG_STBC_SHIFT            26
+@@ -1113,7 +1116,7 @@ struct ieee80211_rx_status {
+       u64 mactime;
+       u32 device_timestamp;
+       u32 ampdu_reference;
+-      u32 flag;
++      u64 flag;
+       u16 freq;
+       u8 vht_flag;
+       u8 rate_idx;
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -2663,8 +2663,9 @@ u64 ieee80211_calculate_rx_timestamp(str
+       rate = cfg80211_calculate_bitrate(&ri);
+       if (WARN_ONCE(!rate,
+-                    "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
+-                    status->flag, status->rate_idx, status->vht_nss))
++                    "Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n",
++                    (unsigned long long)status->flag, status->rate_idx,
++                    status->vht_nss))
+               return 0;
+       /* rewind from end of MPDU */
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -508,18 +508,20 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+           !ieee80211_is_robust_mgmt_frame(skb))
+               return RX_CONTINUE;
+-      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
+-      if (!rx->sta || data_len < 0)
+-              return RX_DROP_UNUSABLE;
+-
+       if (status->flag & RX_FLAG_DECRYPTED) {
+               if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
+                       return RX_DROP_UNUSABLE;
++              if (status->flag & RX_FLAG_MIC_STRIPPED)
++                      mic_len = 0;
+       } else {
+               if (skb_linearize(rx->skb))
+                       return RX_DROP_UNUSABLE;
+       }
++      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
++      if (!rx->sta || data_len < 0)
++              return RX_DROP_UNUSABLE;
++
+       if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
+               ccmp_hdr2pn(pn, skb->data + hdrlen);
+@@ -724,8 +726,7 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+       struct sk_buff *skb = rx->skb;
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       u8 pn[IEEE80211_GCMP_PN_LEN];
+-      int data_len;
+-      int queue;
++      int data_len, queue, mic_len = IEEE80211_GCMP_MIC_LEN;
+       hdrlen = ieee80211_hdrlen(hdr->frame_control);
+@@ -733,19 +734,20 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+           !ieee80211_is_robust_mgmt_frame(skb))
+               return RX_CONTINUE;
+-      data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN -
+-                 IEEE80211_GCMP_MIC_LEN;
+-      if (!rx->sta || data_len < 0)
+-              return RX_DROP_UNUSABLE;
+-
+       if (status->flag & RX_FLAG_DECRYPTED) {
+               if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
+                       return RX_DROP_UNUSABLE;
++              if (status->flag & RX_FLAG_MIC_STRIPPED)
++                      mic_len = 0;
+       } else {
+               if (skb_linearize(rx->skb))
+                       return RX_DROP_UNUSABLE;
+       }
++      data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len;
++      if (!rx->sta || data_len < 0)
++              return RX_DROP_UNUSABLE;
++
+       if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
+               gcmp_hdr2pn(pn, skb->data + hdrlen);
+@@ -776,7 +778,7 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+       }
+       /* Remove GCMP header and MIC */
+-      if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN))
++      if (pskb_trim(skb, skb->len - mic_len))
+               return RX_DROP_UNUSABLE;
+       memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
+       skb_pull(skb, IEEE80211_GCMP_HDR_LEN);
diff --git a/queue-4.4/mac80211-allow-same-pn-for-amsdu-sub-frames.patch b/queue-4.4/mac80211-allow-same-pn-for-amsdu-sub-frames.patch
new file mode 100644 (file)
index 0000000..cce7d92
--- /dev/null
@@ -0,0 +1,88 @@
+From f631a77ba920f7153a1094d09cd8f2ebbffd0328 Mon Sep 17 00:00:00 2001
+From: Sara Sharon <sara.sharon@intel.com>
+Date: Tue, 3 May 2016 15:59:44 +0300
+Subject: mac80211: allow same PN for AMSDU sub-frames
+
+From: Sara Sharon <sara.sharon@intel.com>
+
+commit f631a77ba920f7153a1094d09cd8f2ebbffd0328 upstream.
+
+Some hardware (iwlwifi an example) de-aggregate AMSDUs and copy the IV
+as is to the generated MPDUs, so the same PN appears in multiple
+packets without being a replay attack.  Allow driver to explicitly
+indicate that a frame is allowed to have the same PN as the previous
+frame.
+
+Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Cc: Sriram R <srirrama@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h |    6 +++++-
+ net/mac80211/wpa.c     |   16 ++++++++++++----
+ 2 files changed, 17 insertions(+), 5 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1031,6 +1031,9 @@ ieee80211_tx_info_clear_status(struct ie
+  * @RX_FLAG_RADIOTAP_VENDOR_DATA: This frame contains vendor-specific
+  *    radiotap data in the skb->data (before the frame) as described by
+  *    the &struct ieee80211_vendor_radiotap.
++ * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before.
++ *    This is used for AMSDU subframes which can have the same PN as
++ *    the first subframe.
+  */
+ enum mac80211_rx_flags {
+       RX_FLAG_MMIC_ERROR              = BIT(0),
+@@ -1061,7 +1064,8 @@ enum mac80211_rx_flags {
+       RX_FLAG_5MHZ                    = BIT(29),
+       RX_FLAG_AMSDU_MORE              = BIT(30),
+       RX_FLAG_RADIOTAP_VENDOR_DATA    = BIT(31),
+-      RX_FLAG_MIC_STRIPPED            = BIT_ULL(32),
++      RX_FLAG_MIC_STRIPPED            = BIT_ULL(32),
++      RX_FLAG_ALLOW_SAME_PN           = BIT_ULL(33),
+ };
+ #define RX_FLAG_STBC_SHIFT            26
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -523,12 +523,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+               return RX_DROP_UNUSABLE;
+       if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
++              int res;
++
+               ccmp_hdr2pn(pn, skb->data + hdrlen);
+               queue = rx->security_idx;
+-              if (memcmp(pn, key->u.ccmp.rx_pn[queue],
+-                         IEEE80211_CCMP_PN_LEN) <= 0) {
++              res = memcmp(pn, key->u.ccmp.rx_pn[queue],
++                           IEEE80211_CCMP_PN_LEN);
++              if (res < 0 ||
++                  (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+                       key->u.ccmp.replays++;
+                       return RX_DROP_UNUSABLE;
+               }
+@@ -749,12 +753,16 @@ ieee80211_crypto_gcmp_decrypt(struct iee
+               return RX_DROP_UNUSABLE;
+       if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
++              int res;
++
+               gcmp_hdr2pn(pn, skb->data + hdrlen);
+               queue = rx->security_idx;
+-              if (memcmp(pn, key->u.gcmp.rx_pn[queue],
+-                         IEEE80211_GCMP_PN_LEN) <= 0) {
++              res = memcmp(pn, key->u.gcmp.rx_pn[queue],
++                           IEEE80211_GCMP_PN_LEN);
++              if (res < 0 ||
++                  (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+                       key->u.gcmp.replays++;
+                       return RX_DROP_UNUSABLE;
+               }
index 468c56f7c283c3e4d0d14cd13ae928211d84753d..d2945243aae59172f6d80e66297972bc47b101af 100644 (file)
@@ -263,3 +263,8 @@ regulator-of-add-a-missing-of_node_put-in-an-error-handling-path-of-of_regulator
 asoc-samsung-i2s-ensure-the-rclk-rate-is-properly-determined.patch
 bluetooth-btusb-add-device-id-for-rtl8822be.patch
 kdb-make-mdr-command-repeat.patch
+mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch
+mac80211-allow-same-pn-for-amsdu-sub-frames.patch
+mac80211-add-rx-flag-to-indicate-icv-stripped.patch
+ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch
+ath10k-rebuild-crypto-header-in-rx-data-frames.patch