mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	mac80211: accept key reinstall without changing anything
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: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									c0576e3975
								
							
						
					
					
						commit
						fdf7cb4185
					
				
					 1 changed files with 17 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
 | 
			
		||||
 * Copyright 2007-2008	Johannes Berg <johannes@sipsolutions.net>
 | 
			
		||||
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 | 
			
		||||
 * Copyright 2015	Intel Deutschland GmbH
 | 
			
		||||
 * Copyright 2015-2017	Intel Deutschland GmbH
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
| 
						 | 
				
			
			@ -620,9 +620,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
 | 
			
		|||
 | 
			
		||||
	pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
 | 
			
		||||
	idx = key->conf.keyidx;
 | 
			
		||||
	key->local = sdata->local;
 | 
			
		||||
	key->sdata = sdata;
 | 
			
		||||
	key->sta = sta;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&sdata->local->key_mtx);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -633,6 +630,21 @@ int ieee80211_key_link(struct ieee80211_key *key,
 | 
			
		|||
	else
 | 
			
		||||
		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);
 | 
			
		||||
 | 
			
		||||
	ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
 | 
			
		||||
| 
						 | 
				
			
			@ -648,6 +660,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
 | 
			
		|||
		ret = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
	mutex_unlock(&sdata->local->key_mtx);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue