|
Takashi Iwai |
6f2bb2 |
From 94034c40ab4a3fcf581fbc7f8fdf4e29943c4a24 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
6f2bb2 |
From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
|
Takashi Iwai |
6f2bb2 |
Date: Tue, 11 May 2021 20:02:43 +0200
|
|
Takashi Iwai |
6f2bb2 |
Subject: [PATCH] mac80211: prevent mixed key and fragment cache attacks
|
|
Takashi Iwai |
6f2bb2 |
Git-commit: 94034c40ab4a3fcf581fbc7f8fdf4e29943c4a24
|
|
Takashi Iwai |
6f2bb2 |
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
|
|
Takashi Iwai |
6f2bb2 |
Patch-mainline: Queued in subsystem maintainer repo
|
|
Takashi Iwai |
6f2bb2 |
References: CVE-2020-24587 CVE-2020-24586 bsc#1185863 bsc#1185862 bsc#1185859
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
Simultaneously prevent mixed key attacks (CVE-2020-24587) and fragment
|
|
Takashi Iwai |
6f2bb2 |
cache attacks (CVE-2020-24586). This is accomplished by assigning a
|
|
Takashi Iwai |
6f2bb2 |
unique color to every key (per interface) and using this to track which
|
|
Takashi Iwai |
6f2bb2 |
key was used to decrypt a fragment. When reassembling frames, it is
|
|
Takashi Iwai |
6f2bb2 |
now checked whether all fragments were decrypted using the same key.
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
To assure that fragment cache attacks are also prevented, the ID that is
|
|
Takashi Iwai |
6f2bb2 |
assigned to keys is unique even over (re)associations and (re)connects.
|
|
Takashi Iwai |
6f2bb2 |
This means fragments separated by a (re)association or (re)connect will
|
|
Takashi Iwai |
6f2bb2 |
not be reassembled. Because mac80211 now also prevents the reassembly of
|
|
Takashi Iwai |
6f2bb2 |
mixed encrypted and plaintext fragments, all cache attacks are prevented.
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
Cc: stable@vger.kernel.org
|
|
Takashi Iwai |
6f2bb2 |
Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
|
|
Takashi Iwai |
6f2bb2 |
Link: https://lore.kernel.org/r/20210511200110.3f8290e59823.I622a67769ed39257327a362cfc09c812320eb979@changeid
|
|
Takashi Iwai |
6f2bb2 |
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
Takashi Iwai |
6f2bb2 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
---
|
|
Takashi Iwai |
6f2bb2 |
net/mac80211/ieee80211_i.h | 1 +
|
|
Takashi Iwai |
6f2bb2 |
net/mac80211/key.c | 7 +++++++
|
|
Takashi Iwai |
6f2bb2 |
net/mac80211/key.h | 2 ++
|
|
Takashi Iwai |
6f2bb2 |
net/mac80211/rx.c | 6 ++++++
|
|
Takashi Iwai |
6f2bb2 |
4 files changed, 16 insertions(+)
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
--- a/net/mac80211/ieee80211_i.h
|
|
Takashi Iwai |
6f2bb2 |
+++ b/net/mac80211/ieee80211_i.h
|
|
Takashi Iwai |
6f2bb2 |
@@ -99,6 +99,7 @@ struct ieee80211_fragment_entry {
|
|
Takashi Iwai |
6f2bb2 |
u8 rx_queue;
|
|
Takashi Iwai |
6f2bb2 |
bool check_sequential_pn; /* needed for CCMP/GCMP */
|
|
Takashi Iwai |
6f2bb2 |
u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
|
|
Takashi Iwai |
6f2bb2 |
+ unsigned int key_color;
|
|
Takashi Iwai |
6f2bb2 |
};
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
--- a/net/mac80211/key.c
|
|
Takashi Iwai |
6f2bb2 |
+++ b/net/mac80211/key.c
|
|
Takashi Iwai |
6f2bb2 |
@@ -647,6 +647,7 @@ int ieee80211_key_link(struct ieee80211_
|
|
Takashi Iwai |
6f2bb2 |
struct ieee80211_sub_if_data *sdata,
|
|
Takashi Iwai |
6f2bb2 |
struct sta_info *sta)
|
|
Takashi Iwai |
6f2bb2 |
{
|
|
Takashi Iwai |
6f2bb2 |
+ static atomic_t key_color = ATOMIC_INIT(0);
|
|
Takashi Iwai |
6f2bb2 |
struct ieee80211_local *local = sdata->local;
|
|
Takashi Iwai |
6f2bb2 |
struct ieee80211_key *old_key;
|
|
Takashi Iwai |
6f2bb2 |
int idx = key->conf.keyidx;
|
|
Takashi Iwai |
6f2bb2 |
@@ -682,6 +683,12 @@ int ieee80211_key_link(struct ieee80211_
|
|
Takashi Iwai |
6f2bb2 |
key->sdata = sdata;
|
|
Takashi Iwai |
6f2bb2 |
key->sta = sta;
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
+ /*
|
|
Takashi Iwai |
6f2bb2 |
+ * Assign a unique ID to every key so we can easily prevent mixed
|
|
Takashi Iwai |
6f2bb2 |
+ * key and fragment cache attacks.
|
|
Takashi Iwai |
6f2bb2 |
+ */
|
|
Takashi Iwai |
6f2bb2 |
+ key->color = atomic_inc_return(&key_color);
|
|
Takashi Iwai |
6f2bb2 |
+
|
|
Takashi Iwai |
6f2bb2 |
increment_tailroom_need_count(sdata);
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
|
|
Takashi Iwai |
6f2bb2 |
--- a/net/mac80211/key.h
|
|
Takashi Iwai |
6f2bb2 |
+++ b/net/mac80211/key.h
|
|
Takashi Iwai |
6f2bb2 |
@@ -127,6 +127,8 @@ struct ieee80211_key {
|
|
Takashi Iwai |
6f2bb2 |
} debugfs;
|
|
Takashi Iwai |
6f2bb2 |
#endif
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
+ unsigned int color;
|
|
Takashi Iwai |
6f2bb2 |
+
|
|
Takashi Iwai |
6f2bb2 |
/*
|
|
Takashi Iwai |
6f2bb2 |
* key config, must be last because it contains key
|
|
Takashi Iwai |
6f2bb2 |
* material as variable length member
|
|
Takashi Iwai |
6f2bb2 |
--- a/net/mac80211/rx.c
|
|
Takashi Iwai |
6f2bb2 |
+++ b/net/mac80211/rx.c
|
|
Takashi Iwai |
6f2bb2 |
@@ -2033,6 +2033,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
|
Takashi Iwai |
6f2bb2 |
* next fragment has a sequential PN value.
|
|
Takashi Iwai |
6f2bb2 |
*/
|
|
Takashi Iwai |
6f2bb2 |
entry->check_sequential_pn = true;
|
|
Takashi Iwai |
6f2bb2 |
+ entry->key_color = rx->key->color;
|
|
Takashi Iwai |
6f2bb2 |
memcpy(entry->last_pn,
|
|
Takashi Iwai |
6f2bb2 |
rx->key->u.ccmp.rx_pn[queue],
|
|
Takashi Iwai |
6f2bb2 |
IEEE80211_CCMP_PN_LEN);
|
|
Takashi Iwai |
6f2bb2 |
@@ -2070,6 +2071,11 @@ ieee80211_rx_h_defragment(struct ieee802
|
|
Takashi Iwai |
6f2bb2 |
|
|
Takashi Iwai |
6f2bb2 |
if (!requires_sequential_pn(rx, fc))
|
|
Takashi Iwai |
6f2bb2 |
return RX_DROP_UNUSABLE;
|
|
Takashi Iwai |
6f2bb2 |
+
|
|
Takashi Iwai |
6f2bb2 |
+ /* Prevent mixed key and fragment cache attacks */
|
|
Takashi Iwai |
6f2bb2 |
+ if (entry->key_color != rx->key->color)
|
|
Takashi Iwai |
6f2bb2 |
+ return RX_DROP_UNUSABLE;
|
|
Takashi Iwai |
6f2bb2 |
+
|
|
Takashi Iwai |
6f2bb2 |
memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
|
|
Takashi Iwai |
6f2bb2 |
for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
|
|
Takashi Iwai |
6f2bb2 |
pn[i]++;
|