From 080b4a6084b900e139df0b32d92333a835d493a3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 May 2018 13:59:23 -0700 Subject: [PATCH] 4.4-stable patches 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 --- ...ieval-in-qca4019-with-eth-decap-mode.patch | 105 +++++++ ...uild-crypto-header-in-rx-data-frames.patch | 284 ++++++++++++++++++ ...add-rx-flag-to-indicate-icv-stripped.patch | 76 +++++ ...ing-mic-up-from-driver-for-hw-crypto.patch | 168 +++++++++++ ...1-allow-same-pn-for-amsdu-sub-frames.patch | 88 ++++++ queue-4.4/series | 5 + 6 files changed, 726 insertions(+) create mode 100644 queue-4.4/ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch create mode 100644 queue-4.4/ath10k-rebuild-crypto-header-in-rx-data-frames.patch create mode 100644 queue-4.4/mac80211-add-rx-flag-to-indicate-icv-stripped.patch create mode 100644 queue-4.4/mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch create mode 100644 queue-4.4/mac80211-allow-same-pn-for-amsdu-sub-frames.patch 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 index 00000000000..b2fbc66994d --- /dev/null +++ b/queue-4.4/ath10k-fix-rfc1042-header-retrieval-in-qca4019-with-eth-decap-mode.patch @@ -0,0 +1,105 @@ +From 2f38c3c01de945234d23dd163e3528ccb413066d Mon Sep 17 00:00:00 2001 +From: Vasanthakumar Thiagarajan +Date: Mon, 26 Sep 2016 21:56:24 +0300 +Subject: ath10k: fix rfc1042 header retrieval in QCA4019 with eth decap mode + +From: Vasanthakumar Thiagarajan + +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 +Signed-off-by: Kalle Valo +Signed-off-by: Sriram R +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..fe6fd8ef911 --- /dev/null +++ b/queue-4.4/ath10k-rebuild-crypto-header-in-rx-data-frames.patch @@ -0,0 +1,284 @@ +From 7eccb738fce57cbe53ed903ccf43f9ab257b15b3 Mon Sep 17 00:00:00 2001 +From: Vasanthakumar Thiagarajan +Date: Fri, 27 Oct 2017 18:35:31 +0300 +Subject: ath10k: rebuild crypto header in rx data frames + +From: Vasanthakumar Thiagarajan + +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 +Signed-off-by: Vasanthakumar Thiagarajan +Signed-off-by: Kalle Valo +Signed-off-by: Sriram R +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..de674dc4ae2 --- /dev/null +++ b/queue-4.4/mac80211-add-rx-flag-to-indicate-icv-stripped.patch @@ -0,0 +1,76 @@ +From cef0acd4d7d4811d2d19cd0195031bf0dfe41249 Mon Sep 17 00:00:00 2001 +From: David Spinadel +Date: Mon, 21 Nov 2016 16:58:40 +0200 +Subject: mac80211: Add RX flag to indicate ICV stripped + +From: David Spinadel + +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 +Signed-off-by: Johannes Berg +Cc: Sriram R +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..993ddfe7a53 --- /dev/null +++ b/queue-4.4/mac80211-allow-not-sending-mic-up-from-driver-for-hw-crypto.patch @@ -0,0 +1,168 @@ +From f980ebc058c2fa2a552e495db1de0b330082ab70 Mon Sep 17 00:00:00 2001 +From: Sara Sharon +Date: Wed, 24 Feb 2016 11:49:45 +0200 +Subject: mac80211: allow not sending MIC up from driver for HW crypto + +From: Sara Sharon + +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 +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Cc: Sriram R +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cce7d92df8e --- /dev/null +++ b/queue-4.4/mac80211-allow-same-pn-for-amsdu-sub-frames.patch @@ -0,0 +1,88 @@ +From f631a77ba920f7153a1094d09cd8f2ebbffd0328 Mon Sep 17 00:00:00 2001 +From: Sara Sharon +Date: Tue, 3 May 2016 15:59:44 +0300 +Subject: mac80211: allow same PN for AMSDU sub-frames + +From: Sara Sharon + +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 +Signed-off-by: Luca Coelho +Signed-off-by: Johannes Berg +Cc: Sriram R +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.4/series b/queue-4.4/series index 468c56f7c28..d2945243aae 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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 -- 2.47.3