+++ /dev/null
-From 965a7d72e798eb7af0aa67210e37cf7ecd1c9cad Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
-Date: Tue, 11 May 2021 20:02:42 +0200
-Subject: mac80211: assure all fragments are encrypted
-
-From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
-
-commit 965a7d72e798eb7af0aa67210e37cf7ecd1c9cad upstream.
-
-Do not mix plaintext and encrypted fragments in protected Wi-Fi
-networks. This fixes CVE-2020-26147.
-
-Previously, an attacker was able to first forward a legitimate encrypted
-fragment towards a victim, followed by a plaintext fragment. The
-encrypted and plaintext fragment would then be reassembled. For further
-details see Section 6.3 and Appendix D in the paper "Fragment and Forge:
-Breaking Wi-Fi Through Frame Aggregation and Fragmentation".
-
-Because of this change there are now two equivalent conditions in the
-code to determine if a received fragment requires sequential PNs, so we
-also move this test to a separate function to make the code easier to
-maintain.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
-Link: https://lore.kernel.org/r/20210511200110.30c4394bb835.I5acfdb552cc1d20c339c262315950b3eac491397@changeid
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/mac80211/rx.c | 23 ++++++++++++-----------
- 1 file changed, 12 insertions(+), 11 deletions(-)
-
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1807,6 +1807,16 @@ ieee80211_reassemble_find(struct ieee802
- return NULL;
- }
-
-+static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc)
-+{
-+ return rx->key &&
-+ (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
-+ rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
-+ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
-+ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
-+ ieee80211_has_protected(fc);
-+}
-+
- static ieee80211_rx_result debug_noinline
- ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
- {
-@@ -1852,12 +1862,7 @@ ieee80211_rx_h_defragment(struct ieee802
- /* This is the first fragment of a new frame. */
- entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
- rx->seqno_idx, &(rx->skb));
-- if (rx->key &&
-- (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
-- rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
-- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
-- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
-- ieee80211_has_protected(fc)) {
-+ if (requires_sequential_pn(rx, fc)) {
- int queue = rx->security_idx;
-
- /* Store CCMP/GCMP PN so that we can verify that the
-@@ -1899,11 +1904,7 @@ ieee80211_rx_h_defragment(struct ieee802
- u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
- int queue;
-
-- if (!rx->key ||
-- (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
-- rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 &&
-- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP &&
-- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256))
-+ if (!requires_sequential_pn(rx, fc))
- return RX_DROP_UNUSABLE;
- memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
- for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
+++ /dev/null
-From 94034c40ab4a3fcf581fbc7f8fdf4e29943c4a24 Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
-Date: Tue, 11 May 2021 20:02:43 +0200
-Subject: mac80211: prevent mixed key and fragment cache attacks
-
-From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
-
-commit 94034c40ab4a3fcf581fbc7f8fdf4e29943c4a24 upstream.
-
-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>
-Link: https://lore.kernel.org/r/20210511200110.3f8290e59823.I622a67769ed39257327a362cfc09c812320eb979@changeid
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- 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(+)
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -94,6 +94,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;
- };
-
-
---- a/net/mac80211/key.c
-+++ b/net/mac80211/key.c
-@@ -645,6 +645,7 @@ int ieee80211_key_link(struct ieee80211_
- struct ieee80211_sub_if_data *sdata,
- struct sta_info *sta)
- {
-+ static atomic_t key_color = ATOMIC_INIT(0);
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_key *old_key;
- int idx = key->conf.keyidx;
-@@ -680,6 +681,12 @@ int ieee80211_key_link(struct ieee80211_
- 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);
-
- ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
---- a/net/mac80211/key.h
-+++ b/net/mac80211/key.h
-@@ -123,6 +123,8 @@ struct ieee80211_key {
- } debugfs;
- #endif
-
-+ unsigned int color;
-+
- /*
- * key config, must be last because it contains key
- * material as variable length member
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1869,6 +1869,7 @@ ieee80211_rx_h_defragment(struct ieee802
- * 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);
-@@ -1906,6 +1907,11 @@ ieee80211_rx_h_defragment(struct ieee802
-
- 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]++;