aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/329-mac80211-don-t-compare-TKIP-TX-MIC-key-in-reinstall.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/329-mac80211-don-t-compare-TKIP-TX-MIC-key-in-reinstall.patch')
-rw-r--r--package/kernel/mac80211/patches/329-mac80211-don-t-compare-TKIP-TX-MIC-key-in-reinstall.patch73
1 files changed, 73 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/329-mac80211-don-t-compare-TKIP-TX-MIC-key-in-reinstall.patch b/package/kernel/mac80211/patches/329-mac80211-don-t-compare-TKIP-TX-MIC-key-in-reinstall.patch
new file mode 100644
index 0000000000..1eaf51de72
--- /dev/null
+++ b/package/kernel/mac80211/patches/329-mac80211-don-t-compare-TKIP-TX-MIC-key-in-reinstall.patch
@@ -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;