aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/key.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r--net/mac80211/key.c98
1 files changed, 57 insertions, 41 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index ccd676b2f599..8c02469b7176 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -30,19 +30,20 @@
30 * keys and per-station keys. Since each station belongs to an interface, 30 * keys and per-station keys. Since each station belongs to an interface,
31 * each station key also belongs to that interface. 31 * each station key also belongs to that interface.
32 * 32 *
33 * Hardware acceleration is done on a best-effort basis, for each key 33 * Hardware acceleration is done on a best-effort basis for algorithms
34 * that is eligible the hardware is asked to enable that key but if 34 * that are implemented in software, for each key the hardware is asked
35 * it cannot do that they key is simply kept for software encryption. 35 * to enable that key for offloading but if it cannot do that the key is
36 * There is currently no way of knowing this except by looking into 36 * simply kept for software encryption (unless it is for an algorithm
37 * debugfs. 37 * that isn't implemented in software).
38 * There is currently no way of knowing whether a key is handled in SW
39 * or HW except by looking into debugfs.
38 * 40 *
39 * All key operations are protected internally. 41 * All key management is internally protected by a mutex. Within all
40 * 42 * other parts of mac80211, key references are, just as STA structure
41 * Within mac80211, key references are, just as STA structure references, 43 * references, protected by RCU. Note, however, that some things are
42 * protected by RCU. Note, however, that some things are unprotected, 44 * unprotected, namely the key->sta dereferences within the hardware
43 * namely the key->sta dereferences within the hardware acceleration 45 * acceleration functions. This means that sta_info_destroy() must
44 * functions. This means that sta_info_destroy() must remove the key 46 * remove the key which waits for an RCU grace period.
45 * which waits for an RCU grace period.
46 */ 47 */
47 48
48static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 49static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@@ -84,10 +85,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
84 goto out_unsupported; 85 goto out_unsupported;
85 86
86 sdata = key->sdata; 87 sdata = key->sdata;
87 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 88 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
89 /*
90 * The driver doesn't know anything about VLAN interfaces.
91 * Hence, don't send GTKs for VLAN interfaces to the driver.
92 */
93 if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
94 goto out_unsupported;
88 sdata = container_of(sdata->bss, 95 sdata = container_of(sdata->bss,
89 struct ieee80211_sub_if_data, 96 struct ieee80211_sub_if_data,
90 u.ap); 97 u.ap);
98 }
91 99
92 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); 100 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
93 101
@@ -171,7 +179,7 @@ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
171EXPORT_SYMBOL_GPL(ieee80211_key_removed); 179EXPORT_SYMBOL_GPL(ieee80211_key_removed);
172 180
173static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 181static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
174 int idx) 182 int idx, bool uni, bool multi)
175{ 183{
176 struct ieee80211_key *key = NULL; 184 struct ieee80211_key *key = NULL;
177 185
@@ -180,18 +188,19 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
180 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 188 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
181 key = sdata->keys[idx]; 189 key = sdata->keys[idx];
182 190
183 rcu_assign_pointer(sdata->default_key, key); 191 if (uni)
192 rcu_assign_pointer(sdata->default_unicast_key, key);
193 if (multi)
194 rcu_assign_pointer(sdata->default_multicast_key, key);
184 195
185 if (key) { 196 ieee80211_debugfs_key_update_default(sdata);
186 ieee80211_debugfs_key_remove_default(key->sdata);
187 ieee80211_debugfs_key_add_default(key->sdata);
188 }
189} 197}
190 198
191void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) 199void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
200 bool uni, bool multi)
192{ 201{
193 mutex_lock(&sdata->local->key_mtx); 202 mutex_lock(&sdata->local->key_mtx);
194 __ieee80211_set_default_key(sdata, idx); 203 __ieee80211_set_default_key(sdata, idx, uni, multi);
195 mutex_unlock(&sdata->local->key_mtx); 204 mutex_unlock(&sdata->local->key_mtx);
196} 205}
197 206
@@ -208,10 +217,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
208 217
209 rcu_assign_pointer(sdata->default_mgmt_key, key); 218 rcu_assign_pointer(sdata->default_mgmt_key, key);
210 219
211 if (key) { 220 ieee80211_debugfs_key_update_default(sdata);
212 ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
213 ieee80211_debugfs_key_add_mgmt_default(key->sdata);
214 }
215} 221}
216 222
217void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 223void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -229,7 +235,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
229 struct ieee80211_key *old, 235 struct ieee80211_key *old,
230 struct ieee80211_key *new) 236 struct ieee80211_key *new)
231{ 237{
232 int idx, defkey, defmgmtkey; 238 int idx;
239 bool defunikey, defmultikey, defmgmtkey;
233 240
234 if (new) 241 if (new)
235 list_add(&new->list, &sdata->key_list); 242 list_add(&new->list, &sdata->key_list);
@@ -250,29 +257,31 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
250 else 257 else
251 idx = new->conf.keyidx; 258 idx = new->conf.keyidx;
252 259
253 defkey = old && sdata->default_key == old; 260 defunikey = old && sdata->default_unicast_key == old;
261 defmultikey = old && sdata->default_multicast_key == old;
254 defmgmtkey = old && sdata->default_mgmt_key == old; 262 defmgmtkey = old && sdata->default_mgmt_key == old;
255 263
256 if (defkey && !new) 264 if (defunikey && !new)
257 __ieee80211_set_default_key(sdata, -1); 265 __ieee80211_set_default_key(sdata, -1, true, false);
266 if (defmultikey && !new)
267 __ieee80211_set_default_key(sdata, -1, false, true);
258 if (defmgmtkey && !new) 268 if (defmgmtkey && !new)
259 __ieee80211_set_default_mgmt_key(sdata, -1); 269 __ieee80211_set_default_mgmt_key(sdata, -1);
260 270
261 rcu_assign_pointer(sdata->keys[idx], new); 271 rcu_assign_pointer(sdata->keys[idx], new);
262 if (defkey && new) 272 if (defunikey && new)
263 __ieee80211_set_default_key(sdata, new->conf.keyidx); 273 __ieee80211_set_default_key(sdata, new->conf.keyidx,
274 true, false);
275 if (defmultikey && new)
276 __ieee80211_set_default_key(sdata, new->conf.keyidx,
277 false, true);
264 if (defmgmtkey && new) 278 if (defmgmtkey && new)
265 __ieee80211_set_default_mgmt_key(sdata, 279 __ieee80211_set_default_mgmt_key(sdata,
266 new->conf.keyidx); 280 new->conf.keyidx);
267 } 281 }
268 282
269 if (old) { 283 if (old)
270 /* 284 list_del(&old->list);
271 * We'll use an empty list to indicate that the key
272 * has already been removed.
273 */
274 list_del_init(&old->list);
275 }
276} 285}
277 286
278struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 287struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
@@ -366,6 +375,12 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
366 if (!key) 375 if (!key)
367 return; 376 return;
368 377
378 /*
379 * Synchronize so the TX path can no longer be using
380 * this key before we free/remove it.
381 */
382 synchronize_rcu();
383
369 if (key->local) 384 if (key->local)
370 ieee80211_key_disable_hw_accel(key); 385 ieee80211_key_disable_hw_accel(key);
371 386
@@ -407,8 +422,8 @@ int ieee80211_key_link(struct ieee80211_key *key,
407 struct sta_info *ap; 422 struct sta_info *ap;
408 423
409 /* 424 /*
410 * We're getting a sta pointer in, 425 * We're getting a sta pointer in, so must be under
411 * so must be under RCU read lock. 426 * appropriate locking for sta_info_get().
412 */ 427 */
413 428
414 /* same here, the AP could be using QoS */ 429 /* same here, the AP could be using QoS */
@@ -502,11 +517,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
502 517
503 mutex_lock(&sdata->local->key_mtx); 518 mutex_lock(&sdata->local->key_mtx);
504 519
505 ieee80211_debugfs_key_remove_default(sdata);
506 ieee80211_debugfs_key_remove_mgmt_default(sdata); 520 ieee80211_debugfs_key_remove_mgmt_default(sdata);
507 521
508 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 522 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
509 __ieee80211_key_free(key); 523 __ieee80211_key_free(key);
510 524
525 ieee80211_debugfs_key_update_default(sdata);
526
511 mutex_unlock(&sdata->local->key_mtx); 527 mutex_unlock(&sdata->local->key_mtx);
512} 528}