From patchwork Mon Nov 24 02:37:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sujith Manoharan X-Patchwork-Id: 5362911 Return-Path: X-Original-To: patchwork-ath10k@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D62539FD26 for ; Mon, 24 Nov 2014 02:36:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E96C32034C for ; Mon, 24 Nov 2014 02:36:41 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EFEA0202FF for ; Mon, 24 Nov 2014 02:36:40 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XsjVm-0005Cr-8F; Mon, 24 Nov 2014 02:36:22 +0000 Received: from s72.web-hosting.com ([198.187.29.22]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XsjVi-00057j-Od for ath10k@lists.infradead.org; Mon, 24 Nov 2014 02:36:19 +0000 Received: from [117.199.133.57] (port=11530 helo=sujith-pixel.qualcomm.com) by server72.web-hosting.com with esmtpsa (UNKNOWN:AES128-SHA256:128) (Exim 4.82) (envelope-from ) id 1XsjVJ-001mW9-1w; Sun, 23 Nov 2014 21:35:53 -0500 From: Sujith Manoharan To: ath10k@lists.infradead.org Subject: [PATCH 1/3] ath10k: Fix shared WEP Date: Mon, 24 Nov 2014 08:07:35 +0530 Message-Id: <1416796657-24657-2-git-send-email-sujith@msujith.org> X-Mailer: git-send-email 2.1.3 In-Reply-To: <1416796657-24657-1-git-send-email-sujith@msujith.org> References: <1416796657-24657-1-git-send-email-sujith@msujith.org> X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server72.web-hosting.com X-AntiAbuse: Original Domain - lists.infradead.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - msujith.org X-Get-Message-Sender-Via: server72.web-hosting.com: authenticated_id: sujith@msujith.org X-Source: X-Source-Args: X-Source-Dir: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141123_183618_875867_003C905E X-CRM114-Status: GOOD ( 13.92 ) X-Spam-Score: 0.0 (/) Cc: linux-wireless@vger.kernel.org X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sujith Manoharan When static keys are used in shared WEP, when a station is associated, message 3 is sent with an encrypted payload. But, for subsequent authentications that are triggered without a deauth, the auth frame is decrypted by the HW. To handle this, check if the WEP keys have already been set for the peer and if so, mark the frame as decrypted. This scenario can happen when a station changes its default TX key and initiates a new authentication sequence. Signed-off-by: Sujith Manoharan --- drivers/net/wireless/ath/ath10k/mac.c | 23 +++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/mac.h | 2 ++ drivers/net/wireless/ath/ath10k/wmi.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 1245ac8..23116c2 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -179,6 +179,29 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif, return first_errno; } +bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr, + u8 keyidx) +{ + struct ath10k_peer *peer; + int i; + + /* We don't know which vdev this peer belongs to, + * since WMI doesn't give us that information. + * + * FIXME: multi-bss needs to be handled. + */ + peer = ath10k_peer_find(ar, 0, addr); + if (!peer) + return false; + + for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { + if (peer->keys[i] && peer->keys[i]->keyidx == keyidx) + return true; + } + + return false; +} + static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, struct ieee80211_key_conf *key) { diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index 4e3c989..cfa4d5d 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -41,6 +41,8 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work); void ath10k_halt(struct ath10k *ar); void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif); void ath10k_drain_tx(struct ath10k *ar); +bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr, + u8 keyidx); static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c2bc828..a12bba4 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1113,6 +1113,37 @@ static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band) return rate_idx; } +static void ath10k_wmi_handle_wep_reauth(struct ath10k *ar, + struct sk_buff *skb, + struct ieee80211_rx_status *status) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + unsigned int hdrlen; + bool peer_key; + u8 *addr, keyidx; + + if (!ieee80211_is_auth(hdr->frame_control) || + !ieee80211_has_protected(hdr->frame_control)) + return; + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + if (skb->len < (hdrlen + IEEE80211_WEP_IV_LEN)) + return; + + keyidx = skb->data[hdrlen + 3] >> 6; + addr = ieee80211_get_SA(hdr); + + spin_lock_bh(&ar->data_lock); + peer_key = ath10k_mac_is_peer_wep_key_set(ar, addr, keyidx); + spin_unlock_bh(&ar->data_lock); + + if (peer_key) { + ath10k_dbg(ar, ATH10K_DBG_MAC, + "wep key present for peer: %pM\n", addr); + status->flag |= RX_FLAG_DECRYPTED; + } +} + static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) { struct wmi_mgmt_rx_event_v1 *ev_v1; @@ -1200,6 +1231,8 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); + ath10k_wmi_handle_wep_reauth(ar, skb, status); + /* FW delivers WEP Shared Auth frame with Protected Bit set and * encrypted payload. However in case of PMF it delivers decrypted * frames with Protected Bit set. */