Linux-Wireless Archive on lore.kernel.org
 help / color / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless@vger.kernel.org
Cc: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>, stable@vger.kernel.org
Subject: [PATCH 02/18] mac80211: prevent mixed key and fragment cache attacks
Date: Tue, 11 May 2021 20:02:43 +0200
Message-ID: <20210511200110.3f8290e59823.I622a67769ed39257327a362cfc09c812320eb979@changeid> (raw)
In-Reply-To: <20210511180259.159598-1-johannes@sipsolutions.net>

From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>

Simultaneously prevent mixed key attacks (CVE-2020-24587) and fragment
cache attacks (CVE-2020-24586). This is accomplished by assigning a
unique color to every key (per interface) and using this to track which
key was used to decrypt a fragment. When reassembling frames, it is
now checked whether all fragments were decrypted using the same key.

To assure that fragment cache attacks are also prevented, the ID that is
assigned to keys is unique even over (re)associations and (re)connects.
This means fragments separated by a (re)association or (re)connect will
not be reassembled. Because mac80211 now also prevents the reassembly of
mixed encrypted and plaintext fragments, all cache attacks are prevented.

Cc: stable@vger.kernel.org
Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/ieee80211_i.h | 1 +
 net/mac80211/key.c         | 7 +++++++
 net/mac80211/key.h         | 2 ++
 net/mac80211/rx.c          | 6 ++++++
 4 files changed, 16 insertions(+)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8fcbaa1eedf3..874ffe7819e5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -97,6 +97,7 @@ struct ieee80211_fragment_entry {
 	u8 rx_queue;
 	bool check_sequential_pn; /* needed for CCMP/GCMP */
 	u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
+	unsigned int key_color;
 };
 
 
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 56c068cb49c4..f695fc80088b 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -799,6 +799,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
 		       struct ieee80211_sub_if_data *sdata,
 		       struct sta_info *sta)
 {
+	static atomic_t key_color = ATOMIC_INIT(0);
 	struct ieee80211_key *old_key;
 	int idx = key->conf.keyidx;
 	bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
@@ -850,6 +851,12 @@ int ieee80211_key_link(struct ieee80211_key *key,
 	key->sdata = sdata;
 	key->sta = sta;
 
+	/*
+	 * Assign a unique ID to every key so we can easily prevent mixed
+	 * key and fragment cache attacks.
+	 */
+	key->color = atomic_inc_return(&key_color);
+
 	increment_tailroom_need_count(sdata);
 
 	ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 7ad72e9b4991..1e326c89d721 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -128,6 +128,8 @@ struct ieee80211_key {
 	} debugfs;
 #endif
 
+	unsigned int color;
+
 	/*
 	 * key config, must be last because it contains key
 	 * material as variable length member
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 65fc674e27cc..531232b91bc4 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2255,6 +2255,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
 			 * next fragment has a sequential PN value.
 			 */
 			entry->check_sequential_pn = true;
+			entry->key_color = rx->key->color;
 			memcpy(entry->last_pn,
 			       rx->key->u.ccmp.rx_pn[queue],
 			       IEEE80211_CCMP_PN_LEN);
@@ -2292,6 +2293,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
 
 		if (!requires_sequential_pn(rx, fc))
 			return RX_DROP_UNUSABLE;
+
+		/* Prevent mixed key and fragment cache attacks */
+		if (entry->key_color != rx->key->color)
+			return RX_DROP_UNUSABLE;
+
 		memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
 		for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
 			pn[i]++;
-- 
2.30.2


  parent reply index

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-11 18:02 [PATCH 00/18] mac80211/driver security fixes Johannes Berg
2021-05-11 18:02 ` [PATCH 01/18] mac80211: assure all fragments are encrypted Johannes Berg
2021-05-11 18:02 ` Johannes Berg [this message]
2021-05-11 18:02 ` [PATCH 03/18] mac80211: properly handle A-MSDUs that start with an RFC 1042 header Johannes Berg
2021-05-11 18:02 ` [PATCH 04/18] cfg80211: mitigate A-MSDU aggregation attacks Johannes Berg
2021-05-11 18:02 ` [PATCH 05/18] mac80211: drop A-MSDUs on old ciphers Johannes Berg
2021-05-11 18:02 ` [PATCH 06/18] mac80211: add fragment cache to sta_info Johannes Berg
2021-05-11 18:02 ` [PATCH 07/18] mac80211: check defrag PN against current frame Johannes Berg
2021-05-11 18:02 ` [PATCH 08/18] mac80211: prevent attacks on TKIP/WEP as well Johannes Berg
2021-05-11 18:02 ` [PATCH 09/18] mac80211: do not accept/forward invalid EAPOL frames Johannes Berg
2021-05-11 18:02 ` [PATCH 10/18] mac80211: extend protection against mixed key and fragment cache attacks Johannes Berg
2021-05-11 18:02 ` [PATCH 11/18] ath10k: add CCMP PN replay protection for fragmented frames for PCIe Johannes Berg
2021-05-14 22:23   ` Abhishek Kumar
2021-05-11 18:02 ` [PATCH 12/18] ath10k: drop fragments with multicast DA " Johannes Berg
2021-05-11 18:02 ` [PATCH 13/18] ath10k: drop fragments with multicast DA for SDIO Johannes Berg
2021-05-11 18:02 ` [PATCH 14/18] ath10k: drop MPDU which has discard flag set by firmware " Johannes Berg
2021-05-12 18:35   ` Brian Norris
2021-05-13 17:18     ` Jeff Johnson
2021-05-11 18:02 ` [PATCH 15/18] ath10k: Fix TKIP Michael MIC verification for PCIe Johannes Berg
2021-05-11 18:02 ` [PATCH 16/18] ath10k: Validate first subframe of A-MSDU before processing the list Johannes Berg
2021-05-11 18:02 ` [PATCH 17/18] ath11k: Clear the fragment cache during key install Johannes Berg
2021-05-11 18:02 ` [PATCH 18/18] ath11k: Drop multicast fragments Johannes Berg
2021-05-17 18:54 ` [PATCH 00/18] mac80211/driver security fixes Ben Greear

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210511200110.3f8290e59823.I622a67769ed39257327a362cfc09c812320eb979@changeid \
    --to=johannes@sipsolutions.net \
    --cc=Mathy.Vanhoef@kuleuven.be \
    --cc=linux-wireless@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Wireless Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-wireless/0 linux-wireless/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-wireless linux-wireless/ https://lore.kernel.org/linux-wireless \
		linux-wireless@vger.kernel.org
	public-inbox-index linux-wireless

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-wireless


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git