key.c 16.0 KB
Newer Older
1 2 3 4
/*
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
5
 * Copyright 2007-2008	Johannes Berg <johannes@sipsolutions.net>
6 7 8 9 10 11
 *
 * 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
 * published by the Free Software Foundation.
 */

J
Johannes Berg 已提交
12 13 14
#include <linux/if_ether.h>
#include <linux/etherdevice.h>
#include <linux/list.h>
15
#include <linux/rcupdate.h>
16
#include <linux/rtnetlink.h>
17
#include <linux/slab.h>
18 19
#include <net/mac80211.h>
#include "ieee80211_i.h"
20
#include "driver-ops.h"
21 22
#include "debugfs_key.h"
#include "aes_ccm.h"
23
#include "aes_cmac.h"
24

J
Johannes Berg 已提交
25

J
Johannes Berg 已提交
26 27
/**
 * DOC: Key handling basics
J
Johannes Berg 已提交
28 29 30 31 32
 *
 * Key handling in mac80211 is done based on per-interface (sub_if_data)
 * keys and per-station keys. Since each station belongs to an interface,
 * each station key also belongs to that interface.
 *
33 34 35 36 37 38 39
 * Hardware acceleration is done on a best-effort basis for algorithms
 * that are implemented in software,  for each key the hardware is asked
 * to enable that key for offloading but if it cannot do that the key is
 * simply kept for software encryption (unless it is for an algorithm
 * that isn't implemented in software).
 * There is currently no way of knowing whether a key is handled in SW
 * or HW except by looking into debugfs.
J
Johannes Berg 已提交
40
 *
41 42 43 44 45 46
 * All key management is internally protected by a mutex. Within all
 * other parts of mac80211, key references are, just as STA structure
 * references, protected by RCU. Note, however, that some things are
 * unprotected, namely the key->sta dereferences within the hardware
 * acceleration functions. This means that sta_info_destroy() must
 * remove the key which waits for an RCU grace period.
J
Johannes Berg 已提交
47 48 49 50
 */

static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

J
Johannes Berg 已提交
51
static void assert_key_lock(struct ieee80211_local *local)
52
{
53
	lockdep_assert_held(&local->key_mtx);
54 55
}

56
static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
J
Johannes Berg 已提交
57 58
{
	if (key->sta)
59
		return &key->sta->sta;
J
Johannes Berg 已提交
60

61
	return NULL;
J
Johannes Berg 已提交
62 63
}

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
{
	/*
	 * When this count is zero, SKB resizing for allocating tailroom
	 * for IV or MMIC is skipped. But, this check has created two race
	 * cases in xmit path while transiting from zero count to one:
	 *
	 * 1. SKB resize was skipped because no key was added but just before
	 * the xmit key is added and SW encryption kicks off.
	 *
	 * 2. SKB resize was skipped because all the keys were hw planted but
	 * just before xmit one of the key is deleted and SW encryption kicks
	 * off.
	 *
	 * In both the above case SW encryption will find not enough space for
	 * tailroom and exits with WARN_ON. (See WARN_ONs at wpa.c)
	 *
	 * Solution has been explained at
	 * http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net
	 */

	if (!sdata->crypto_tx_tailroom_needed_cnt++) {
		/*
		 * Flush all XMIT packets currently using HW encryption or no
		 * encryption at all if the count transition is from 0 -> 1.
		 */
		synchronize_net();
	}
}

94
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
J
Johannes Berg 已提交
95
{
96 97
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_sta *sta;
J
Johannes Berg 已提交
98 99
	int ret;

100 101
	might_sleep();

102
	if (!key->local->ops->set_key)
103
		goto out_unsupported;
J
Johannes Berg 已提交
104

J
Johannes Berg 已提交
105 106
	assert_key_lock(key->local);

107 108
	sta = get_sta_for_key(key);

109 110 111 112 113 114 115 116
	/*
	 * If this is a per-STA GTK, check if it
	 * is supported; if not, return.
	 */
	if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
	    !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
		goto out_unsupported;

117
	sdata = key->sdata;
118 119 120 121 122 123 124
	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
		/*
		 * The driver doesn't know anything about VLAN interfaces.
		 * Hence, don't send GTKs for VLAN interfaces to the driver.
		 */
		if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
			goto out_unsupported;
125 126 127
		sdata = container_of(sdata->bss,
				     struct ieee80211_sub_if_data,
				     u.ap);
128
	}
J
Johannes Berg 已提交
129

