mac80211: backport fixes for fix for CVE-2017-13080

This commit is contained in:
coolsnowwolf 2017-10-27 11:25:49 +08:00
parent 791acd01bb
commit 457fcc005a
6 changed files with 235 additions and 236 deletions

View File

@ -24,7 +24,7 @@ PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_DRIVERS = \
adm8211 \
airo \
ath ath5k ath9k ath9k-common ath9k-htc ath10k \
ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k \
b43 b43legacy \
carl9170 \
hermes hermes-pci hermes-pcmcia hermes-plx\
@ -217,6 +217,43 @@ define KernelPackage/ath5k/description
Atheros 5xxx chipset.
endef
define KernelPackage/ath6kl
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros FullMAC wireless devices (common code for ath6kl_sdio and ath6kl_usb)
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl
HIDDEN:=1
DEPENDS+= +kmod-ath +@DRIVER_11N_SUPPORT +@KERNEL_RELAY
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_core.ko
endef
define KernelPackage/ath6kl-sdio
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n SDIO wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl
DEPENDS+= +kmod-mmc +kmod-ath6kl
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_sdio.ko
AUTOLOAD:=$(call AutoProbe,ath6kl_sdio)
endef
define KernelPackage/ath6kl-sdio/description
This module adds support for wireless adapters based on
Atheros IEEE 802.11n AR6003 and AR6004 family of chipsets.
endef
define KernelPackage/ath6kl-usb
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n USB wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-ath6kl
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_usb.ko
AUTOLOAD:=$(call AutoProbe,ath6kl_usb)
endef
define KernelPackage/ath6kl-usb/description
This module adds support for wireless adapters based on the
Atheros IEEE 802.11n AR6004 chipset.
endef
define KernelPackage/ath9k-common
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc)
@ -1513,7 +1550,8 @@ ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS
ATH9K_HTC_DEBUGFS \
ATH10K_DEBUGFS \
CARL9170_DEBUGFS \
ATH5K_DEBUG
ATH5K_DEBUG \
ATH6KL_DEBUG
endif
ifdef CONFIG_PACKAGE_MAC80211_TRACING
@ -1554,6 +1592,10 @@ else
config-y += ATH5K_PCI
endif
config-$(call config_package,ath6kl) += ATH6KL
config-$(call config_package,ath6kl-sdio) += ATH6KL_SDIO
config-$(call config_package,ath6kl-usb) += ATH6KL_USB
config-$(call config_package,carl9170) += CARL9170
config-$(call config_package,b43) += B43
@ -1795,6 +1837,9 @@ $(eval $(call KernelPackage,airo))
$(eval $(call KernelPackage,ath))
$(eval $(call KernelPackage,ath10k))
$(eval $(call KernelPackage,ath5k))
$(eval $(call KernelPackage,ath6kl))
$(eval $(call KernelPackage,ath6kl-sdio))
$(eval $(call KernelPackage,ath6kl-usb))
$(eval $(call KernelPackage,ath9k))
$(eval $(call KernelPackage,ath9k-common))
$(eval $(call KernelPackage,ath9k-htc))

View File

@ -116,6 +116,7 @@ detect_mac80211() {
set wireless.radio${devidx}.hwmode=11${mode_band}
${dev_id}
${ht_capab}
set wireless.radio${devidx}.disabled=0
set wireless.default_radio${devidx}=wifi-iface
set wireless.default_radio${devidx}.device=radio${devidx}

View File

@ -0,0 +1,81 @@
From fdf7cb4185b60c68e1a75e61691c4afdc15dea0e Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg@intel.com>
Date: Tue, 5 Sep 2017 14:54:54 +0200
Subject: [PATCH] mac80211: accept key reinstall without changing anything
When a key is reinstalled we can reset the replay counters
etc. which can lead to nonce reuse and/or replay detection
being impossible, breaking security properties, as described
in the "KRACK attacks".
In particular, CVE-2017-13080 applies to GTK rekeying that
happened in firmware while the host is in D3, with the second
part of the attack being done after the host wakes up. In
this case, the wpa_supplicant mitigation isn't sufficient
since wpa_supplicant doesn't know the GTK material.
In case this happens, simply silently accept the new key
coming from userspace but don't take any action on it since
it's the same key; this keeps the PN replay counters intact.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/key.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index a98fc2b5e0dc..ae995c8480db 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -4,7 +4,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright 2015 Intel Deutschland GmbH
+ * Copyright 2015-2017 Intel Deutschland GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -620,9 +620,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
idx = key->conf.keyidx;
- key->local = sdata->local;
- key->sdata = sdata;
- key->sta = sta;
mutex_lock(&sdata->local->key_mtx);
@@ -633,6 +630,21 @@ int ieee80211_key_link(struct ieee80211_key *key,
else
old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
+ /*
+ * Silently accept key re-installation without really installing the
+ * new version of the key to avoid nonce reuse or replay issues.
+ */
+ if (old_key && key->conf.keylen == old_key->conf.keylen &&
+ !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) {
+ ieee80211_key_free_unused(key);
+ ret = 0;
+ goto out;
+ }
+
+ key->local = sdata->local;
+ key->sdata = sdata;
+ key->sta = sta;
+
increment_tailroom_need_count(sdata);
ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
@@ -648,6 +660,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
ret = 0;
}
+ out:
mutex_unlock(&sdata->local->key_mtx);
return ret;
--
2.13.6

View File

@ -0,0 +1,33 @@
From 2bdd713b92a9cade239d3c7d15205a09f556624d Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
Date: Tue, 17 Oct 2017 20:32:07 +0200
Subject: [PATCH] mac80211: use constant time comparison with keys
Otherwise we risk leaking information via timing side channel.
Fixes: fdf7cb4185b6 ("mac80211: accept key reinstall without changing anything")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/key.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <net/mac80211.h>
+#include <crypto/algapi.h>
#include <asm/unaligned.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
@@ -635,7 +636,7 @@ int ieee80211_key_link(struct ieee80211_
* new version of the key to avoid nonce reuse or replay issues.
*/
if (old_key && key->conf.keylen == old_key->conf.keylen &&
- !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) {
+ !crypto_memneq(key->conf.key, old_key->conf.key, key->conf.keylen)) {
ieee80211_key_free_unused(key);
ret = 0;
goto out;

View File

@ -0,0 +1,73 @@
From cfbb0d90a7abb289edc91833d0905931f8805f12 Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg@intel.com>
Date: Tue, 24 Oct 2017 21:12:13 +0200
Subject: [PATCH] mac80211: don't compare TKIP TX MIC key in reinstall prevention
For the reinstall prevention, the code I had added compares the
whole key. It turns out though that iwlwifi firmware doesn't
provide the TKIP TX MIC key as it's not needed in client mode,
and thus the comparison will always return false.
For client mode, thus always zero out the TX MIC key part before
doing the comparison in order to avoid accepting the reinstall
of the key with identical encryption and RX MIC key, but not the
same TX MIC key (since the supplicant provides the real one.)
Fixes: fdf7cb4185b6 ("mac80211: accept key reinstall without changing anything")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/key.c | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -610,6 +610,39 @@ void ieee80211_key_free_unused(struct ie
ieee80211_key_free_common(key);
}
+static bool ieee80211_key_identical(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_key *old,
+ struct ieee80211_key *new)
+{
+ u8 tkip_old[WLAN_KEY_LEN_TKIP], tkip_new[WLAN_KEY_LEN_TKIP];
+ u8 *tk_old, *tk_new;
+
+ if (!old || new->conf.keylen != old->conf.keylen)
+ return false;
+
+ tk_old = old->conf.key;
+ tk_new = new->conf.key;
+
+ /*
+ * In station mode, don't compare the TX MIC key, as it's never used
+ * and offloaded rekeying may not care to send it to the host. This
+ * is the case in iwlwifi, for example.
+ */
+ if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+ new->conf.cipher == WLAN_CIPHER_SUITE_TKIP &&
+ new->conf.keylen == WLAN_KEY_LEN_TKIP &&
+ !(new->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ memcpy(tkip_old, tk_old, WLAN_KEY_LEN_TKIP);
+ memcpy(tkip_new, tk_new, WLAN_KEY_LEN_TKIP);
+ memset(tkip_old + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
+ memset(tkip_new + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 0, 8);
+ tk_old = tkip_old;
+ tk_new = tkip_new;
+ }
+
+ return !crypto_memneq(tk_old, tk_new, new->conf.keylen);
+}
+
int ieee80211_key_link(struct ieee80211_key *key,
struct ieee80211_sub_if_data *sdata,
struct sta_info *sta)
@@ -635,8 +668,7 @@ int ieee80211_key_link(struct ieee80211_
* Silently accept key re-installation without really installing the
* new version of the key to avoid nonce reuse or replay issues.
*/
- if (old_key && key->conf.keylen == old_key->conf.keylen &&
- !crypto_memneq(key->conf.key, old_key->conf.key, key->conf.keylen)) {
+ if (ieee80211_key_identical(sdata, old_key, key)) {
ieee80211_key_free_unused(key);
ret = 0;
goto out;

View File

@ -1,234 +0,0 @@
From patchwork Mon Sep 25 22:29:41 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v2] ath10k: add new cipher suite support
From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
X-Patchwork-Id: 9970615
Message-Id: <1506378581-13598-1-git-send-email-rmanohar@qti.qualcomm.com>
To: <ath10k@lists.infradead.org>
Cc: Jouni Malinen <jouni@qca.qualcomm.com>, linux-wireless@vger.kernel.org,
Rajkumar Manoharan <rmanohar@qti.qualcomm.com>, rmanohar@codeaurora.org
Date: Mon, 25 Sep 2017 15:29:41 -0700
QCA99x0 and QCA4019 family chips support CCMP-256, GCMP-128, and
GCMP-256 ciphers in hardware, so advertise support for these. As
firmware does not support group management frame ciphers (BIP),
handle them in software (mac80211).
Reviewed-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
Cc: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
---
v2: fix a bug in assigning n_cipher_suites. fill hw_param n_cipher_suites
for all chips.
drivers/net/wireless/ath/ath10k/core.c | 12 ++++++++++
drivers/net/wireless/ath/ath10k/hw.h | 3 +++
drivers/net/wireless/ath/ath10k/mac.c | 43 ++++++++++++++++++++++++++++++++--
drivers/net/wireless/ath/ath10k/wmi.h | 1 +
4 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index a4f635820f35..71de3a28b59c 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -74,6 +74,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -97,6 +98,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -119,6 +121,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -141,6 +144,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -163,6 +167,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -188,6 +193,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -216,6 +222,7 @@
.spectral_bin_discard = 4,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 11,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -249,6 +256,7 @@
*/
.vht160_mcs_rx_highest = 1560,
.vht160_mcs_tx_highest = 1560,
+ .n_cipher_suites = 11,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -281,6 +289,7 @@
*/
.vht160_mcs_rx_highest = 780,
.vht160_mcs_tx_highest = 780,
+ .n_cipher_suites = 11,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -303,6 +312,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -327,6 +337,7 @@
.spectral_bin_discard = 0,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 8,
},
{
.id = QCA4019_HW_1_0_DEV_VERSION,
@@ -356,6 +367,7 @@
.spectral_bin_discard = 4,
.vht160_mcs_rx_highest = 0,
.vht160_mcs_tx_highest = 0,
+ .n_cipher_suites = 11,
},
};
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 0c089f6dd3d9..ed30d5b6cd0e 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -550,6 +550,9 @@ struct ath10k_hw_params {
*/
int vht160_mcs_rx_highest;
int vht160_mcs_tx_highest;
+
+ /* Number of ciphers supported (i.e First N) in cipher_suites array */
+ int n_cipher_suites;
};
struct htt_rx_desc;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 5683f1a5330e..89455231754c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -242,6 +242,16 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
case WLAN_CIPHER_SUITE_WEP104:
arg.key_cipher = WMI_CIPHER_WEP;
break;
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ arg.key_cipher = WMI_CIPHER_AES_CCM;
+ break;
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ arg.key_cipher = WMI_CIPHER_AES_GCM;
+ break;
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
case WLAN_CIPHER_SUITE_AES_CMAC:
WARN_ON(1);
return -EINVAL;
@@ -5723,7 +5733,10 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
u32 flags2;
/* this one needs to be done in software */
- if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
+ if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
+ key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
+ key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256 ||
+ key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
return 1;
if (arvif->nohwcrypt)
@@ -8074,7 +8087,22 @@ int ath10k_mac_register(struct ath10k *ar)
WLAN_CIPHER_SUITE_WEP104,
WLAN_CIPHER_SUITE_TKIP,
WLAN_CIPHER_SUITE_CCMP,
+
+ /* Do not add hardware supported ciphers before this line.
+ * Allow software encryption for all chips. Don't forget to
+ * update n_cipher_suites below.
+ */
WLAN_CIPHER_SUITE_AES_CMAC,
+ WLAN_CIPHER_SUITE_BIP_CMAC_256,
+ WLAN_CIPHER_SUITE_BIP_GMAC_128,
+ WLAN_CIPHER_SUITE_BIP_GMAC_256,
+
+ /* Only QCA99x0 and QCA4019 varients support GCMP-128, GCMP-256
+ * and CCMP-256 in hardware.
+ */
+ WLAN_CIPHER_SUITE_GCMP,
+ WLAN_CIPHER_SUITE_GCMP_256,
+ WLAN_CIPHER_SUITE_CCMP_256,
};
struct ieee80211_supported_band *band;
void *channels;
@@ -8313,7 +8341,18 @@ int ath10k_mac_register(struct ath10k *ar)
}
ar->hw->wiphy->cipher_suites = cipher_suites;
- ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+ /* QCA988x and QCA6174 family chips do not support CCMP-256, GCMP-128
+ * and GCMP-256 ciphers in hardware. Fetch number of ciphers supported
+ * from chip specific hw_param table.
+ */
+ if (!ar->hw_params.n_cipher_suites ||
+ ar->hw_params.n_cipher_suites > ARRAY_SIZE(cipher_suites)) {
+ ath10k_err(ar, "invalid hw_params.n_cipher_suites %d\n",
+ ar->hw_params.n_cipher_suites);
+ ar->hw_params.n_cipher_suites = 8;
+ }
+ ar->hw->wiphy->n_cipher_suites = ar->hw_params.n_cipher_suites;
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 7a3606dde227..c02b21cff38d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4751,6 +4751,7 @@ struct wmi_key_seq_counter {
#define WMI_CIPHER_WAPI 0x5
#define WMI_CIPHER_CKIP 0x6
#define WMI_CIPHER_AES_CMAC 0x7
+#define WMI_CIPHER_AES_GCM 0x8
struct wmi_vdev_install_key_cmd {
__le32 vdev_id;