aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/key.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/mac80211/key.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r--net/mac80211/key.c291
1 files changed, 178 insertions, 113 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 1b9d87ed143a..f825e2f0a57e 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -30,26 +30,27 @@
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 };
49 50
50static void assert_key_lock(struct ieee80211_local *local) 51static void assert_key_lock(struct ieee80211_local *local)
51{ 52{
52 WARN_ON(!mutex_is_locked(&local->key_mtx)); 53 lockdep_assert_held(&local->key_mtx);
53} 54}
54 55
55static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) 56static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
@@ -60,7 +61,7 @@ static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
60 return NULL; 61 return NULL;
61} 62}
62 63
63static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) 64static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
64{ 65{
65 struct ieee80211_sub_if_data *sdata; 66 struct ieee80211_sub_if_data *sdata;
66 struct ieee80211_sta *sta; 67 struct ieee80211_sta *sta;
@@ -69,28 +70,57 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
69 might_sleep(); 70 might_sleep();
70 71
71 if (!key->local->ops->set_key) 72 if (!key->local->ops->set_key)
72 return; 73 goto out_unsupported;
73 74
74 assert_key_lock(key->local); 75 assert_key_lock(key->local);
75 76
76 sta = get_sta_for_key(key); 77 sta = get_sta_for_key(key);
77 78
79 /*
80 * If this is a per-STA GTK, check if it
81 * is supported; if not, return.
82 */
83 if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
84 !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
85 goto out_unsupported;
86
78 sdata = key->sdata; 87 sdata = key->sdata;
79 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;
80 sdata = container_of(sdata->bss, 95 sdata = container_of(sdata->bss,
81 struct ieee80211_sub_if_data, 96 struct ieee80211_sub_if_data,
82 u.ap); 97 u.ap);
98 }
83 99
84 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);
85 101
86 if (!ret) 102 if (!ret) {
87 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 103 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
104 return 0;
105 }
88 106
89 if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) 107 if (ret != -ENOSPC && ret != -EOPNOTSUPP)
90 printk(KERN_ERR "mac80211-%s: failed to set key " 108 wiphy_err(key->local->hw.wiphy,
91 "(%d, %pM) to hardware (%d)\n", 109 "failed to set key (%d, %pM) to hardware (%d)\n",
92 wiphy_name(key->local->hw.wiphy), 110 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
93 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); 111
112 out_unsupported:
113 switch (key->conf.cipher) {
114 case WLAN_CIPHER_SUITE_WEP40:
115 case WLAN_CIPHER_SUITE_WEP104:
116 case WLAN_CIPHER_SUITE_TKIP:
117 case WLAN_CIPHER_SUITE_CCMP:
118 case WLAN_CIPHER_SUITE_AES_CMAC:
119 /* all of these we can do in software */
120 return 0;
121 default:
122 return -EINVAL;
123 }
94} 124}
95 125
96static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) 126static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
@@ -121,36 +151,56 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
121 sta, &key->conf); 151 sta, &key->conf);
122 152
123 if (ret) 153 if (ret)
124 printk(KERN_ERR "mac80211-%s: failed to remove key " 154 wiphy_err(key->local->hw.wiphy,
125 "(%d, %pM) from hardware (%d)\n", 155 "failed to remove key (%d, %pM) from hardware (%d)\n",
126 wiphy_name(key->local->hw.wiphy), 156 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
127 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
128 157
129 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 158 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
130} 159}
131 160
161void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
162{
163 struct ieee80211_key *key;
164
165 key = container_of(key_conf, struct ieee80211_key, conf);
166
167 might_sleep();
168 assert_key_lock(key->local);
169
170 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
171
172 /*
173 * Flush TX path to avoid attempts to use this key
174 * after this function returns. Until then, drivers
175 * must be prepared to handle the key.
176 */
177 synchronize_rcu();
178}
179EXPORT_SYMBOL_GPL(ieee80211_key_removed);
180
132static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 181static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
133 int idx) 182 int idx, bool uni, bool multi)
134{ 183{
135 struct ieee80211_key *key = NULL; 184 struct ieee80211_key *key = NULL;
136 185
137 assert_key_lock(sdata->local); 186 assert_key_lock(sdata->local);
138 187
139 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 188 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
140 key = sdata->keys[idx]; 189 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
141 190
142 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);
143 195
144 if (key) { 196 ieee80211_debugfs_key_update_default(sdata);
145 ieee80211_debugfs_key_remove_default(key->sdata);
146 ieee80211_debugfs_key_add_default(key->sdata);
147 }
148} 197}
149 198
150void 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)
151{ 201{
152 mutex_lock(&sdata->local->key_mtx); 202 mutex_lock(&sdata->local->key_mtx);
153 __ieee80211_set_default_key(sdata, idx); 203 __ieee80211_set_default_key(sdata, idx, uni, multi);
154 mutex_unlock(&sdata->local->key_mtx); 204 mutex_unlock(&sdata->local->key_mtx);
155} 205}
156 206
@@ -163,14 +213,11 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
163 213
164 if (idx >= NUM_DEFAULT_KEYS && 214 if (idx >= NUM_DEFAULT_KEYS &&
165 idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 215 idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
166 key = sdata->keys[idx]; 216 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
167 217
168 rcu_assign_pointer(sdata->default_mgmt_key, key); 218 rcu_assign_pointer(sdata->default_mgmt_key, key);
169 219
170 if (key) { 220 ieee80211_debugfs_key_update_default(sdata);
171 ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
172 ieee80211_debugfs_key_add_mgmt_default(key->sdata);
173 }
174} 221}
175 222
176void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 223void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -184,16 +231,24 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
184 231
185static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, 232static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
186 struct sta_info *sta, 233 struct sta_info *sta,
234 bool pairwise,
187 struct ieee80211_key *old, 235 struct ieee80211_key *old,
188 struct ieee80211_key *new) 236 struct ieee80211_key *new)
189{ 237{
190 int idx, defkey, defmgmtkey; 238 int idx;
239 bool defunikey, defmultikey, defmgmtkey;
191 240
192 if (new) 241 if (new)
193 list_add(&new->list, &sdata->key_list); 242 list_add(&new->list, &sdata->key_list);
194 243
195 if (sta) { 244 if (sta && pairwise) {
196 rcu_assign_pointer(sta->key, new); 245 rcu_assign_pointer(sta->ptk, new);
246 } else if (sta) {
247 if (old)
248 idx = old->conf.keyidx;
249 else
250 idx = new->conf.keyidx;
251 rcu_assign_pointer(sta->gtk[idx], new);
197 } else { 252 } else {
198 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); 253 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
199 254
@@ -202,45 +257,51 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
202 else 257 else
203 idx = new->conf.keyidx; 258 idx = new->conf.keyidx;
204 259
205 defkey = old && sdata->default_key == old; 260 defunikey = old &&
206 defmgmtkey = old && sdata->default_mgmt_key == old; 261 old == key_mtx_dereference(sdata->local,
207 262 sdata->default_unicast_key);
208 if (defkey && !new) 263 defmultikey = old &&
209 __ieee80211_set_default_key(sdata, -1); 264 old == key_mtx_dereference(sdata->local,
265 sdata->default_multicast_key);
266 defmgmtkey = old &&
267 old == key_mtx_dereference(sdata->local,
268 sdata->default_mgmt_key);
269
270 if (defunikey && !new)
271 __ieee80211_set_default_key(sdata, -1, true, false);
272 if (defmultikey && !new)
273 __ieee80211_set_default_key(sdata, -1, false, true);
210 if (defmgmtkey && !new) 274 if (defmgmtkey && !new)
211 __ieee80211_set_default_mgmt_key(sdata, -1); 275 __ieee80211_set_default_mgmt_key(sdata, -1);
212 276
213 rcu_assign_pointer(sdata->keys[idx], new); 277 rcu_assign_pointer(sdata->keys[idx], new);
214 if (defkey && new) 278 if (defunikey && new)
215 __ieee80211_set_default_key(sdata, new->conf.keyidx); 279 __ieee80211_set_default_key(sdata, new->conf.keyidx,
280 true, false);
281 if (defmultikey && new)
282 __ieee80211_set_default_key(sdata, new->conf.keyidx,
283 false, true);
216 if (defmgmtkey && new) 284 if (defmgmtkey && new)
217 __ieee80211_set_default_mgmt_key(sdata, 285 __ieee80211_set_default_mgmt_key(sdata,
218 new->conf.keyidx); 286 new->conf.keyidx);
219 } 287 }
220 288
221 if (old) { 289 if (old)
222 /* 290 list_del(&old->list);
223 * We'll use an empty list to indicate that the key
224 * has already been removed.
225 */
226 list_del_init(&old->list);
227 }
228} 291}
229 292
230struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, 293struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
231 int idx,
232 size_t key_len,
233 const u8 *key_data, 294 const u8 *key_data,
234 size_t seq_len, const u8 *seq) 295 size_t seq_len, const u8 *seq)
235{ 296{
236 struct ieee80211_key *key; 297 struct ieee80211_key *key;
237 int i, j; 298 int i, j, err;
238 299
239 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); 300 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
240 301
241 key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); 302 key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
242 if (!key) 303 if (!key)
243 return NULL; 304 return ERR_PTR(-ENOMEM);
244 305
245 /* 306 /*
246 * Default to software encryption; we'll later upload the 307 * Default to software encryption; we'll later upload the
@@ -249,15 +310,16 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
249 key->conf.flags = 0; 310 key->conf.flags = 0;
250 key->flags = 0; 311 key->flags = 0;
251 312
252 key->conf.alg = alg; 313 key->conf.cipher = cipher;
253 key->conf.keyidx = idx; 314 key->conf.keyidx = idx;
254 key->conf.keylen = key_len; 315 key->conf.keylen = key_len;
255 switch (alg) { 316 switch (cipher) {
256 case ALG_WEP: 317 case WLAN_CIPHER_SUITE_WEP40:
318 case WLAN_CIPHER_SUITE_WEP104:
257 key->conf.iv_len = WEP_IV_LEN; 319 key->conf.iv_len = WEP_IV_LEN;
258 key->conf.icv_len = WEP_ICV_LEN; 320 key->conf.icv_len = WEP_ICV_LEN;
259 break; 321 break;
260 case ALG_TKIP: 322 case WLAN_CIPHER_SUITE_TKIP:
261 key->conf.iv_len = TKIP_IV_LEN; 323 key->conf.iv_len = TKIP_IV_LEN;
262 key->conf.icv_len = TKIP_ICV_LEN; 324 key->conf.icv_len = TKIP_ICV_LEN;
263 if (seq) { 325 if (seq) {
@@ -269,7 +331,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
269 } 331 }
270 } 332 }
271 break; 333 break;
272 case ALG_CCMP: 334 case WLAN_CIPHER_SUITE_CCMP:
273 key->conf.iv_len = CCMP_HDR_LEN; 335 key->conf.iv_len = CCMP_HDR_LEN;
274 key->conf.icv_len = CCMP_MIC_LEN; 336 key->conf.icv_len = CCMP_MIC_LEN;
275 if (seq) { 337 if (seq) {
@@ -278,42 +340,38 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
278 key->u.ccmp.rx_pn[i][j] = 340 key->u.ccmp.rx_pn[i][j] =
279 seq[CCMP_PN_LEN - j - 1]; 341 seq[CCMP_PN_LEN - j - 1];
280 } 342 }
281 break;
282 case ALG_AES_CMAC:
283 key->conf.iv_len = 0;
284 key->conf.icv_len = sizeof(struct ieee80211_mmie);
285 if (seq)
286 for (j = 0; j < 6; j++)
287 key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
288 break;
289 }
290 memcpy(key->conf.key, key_data, key_len);
291 INIT_LIST_HEAD(&key->list);
292
293 if (alg == ALG_CCMP) {
294 /* 343 /*
295 * Initialize AES key state here as an optimization so that 344 * Initialize AES key state here as an optimization so that
296 * it does not need to be initialized for every packet. 345 * it does not need to be initialized for every packet.
297 */ 346 */
298 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data); 347 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
299 if (!key->u.ccmp.tfm) { 348 if (IS_ERR(key->u.ccmp.tfm)) {
349 err = PTR_ERR(key->u.ccmp.tfm);
300 kfree(key); 350 kfree(key);
301 return NULL; 351 return ERR_PTR(err);
302 } 352 }
303 } 353 break;
304 354 case WLAN_CIPHER_SUITE_AES_CMAC:
305 if (alg == ALG_AES_CMAC) { 355 key->conf.iv_len = 0;
356 key->conf.icv_len = sizeof(struct ieee80211_mmie);
357 if (seq)
358 for (j = 0; j < 6; j++)
359 key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
306 /* 360 /*
307 * Initialize AES key state here as an optimization so that 361 * Initialize AES key state here as an optimization so that
308 * it does not need to be initialized for every packet. 362 * it does not need to be initialized for every packet.
309 */ 363 */
310 key->u.aes_cmac.tfm = 364 key->u.aes_cmac.tfm =
311 ieee80211_aes_cmac_key_setup(key_data); 365 ieee80211_aes_cmac_key_setup(key_data);
312 if (!key->u.aes_cmac.tfm) { 366 if (IS_ERR(key->u.aes_cmac.tfm)) {
367 err = PTR_ERR(key->u.aes_cmac.tfm);
313 kfree(key); 368 kfree(key);
314 return NULL; 369 return ERR_PTR(err);
315 } 370 }
371 break;
316 } 372 }
373 memcpy(key->conf.key, key_data, key_len);
374 INIT_LIST_HEAD(&key->list);
317 375
318 return key; 376 return key;
319} 377}
@@ -323,12 +381,18 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
323 if (!key) 381 if (!key)
324 return; 382 return;
325 383
384 /*
385 * Synchronize so the TX path can no longer be using
386 * this key before we free/remove it.
387 */
388 synchronize_rcu();
389
326 if (key->local) 390 if (key->local)
327 ieee80211_key_disable_hw_accel(key); 391 ieee80211_key_disable_hw_accel(key);
328 392
329 if (key->conf.alg == ALG_CCMP) 393 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
330 ieee80211_aes_key_free(key->u.ccmp.tfm); 394 ieee80211_aes_key_free(key->u.ccmp.tfm);
331 if (key->conf.alg == ALG_AES_CMAC) 395 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
332 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); 396 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
333 if (key->local) 397 if (key->local)
334 ieee80211_debugfs_key_remove(key); 398 ieee80211_debugfs_key_remove(key);
@@ -336,16 +400,18 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
336 kfree(key); 400 kfree(key);
337} 401}
338 402
339void ieee80211_key_link(struct ieee80211_key *key, 403int ieee80211_key_link(struct ieee80211_key *key,
340 struct ieee80211_sub_if_data *sdata, 404 struct ieee80211_sub_if_data *sdata,
341 struct sta_info *sta) 405 struct sta_info *sta)
342{ 406{
343 struct ieee80211_key *old_key; 407 struct ieee80211_key *old_key;
344 int idx; 408 int idx, ret;
409 bool pairwise;
345 410
346 BUG_ON(!sdata); 411 BUG_ON(!sdata);
347 BUG_ON(!key); 412 BUG_ON(!key);
348 413
414 pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
349 idx = key->conf.keyidx; 415 idx = key->conf.keyidx;
350 key->local = sdata->local; 416 key->local = sdata->local;
351 key->sdata = sdata; 417 key->sdata = sdata;
@@ -358,20 +424,13 @@ void ieee80211_key_link(struct ieee80211_key *key,
358 */ 424 */
359 if (test_sta_flags(sta, WLAN_STA_WME)) 425 if (test_sta_flags(sta, WLAN_STA_WME))
360 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; 426 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
361
362 /*
363 * This key is for a specific sta interface,
364 * inform the driver that it should try to store
365 * this key as pairwise key.
366 */
367 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
368 } else { 427 } else {
369 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 428 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
370 struct sta_info *ap; 429 struct sta_info *ap;
371 430
372 /* 431 /*
373 * We're getting a sta pointer in, 432 * We're getting a sta pointer in, so must be under
374 * so must be under RCU read lock. 433 * appropriate locking for sta_info_get().
375 */ 434 */
376 435
377 /* same here, the AP could be using QoS */ 436 /* same here, the AP could be using QoS */
@@ -386,38 +445,43 @@ void ieee80211_key_link(struct ieee80211_key *key,
386 445
387 mutex_lock(&sdata->local->key_mtx); 446 mutex_lock(&sdata->local->key_mtx);
388 447
389 if (sta) 448 if (sta && pairwise)
390 old_key = sta->key; 449 old_key = key_mtx_dereference(sdata->local, sta->ptk);
450 else if (sta)
451 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
391 else 452 else
392 old_key = sdata->keys[idx]; 453 old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
393 454
394 __ieee80211_key_replace(sdata, sta, old_key, key); 455 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
395 __ieee80211_key_destroy(old_key); 456 __ieee80211_key_destroy(old_key);
396 457
397 ieee80211_debugfs_key_add(key); 458 ieee80211_debugfs_key_add(key);
398 459
399 ieee80211_key_enable_hw_accel(key); 460 ret = ieee80211_key_enable_hw_accel(key);
400 461
401 mutex_unlock(&sdata->local->key_mtx); 462 mutex_unlock(&sdata->local->key_mtx);
463
464 return ret;
402} 465}
403 466
404static void __ieee80211_key_free(struct ieee80211_key *key) 467void __ieee80211_key_free(struct ieee80211_key *key)
405{ 468{
469 if (!key)
470 return;
471
406 /* 472 /*
407 * Replace key with nothingness if it was ever used. 473 * Replace key with nothingness if it was ever used.
408 */ 474 */
409 if (key->sdata) 475 if (key->sdata)
410 __ieee80211_key_replace(key->sdata, key->sta, 476 __ieee80211_key_replace(key->sdata, key->sta,
411 key, NULL); 477 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
478 key, NULL);
412 __ieee80211_key_destroy(key); 479 __ieee80211_key_destroy(key);
413} 480}
414 481
415void ieee80211_key_free(struct ieee80211_local *local, 482void ieee80211_key_free(struct ieee80211_local *local,
416 struct ieee80211_key *key) 483 struct ieee80211_key *key)
417{ 484{
418 if (!key)
419 return;
420
421 mutex_lock(&local->key_mtx); 485 mutex_lock(&local->key_mtx);
422 __ieee80211_key_free(key); 486 __ieee80211_key_free(key);
423 mutex_unlock(&local->key_mtx); 487 mutex_unlock(&local->key_mtx);
@@ -460,11 +524,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
460 524
461 mutex_lock(&sdata->local->key_mtx); 525 mutex_lock(&sdata->local->key_mtx);
462 526
463 ieee80211_debugfs_key_remove_default(sdata);
464 ieee80211_debugfs_key_remove_mgmt_default(sdata); 527 ieee80211_debugfs_key_remove_mgmt_default(sdata);
465 528
466 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 529 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
467 __ieee80211_key_free(key); 530 __ieee80211_key_free(key);
468 531
532 ieee80211_debugfs_key_update_default(sdata);
533
469 mutex_unlock(&sdata->local->key_mtx); 534 mutex_unlock(&sdata->local->key_mtx);
470} 535}