J
Johannes Berg 已提交
130
	ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
J
Johannes Berg 已提交
131

132
	if (!ret) {
J
Johannes Berg 已提交
133
		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
134 135 136 137 138

		if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
		      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
			sdata->crypto_tx_tailroom_needed_cnt--;

139 140
		return 0;
	}
J
Johannes Berg 已提交
141

142
	if (ret != -ENOSPC && ret != -EOPNOTSUPP)
J
Joe Perches 已提交
143 144 145
		wiphy_err(key->local->hw.wiphy,
			  "failed to set key (%d, %pM) to hardware (%d)\n",
			  key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
146

147 148 149 150 151 152 153 154 155 156 157
 out_unsupported:
	switch (key->conf.cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
	case WLAN_CIPHER_SUITE_TKIP:
	case WLAN_CIPHER_SUITE_CCMP:
	case WLAN_CIPHER_SUITE_AES_CMAC:
		/* all of these we can do in software */
		return 0;
	default:
		return -EINVAL;
158
	}
J
Johannes Berg 已提交
159 160 161 162
}

static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
{
163 164
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_sta *sta;
J
Johannes Berg 已提交
165 166
	int ret;

167 168
	might_sleep();

169
	if (!key || !key->local->ops->set_key)
J
Johannes Berg 已提交
170 171
		return;

J
Johannes Berg 已提交
172 173 174
	assert_key_lock(key->local);

	if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
J
Johannes Berg 已提交
175 176
		return;

177 178 179
	sta = get_sta_for_key(key);
	sdata = key->sdata;

180 181 182 183
	if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
	      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
		increment_tailroom_need_count(sdata);

184 185 186 187
	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
		sdata = container_of(sdata->bss,
				     struct ieee80211_sub_if_data,
				     u.ap);
J
Johannes Berg 已提交
188

J
Johannes Berg 已提交
189
	ret = drv_set_key(key->local, DISABLE_KEY, sdata,
190
			  sta, &key->conf);
J
Johannes Berg 已提交
191 192

	if (ret)
J
Joe Perches 已提交
193 194 195
		wiphy_err(key->local->hw.wiphy,
			  "failed to remove key (%d, %pM) from hardware (%d)\n",
			  key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
J
Johannes Berg 已提交
196

197 198 199
	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
}

200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
{
	struct ieee80211_key *key;

	key = container_of(key_conf, struct ieee80211_key, conf);

	might_sleep();
	assert_key_lock(key->local);

	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;

	/*
	 * Flush TX path to avoid attempts to use this key
	 * after this function returns. Until then, drivers
	 * must be prepared to handle the key.
	 */
	synchronize_rcu();
}
EXPORT_SYMBOL_GPL(ieee80211_key_removed);

220
static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
221
					int idx, bool uni, bool multi)
222 223 224
{
	struct ieee80211_key *key = NULL;

J
Johannes Berg 已提交
225 226
	assert_key_lock(sdata->local);

227
	if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
J
Johannes Berg 已提交
228
		key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
229

230 231 232 233
	if (uni)
		rcu_assign_pointer(sdata->default_unicast_key, key);
	if (multi)
		rcu_assign_pointer(sdata->default_multicast_key, key);
234

235
	ieee80211_debugfs_key_update_default(sdata);
236 237
}

238 239
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
			       bool uni, bool multi)
240
{
J
Johannes Berg 已提交
241
	mutex_lock(&sdata->local->key_mtx);
242
	__ieee80211_set_default_key(sdata, idx, uni, multi);
J
Johannes Berg 已提交
243
	mutex_unlock(&sdata->local->key_mtx);
244 245
}

246 247 248 249 250
static void
__ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
{
	struct ieee80211_key *key = NULL;

J
Johannes Berg 已提交
251 252
	assert_key_lock(sdata->local);

253 254
	if (idx >= NUM_DEFAULT_KEYS &&
	    idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
J
Johannes Berg 已提交
255
		key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
256 257 258

	rcu_assign_pointer(sdata->default_mgmt_key, key);

259
	ieee80211_debugfs_key_update_default(sdata);
260 261 262 263 264
}

void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
				    int idx)
{
J
Johannes Berg 已提交
265
	mutex_lock(&sdata->local->key_mtx);
266
	__ieee80211_set_default_mgmt_key(sdata, idx);
J
Johannes Berg 已提交
267
	mutex_unlock(&sdata->local->key_mtx);
268 269
}

270 271 272

