Commit 6440f0ee authored by Johannes Berg's avatar Johannes Berg Committed by Greg Kroah-Hartman

mac80211: accept key reinstall without changing anything

commit fdf7cb41 upstream.

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: default avatarJohannes Berg <johannes.berg@intel.com>
Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c4e3d53b
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2017 Intel Deutschland GmbH
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -617,9 +618,6 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -617,9 +618,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
idx = key->conf.keyidx; idx = key->conf.keyidx;
key->local = sdata->local;
key->sdata = sdata;
key->sta = sta;
mutex_lock(&sdata->local->key_mtx); mutex_lock(&sdata->local->key_mtx);
...@@ -630,6 +628,21 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -630,6 +628,21 @@ int ieee80211_key_link(struct ieee80211_key *key,
else else
old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]); 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); increment_tailroom_need_count(sdata);
ieee80211_key_replace(sdata, sta, pairwise, old_key, key); ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
...@@ -645,6 +658,7 @@ int ieee80211_key_link(struct ieee80211_key *key, ...@@ -645,6 +658,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
ret = 0; ret = 0;
} }
out:
mutex_unlock(&sdata->local->key_mtx); mutex_unlock(&sdata->local->key_mtx);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment