From patchwork Fri Apr 26 06:41:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kalle Valo X-Patchwork-Id: 10918349 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 11AB614C0 for ; Fri, 26 Apr 2019 06:41:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 00F6828AB9 for ; Fri, 26 Apr 2019 06:41:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E9B4A28DA9; Fri, 26 Apr 2019 06:41:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8110828B61 for ; Fri, 26 Apr 2019 06:41:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=MFK/O2QBwRVjAq9KTCd4oPECqHUCySHRziRTLXGX/ls=; b=OSbwO7j8fqEV00Ju0vUvl3boT3 ELesGJOT20XqOEtfsS7PuO7TSxTvt3+oaSROthMMOuJDHlL8sdsy4iUrFUjABuLSQj6CvWn1YhOwf p0HiUJv7n9OK8S98tq0FROd5gNZAYWWEhDngO85zRqyFF7I1Lw3H8Pon92eys6rfuuc63tHtB6Ixh cAG0owRYdw6/hVyWnXx4iDTmig1stiJtLfdF2G+qzvnRtBZHmG7/ZwCaTkT7AaJKO5i9mVAiYBgqP f2t2U4zlfqYsCn2R6ZZwhtHJwVHIbUtgHldC9oRAOPND1nmf1OUEONfyT4KwymdSTp5IqdapwYj5P wC4qeCBg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hJuY3-0007hV-Qb; Fri, 26 Apr 2019 06:41:27 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hJuXx-0007ZH-Re for ath10k@lists.infradead.org; Fri, 26 Apr 2019 06:41:25 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 8BBCF6081E; Fri, 26 Apr 2019 06:41:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1556260881; bh=B6AQg1vhvoLoMjqUcNaqmn4deeKFkAKe+6ovhnH0yxs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OevX3z8JX0VIhvfkYdvGMYIGRPMEDpSC0Vh61tTI0ImvSeJMqXTSLI3HQSgJrfT98 nLBcmCtsucDLnx88zNtD5gyI76daplnDLnv0tJENHoSZQXQfB4jiOCsJMfDHsAprVJ fTDFtvO0gbhd5G2MHGADTh5isHsOmL6REuBk6Wxw= Received: from potku.adurom.net (88-114-240-156.elisa-laajakaista.fi [88.114.240.156]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: kvalo@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id CA24A607CA; Fri, 26 Apr 2019 06:41:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1556260881; bh=B6AQg1vhvoLoMjqUcNaqmn4deeKFkAKe+6ovhnH0yxs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OevX3z8JX0VIhvfkYdvGMYIGRPMEDpSC0Vh61tTI0ImvSeJMqXTSLI3HQSgJrfT98 nLBcmCtsucDLnx88zNtD5gyI76daplnDLnv0tJENHoSZQXQfB4jiOCsJMfDHsAprVJ fTDFtvO0gbhd5G2MHGADTh5isHsOmL6REuBk6Wxw= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org CA24A607CA Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=kvalo@codeaurora.org From: Kalle Valo To: ath10k@lists.infradead.org Subject: [PATCH 3/5] ath10k: add PN replay protection for high latency devices Date: Fri, 26 Apr 2019 09:41:09 +0300 Message-Id: <1556260871-2919-4-git-send-email-kvalo@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1556260871-2919-1-git-send-email-kvalo@codeaurora.org> References: <1556260871-2919-1-git-send-email-kvalo@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190425_234122_175940_86ED0569 X-CRM114-Status: GOOD ( 14.78 ) X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-wireless@vger.kernel.org, Wen Gong MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wen Gong On high latency devices (SDIO, USB) ath10k did not do PN replay check, a data frame with an invalid PN number was not discard as it should have been. So this patch implements PN replay in ath10k. PN replay check for fragmented frames is implemented in followup patch. With low latency devices (PCI, AHB) hardware can store the data frames's content to host memory directly and the firmware can fully reorder data frames, and do PN replay check at the same time. But for high latency devices all data frames will be received and stored in firmware's memory and it is hard to do full reorder because of the memory size limitations in the firmware. This is why the PN replay protections needs to be implemented in host driver. Tested on QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00007-QCARMSWP-1. Signed-off-by: Wen Gong Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 97 +++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index cc2875d73bf0..961e14633320 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -2061,9 +2061,91 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) return 0; } +static void ath10k_htt_rx_mpdu_desc_pn_hl(struct htt_hl_rx_desc *rx_desc, + union htt_rx_pn_t *pn, + int pn_len_bits) +{ + switch (pn_len_bits) { + case 48: + pn->pn48 = __le32_to_cpu(rx_desc->pn_31_0) + + ((u64)(__le32_to_cpu(rx_desc->u0.pn_63_32) & 0xFFFF) << 32); + break; + case 24: + pn->pn24 = __le32_to_cpu(rx_desc->pn_31_0); + break; + }; +} + +static bool ath10k_htt_rx_pn_cmp48(union htt_rx_pn_t *new_pn, + union htt_rx_pn_t *old_pn) +{ + return ((new_pn->pn48 & 0xffffffffffffULL) <= + (old_pn->pn48 & 0xffffffffffffULL)); +} + +static bool ath10k_htt_rx_pn_check_replay_hl(struct ath10k *ar, + struct ath10k_peer *peer, + struct htt_rx_indication_hl *rx) +{ + bool last_pn_valid, pn_invalid = false; + enum htt_txrx_sec_cast_type sec_index; + enum htt_security_types sec_type; + union htt_rx_pn_t new_pn = {0}; + struct htt_hl_rx_desc *rx_desc; + union htt_rx_pn_t *last_pn; + u32 rx_desc_info, tid; + int num_mpdu_ranges; + + lockdep_assert_held(&ar->data_lock); + + if (!peer) + return false; + + if (!(rx->fw_desc.flags & FW_RX_DESC_FLAGS_FIRST_MSDU)) + return false; + + num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1), + HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); + + rx_desc = (struct htt_hl_rx_desc *)&rx->mpdu_ranges[num_mpdu_ranges]; + rx_desc_info = __le32_to_cpu(rx_desc->info); + + if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) + return false; + + tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID); + last_pn_valid = peer->tids_last_pn_valid[tid]; + last_pn = &peer->tids_last_pn[tid]; + + if (MS(rx_desc_info, HTT_RX_DESC_HL_INFO_MCAST_BCAST)) + sec_index = HTT_TXRX_SEC_MCAST; + else + sec_index = HTT_TXRX_SEC_UCAST; + + sec_type = peer->rx_pn[sec_index].sec_type; + ath10k_htt_rx_mpdu_desc_pn_hl(rx_desc, &new_pn, peer->rx_pn[sec_index].pn_len); + + if (sec_type != HTT_SECURITY_AES_CCMP && + sec_type != HTT_SECURITY_TKIP && + sec_type != HTT_SECURITY_TKIP_NOMIC) + return false; + + if (last_pn_valid) + pn_invalid = ath10k_htt_rx_pn_cmp48(&new_pn, last_pn); + else + peer->tids_last_pn_valid[tid] = 1; + + if (!pn_invalid) + last_pn->pn48 = new_pn.pn48; + + return pn_invalid; +} + static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt, struct htt_rx_indication_hl *rx, - struct sk_buff *skb) + struct sk_buff *skb, + enum htt_rx_pn_check_type check_pn_type, + enum htt_rx_tkip_demic_type tkip_mic_type) { struct ath10k *ar = htt->ar; struct ath10k_peer *peer; @@ -2107,6 +2189,10 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt, goto err; } + if (check_pn_type == HTT_RX_PN_CHECK && + ath10k_htt_rx_pn_check_replay_hl(ar, peer, rx)) + goto err; + /* Strip off all headers before the MAC header before delivery to * mac80211 */ @@ -2114,6 +2200,7 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt, sizeof(rx->ppdu) + sizeof(rx->prefix) + sizeof(rx->fw_desc) + sizeof(*mpdu_ranges) * num_mpdu_ranges + rx_desc_len; + skb_pull(skb, tot_hdr_len); hdr = (struct ieee80211_hdr *)skb->data; @@ -2162,6 +2249,10 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt, RX_FLAG_MMIC_STRIPPED; } + if (tkip_mic_type == HTT_RX_TKIP_MIC) + rx_status->flag &= ~RX_FLAG_IV_STRIPPED & + ~RX_FLAG_MMIC_STRIPPED; + ieee80211_rx_ni(ar->hw, skb); /* We have delivered the skb to the upper layers (mac80211) so we @@ -3343,7 +3434,9 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, - skb); + skb, + HTT_RX_PN_CHECK, + HTT_RX_NON_TKIP_MIC); else ath10k_htt_rx_proc_rx_ind_ll(htt, &resp->rx_ind); break;