static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
				    struct sta_info *sta,
273
				    bool pairwise,
274 275 276
				    struct ieee80211_key *old,
				    struct ieee80211_key *new)
{
277 278
	int idx;
	bool defunikey, defmultikey, defmgmtkey;
279 280 281 282

	if (new)
		list_add(&new->list, &sdata->key_list);

283 284 285 286 287 288 289 290
	if (sta && pairwise) {
		rcu_assign_pointer(sta->ptk, new);
	} else if (sta) {
		if (old)
			idx = old->conf.keyidx;
		else
			idx = new->conf.keyidx;
		rcu_assign_pointer(sta->gtk[idx], new);
291 292 293 294 295 296 297 298
	} else {
		WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);

		if (old)
			idx = old->conf.keyidx;
		else
			idx = new->conf.keyidx;

J
Johannes Berg 已提交
299 300 301 302 303 304 305 306 307
		defunikey = old &&
			old == key_mtx_dereference(sdata->local,
						sdata->default_unicast_key);
		defmultikey = old &&
			old == key_mtx_dereference(sdata->local,
						sdata->default_multicast_key);
		defmgmtkey = old &&
			old == key_mtx_dereference(sdata->local,
						sdata->default_mgmt_key);
308

309 310 311 312
		if (defunikey && !new)
			__ieee80211_set_default_key(sdata, -1, true, false);
		if (defmultikey && !new)
			__ieee80211_set_default_key(sdata, -1, false, true);
313 314
		if (defmgmtkey && !new)
			__ieee80211_set_default_mgmt_key(sdata, -1);
315 316

		rcu_assign_pointer(sdata->keys[idx], new);
317 318 319 320 321 322
		if (defunikey && new)
			__ieee80211_set_default_key(sdata, new->conf.keyidx,
						    true, false);
		if (defmultikey && new)
			__ieee80211_set_default_key(sdata, new->conf.keyidx,
						    false, true);
323 324 325
		if (defmgmtkey && new)
			__ieee80211_set_default_mgmt_key(sdata,
							 new->conf.keyidx);
326 327
	}

328 329
	if (old)
		list_del(&old->list);
J
Johannes Berg 已提交
330 331
}

332
struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
333 334
					  const u8 *key_data,
					  size_t seq_len, const u8 *seq)
335 336
{
	struct ieee80211_key *key;
337
	int i, j, err;
338

339
	BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
J
Johannes Berg 已提交
340 341

	key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
342
	if (!key)
343
		return ERR_PTR(-ENOMEM);
J
Johannes Berg 已提交
344 345 346 347 348 349 350 351

	/*
	 * Default to software encryption; we'll later upload the
	 * key to the hardware if possible.
	 */
	key->conf.flags = 0;
	key->flags = 0;

352
	key->conf.cipher = cipher;
J
Johannes Berg 已提交
353 354
	key->conf.keyidx = idx;
	key->conf.keylen = key_len;
355 356 357
	switch (cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
358 359 360
		key->conf.iv_len = WEP_IV_LEN;
		key->conf.icv_len = WEP_ICV_LEN;
		break;
361
	case WLAN_CIPHER_SUITE_TKIP:
362 363
		key->conf.iv_len = TKIP_IV_LEN;
		key->conf.icv_len = TKIP_ICV_LEN;
364
		if (seq) {
365 366 367 368 369 370 371
			for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
				key->u.tkip.rx[i].iv32 =
					get_unaligned_le32(&seq[2]);
				key->u.tkip.rx[i].iv16 =
					get_unaligned_le16(seq);
			}
		}
372
		break;
373
	case WLAN_CIPHER_SUITE_CCMP:
374 375
		key->conf.iv_len = CCMP_HDR_LEN;
		key->conf.icv_len = CCMP_MIC_LEN;
376
		if (seq) {
377
			for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++)
378 379 380 381
				for (j = 0; j < CCMP_PN_LEN; j++)
					key->u.ccmp.rx_pn[i][j] =
						seq[CCMP_PN_LEN - j - 1];
		}
J
Johannes Berg 已提交
382 383 384 385 386
		/*
		 * Initialize AES key state here as an optimization so that
		 * it does not need to be initialized for every packet.
		 */
		key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
387 388
		if (IS_ERR(key->u.ccmp.tfm)) {
			err = PTR_ERR(key->u.ccmp.tfm);
389
			kfree(key);
390
			return ERR_PTR(err);
J
Johannes Berg 已提交
391
		}
J
Johannes Berg 已提交
392 393 394 395 396 397 398
		break;
	case WLAN_CIPHER_SUITE_AES_CMAC:
		key->conf.iv_len = 0;
		key->conf.icv_len = sizeof(struct ieee80211_mmie);
		if (seq)
			for (j = 0; j < 6; j++)
				key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
399 400 401 402 403 404
		/*
		 * Initialize AES key state here as an optimization so that
		 * it does not need to be initialized for every packet.
		 */
		key->u.aes_cmac.tfm =
			ieee80211_aes_cmac_key_setup(key_data);
405 406
		if (IS_ERR(key->u.aes_cmac.tfm)) {
			err = PTR_ERR(key->u.aes_cmac.tfm);
407
			kfree(key);
408
			return ERR_PTR(err);
409
		}
J
Johannes Berg 已提交
410
		break;
411
	}
J
Johannes Berg 已提交
412 413
	memcpy(key->conf.key, key_data, key_len);
	INIT_LIST_HEAD(&key->list);
414

415 416
	return key;
}
J
Johannes Berg 已提交
417

J
Johannes Berg 已提交
418 419 420 421 422
static void __ieee80211_key_destroy(struct ieee80211_key *key)
{
	if (!key)
		return;

423 424 425 426 427 428
	/*
	 * Synchronize so the TX path can no longer be using
	 * this key before we free/remove it.
	 */
	synchronize_rcu();

429 430
	if (key->local)
		ieee80211_key_disable_hw_accel(key);
J
Johannes Berg 已提交
431

432
	if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
J
Johannes Berg 已提交
433
		ieee80211_aes_key_free(key->u.ccmp.tfm);
434
	if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
J
Johannes Berg 已提交
435
		ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
436
	if (key->local) {
437
		ieee80211_debugfs_key_remove(key);
438 439
		key->sdata->crypto_tx_tailroom_needed_cnt--;
	}
J
Johannes Berg 已提交
440 441 442 443

	kfree(key);
}

444 445 446
int ieee80211_key_link(struct ieee80211_key *key,
		       struct ieee80211_sub_if_data *sdata,
		       struct sta_info *sta)
447 448
{
	struct ieee80211_key *old_key;
449
	int idx, ret;
450
	bool pairwise;
451 452 453 454

	BUG_ON(!sdata);
	BUG_ON(!key);

455
	pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
456 457 458 459 460
	idx = key->conf.keyidx;
	key->local = sdata->local;
	key->sdata = sdata;
	key->sta = sta;

J
Johannes Berg 已提交
461 462 463 464 465
	if (sta) {
		/*
		 * some hardware cannot handle TKIP with QoS, so
		 * we indicate whether QoS could be in use.
		 */
466
		if (test_sta_flags(sta, WLAN_STA_WME))
J
Johannes Berg 已提交
467 468
			key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
	} else {
469
		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
J
Johannes Berg 已提交
470 471
			struct sta_info *ap;

472
			/*
473 474
			 * We're getting a sta pointer in, so must be under
			 * appropriate locking for sta_info_get().
475
			 */
476

J
Johannes Berg 已提交
477
			/* same here, the AP could be using QoS */
478
			ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
J
Johannes Berg 已提交
479
			if (ap) {
480
				if (test_sta_flags(ap, WLAN_STA_WME))
J
Johannes Berg 已提交
481 482 483 484 485 486
					key->conf.flags |=
						IEEE80211_KEY_FLAG_WMM_STA;
			}
		}
	}

J
Johannes Berg 已提交
487
	mutex_lock(&sdata->local->key_mtx);
488

489
	if (sta && pairwise)
J
Johannes Berg 已提交
490
		old_key = key_mtx_dereference(sdata->local, sta->ptk);
491
	else if (sta)
J
Johannes Berg 已提交
492
		old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
493
	else
J
Johannes Berg 已提交
494
		old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
495

496 497
	increment_tailroom_need_count(sdata);

498
	__ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
J
Johannes Berg 已提交
499
	__ieee80211_key_destroy(old_key);
500

J
Johannes Berg 已提交
501
	ieee80211_debugfs_key_add(key);
502

503
	ret = ieee80211_key_enable_hw_accel(key);
J
Johannes Berg 已提交
504

J
Johannes Berg 已提交
505
	mutex_unlock(&sdata->local->key_mtx);
506 507

	return ret;
508 509
}

510
void __ieee80211_key_free(struct ieee80211_key *key)
511
{
512 513 514
	if (!key)
		return;

515 516 517
	/*
	 * Replace key with nothingness if it was ever used.
	 */
J
Johannes Berg 已提交
518
	if (key->sdata)
519
		__ieee80211_key_replace(key->sdata, key->sta,
520 521
				key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
				key, NULL);
J
Johannes Berg 已提交
522
	__ieee80211_key_destroy(key);
523
}
524

525 526
void ieee80211_key_free(struct ieee80211_local *local,
			struct ieee80211_key *key)
527
{
J
Johannes Berg 已提交
528
	mutex_lock(&local->key_mtx);
J
Johannes Berg 已提交
529
	__ieee80211_key_free(key);
J
Johannes Berg 已提交
530
	mutex_unlock(&local->key_mtx);
J
Johannes Berg 已提交
531 532
}

J
Johannes Berg 已提交
533
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
J
Johannes Berg 已提交
534 535
{
	struct ieee80211_key *key;
J
Johannes Berg 已提交
536

J
Johannes Berg 已提交
537
	ASSERT_RTNL();
J
Johannes Berg 已提交
538

539
	if (WARN_ON(!ieee80211_sdata_running(sdata)))
J
Johannes Berg 已提交
540
		return;
J
Johannes Berg 已提交
541

J
Johannes Berg 已提交
542
	mutex_lock(&sdata->local->key_mtx);
J
Johannes Berg 已提交
543

544 545 546 547
	sdata->crypto_tx_tailroom_needed_cnt = 0;

	list_for_each_entry(key, &sdata->key_list, list) {
		increment_tailroom_need_count(sdata);
J
Johannes Berg 已提交
548
		ieee80211_key_enable_hw_accel(key);
549
	}
550

J
Johannes Berg 已提交
551
	mutex_unlock(&sdata->local->key_mtx);
J
Johannes Berg 已提交
552 553
}

554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
void ieee80211_iter_keys(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 void (*iter)(struct ieee80211_hw *hw,
				      struct ieee80211_vif *vif,
				      struct ieee80211_sta *sta,
				      struct ieee80211_key_conf *key,
				      void *data),
			 void *iter_data)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_key *key;
	struct ieee80211_sub_if_data *sdata;

	ASSERT_RTNL();

	mutex_lock(&local->key_mtx);
	if (vif) {
		sdata = vif_to_sdata(vif);
		list_for_each_entry(key, &sdata->key_list, list)
			iter(hw, &sdata->vif,
			     key->sta ? &key->sta->sta : NULL,
			     &key->conf, iter_data);
	} else {
		list_for_each_entry(sdata, &local->interfaces, list)
			list_for_each_entry(key, &sdata->key_list, list)
				iter(hw, &sdata->vif,
				     key->sta ? &key->sta->sta : NULL,
				     &key->conf, iter_data);
	}
	mutex_unlock(&local->key_mtx);
}
EXPORT_SYMBOL(ieee80211_iter_keys);

J
Johannes Berg 已提交
587
void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
J
Johannes Berg 已提交
588 589 590
{
	struct ieee80211_key *key;

J
Johannes Berg 已提交
591
	ASSERT_RTNL();
592

J
Johannes Berg 已提交
593
	mutex_lock(&sdata->local->key_mtx);
J
Johannes Berg 已提交
594

J
Johannes Berg 已提交
595 596
	list_for_each_entry(key, &sdata->key_list, list)
		ieee80211_key_disable_hw_accel(key);
J
Johannes Berg 已提交
597

J
Johannes Berg 已提交
598
	mutex_unlock(&sdata->local->key_mtx);
599
}
J
Johannes Berg 已提交
600

601 602 603
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_key *key, *tmp;
604

J
Johannes Berg 已提交
605
	mutex_lock(&sdata->local->key_mtx);
606

607
	ieee80211_debugfs_key_remove_mgmt_default(sdata);
608 609

	list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
J
Johannes Berg 已提交
610
		__ieee80211_key_free(key);
611

612 613
	ieee80211_debugfs_key_update_default(sdata);

J
Johannes Berg 已提交
614
	mutex_unlock(&sdata->local->key_mtx);
J
Johannes Berg 已提交
615
}
616 617 618 619 620 621 622 623 624 625 626 627


void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid,
				const u8 *replay_ctr, gfp_t gfp)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);

	trace_api_gtk_rekey_notify(sdata, bssid, replay_ctr);

	cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp);
}
EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify);