Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/mac80211/key.c
15109 views
1
/*
2
* Copyright 2002-2005, Instant802 Networks, Inc.
3
* Copyright 2005-2006, Devicescape Software, Inc.
4
* Copyright 2006-2007 Jiri Benc <[email protected]>
5
* Copyright 2007-2008 Johannes Berg <[email protected]>
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License version 2 as
9
* published by the Free Software Foundation.
10
*/
11
12
#include <linux/if_ether.h>
13
#include <linux/etherdevice.h>
14
#include <linux/list.h>
15
#include <linux/rcupdate.h>
16
#include <linux/rtnetlink.h>
17
#include <linux/slab.h>
18
#include <net/mac80211.h>
19
#include "ieee80211_i.h"
20
#include "driver-ops.h"
21
#include "debugfs_key.h"
22
#include "aes_ccm.h"
23
#include "aes_cmac.h"
24
25
26
/**
27
* DOC: Key handling basics
28
*
29
* Key handling in mac80211 is done based on per-interface (sub_if_data)
30
* keys and per-station keys. Since each station belongs to an interface,
31
* each station key also belongs to that interface.
32
*
33
* Hardware acceleration is done on a best-effort basis for algorithms
34
* that are implemented in software, for each key the hardware is asked
35
* to enable that key for offloading but if it cannot do that the key is
36
* simply kept for software encryption (unless it is for an algorithm
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.
40
*
41
* All key management is internally protected by a mutex. Within all
42
* other parts of mac80211, key references are, just as STA structure
43
* references, protected by RCU. Note, however, that some things are
44
* unprotected, namely the key->sta dereferences within the hardware
45
* acceleration functions. This means that sta_info_destroy() must
46
* remove the key which waits for an RCU grace period.
47
*/
48
49
static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
50
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)
57
{
58
if (key->sta)
59
return &key->sta->sta;
60
61
return NULL;
62
}
63
64
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
65
{
66
struct ieee80211_sub_if_data *sdata;
67
struct ieee80211_sta *sta;
68
int ret;
69
70
might_sleep();
71
72
if (!key->local->ops->set_key)
73
goto out_unsupported;
74
75
assert_key_lock(key->local);
76
77
sta = get_sta_for_key(key);
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
87
sdata = key->sdata;
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;
95
sdata = container_of(sdata->bss,
96
struct ieee80211_sub_if_data,
97
u.ap);
98
}
99
100
ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
101
102
if (!ret) {
103
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
104
return 0;
105
}
106
107
if (ret != -ENOSPC && ret != -EOPNOTSUPP)
108
wiphy_err(key->local->hw.wiphy,
109
"failed to set key (%d, %pM) to hardware (%d)\n",
110
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
}
124
}
125
126
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
127
{
128
struct ieee80211_sub_if_data *sdata;
129
struct ieee80211_sta *sta;
130
int ret;
131
132
might_sleep();
133
134
if (!key || !key->local->ops->set_key)
135
return;
136
137
assert_key_lock(key->local);
138
139
if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
140
return;
141
142
sta = get_sta_for_key(key);
143
sdata = key->sdata;
144
145
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
146
sdata = container_of(sdata->bss,
147
struct ieee80211_sub_if_data,
148
u.ap);
149
150
ret = drv_set_key(key->local, DISABLE_KEY, sdata,
151
sta, &key->conf);
152
153
if (ret)
154
wiphy_err(key->local->hw.wiphy,
155
"failed to remove key (%d, %pM) from hardware (%d)\n",
156
key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
157
158
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
159
}
160
161
void 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
}
179
EXPORT_SYMBOL_GPL(ieee80211_key_removed);
180
181
static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
182
int idx, bool uni, bool multi)
183
{
184
struct ieee80211_key *key = NULL;
185
186
assert_key_lock(sdata->local);
187
188
if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
189
key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
190
191
if (uni)
192
rcu_assign_pointer(sdata->default_unicast_key, key);
193
if (multi)
194
rcu_assign_pointer(sdata->default_multicast_key, key);
195
196
ieee80211_debugfs_key_update_default(sdata);
197
}
198
199
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
200
bool uni, bool multi)
201
{
202
mutex_lock(&sdata->local->key_mtx);
203
__ieee80211_set_default_key(sdata, idx, uni, multi);
204
mutex_unlock(&sdata->local->key_mtx);
205
}
206
207
static void
208
__ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
209
{
210
struct ieee80211_key *key = NULL;
211
212
assert_key_lock(sdata->local);
213
214
if (idx >= NUM_DEFAULT_KEYS &&
215
idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
216
key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
217
218
rcu_assign_pointer(sdata->default_mgmt_key, key);
219
220
ieee80211_debugfs_key_update_default(sdata);
221
}
222
223
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
224
int idx)
225
{
226
mutex_lock(&sdata->local->key_mtx);
227
__ieee80211_set_default_mgmt_key(sdata, idx);
228
mutex_unlock(&sdata->local->key_mtx);
229
}
230
231
232
static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
233
struct sta_info *sta,
234
bool pairwise,
235
struct ieee80211_key *old,
236
struct ieee80211_key *new)
237
{
238
int idx;
239
bool defunikey, defmultikey, defmgmtkey;
240
241
if (new)
242
list_add(&new->list, &sdata->key_list);
243
244
if (sta && pairwise) {
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);
252
} else {
253
WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
254
255
if (old)
256
idx = old->conf.keyidx;
257
else
258
idx = new->conf.keyidx;
259
260
defunikey = old &&
261
old == key_mtx_dereference(sdata->local,
262
sdata->default_unicast_key);
263
defmultikey = old &&
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);
274
if (defmgmtkey && !new)
275
__ieee80211_set_default_mgmt_key(sdata, -1);
276
277
rcu_assign_pointer(sdata->keys[idx], new);
278
if (defunikey && new)
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);
284
if (defmgmtkey && new)
285
__ieee80211_set_default_mgmt_key(sdata,
286
new->conf.keyidx);
287
}
288
289
if (old)
290
list_del(&old->list);
291
}
292
293
struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
294
const u8 *key_data,
295
size_t seq_len, const u8 *seq)
296
{
297
struct ieee80211_key *key;
298
int i, j, err;
299
300
BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
301
302
key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
303
if (!key)
304
return ERR_PTR(-ENOMEM);
305
306
/*
307
* Default to software encryption; we'll later upload the
308
* key to the hardware if possible.
309
*/
310
key->conf.flags = 0;
311
key->flags = 0;
312
313
key->conf.cipher = cipher;
314
key->conf.keyidx = idx;
315
key->conf.keylen = key_len;
316
switch (cipher) {
317
case WLAN_CIPHER_SUITE_WEP40:
318
case WLAN_CIPHER_SUITE_WEP104:
319
key->conf.iv_len = WEP_IV_LEN;
320
key->conf.icv_len = WEP_ICV_LEN;
321
break;
322
case WLAN_CIPHER_SUITE_TKIP:
323
key->conf.iv_len = TKIP_IV_LEN;
324
key->conf.icv_len = TKIP_ICV_LEN;
325
if (seq) {
326
for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
327
key->u.tkip.rx[i].iv32 =
328
get_unaligned_le32(&seq[2]);
329
key->u.tkip.rx[i].iv16 =
330
get_unaligned_le16(seq);
331
}
332
}
333
break;
334
case WLAN_CIPHER_SUITE_CCMP:
335
key->conf.iv_len = CCMP_HDR_LEN;
336
key->conf.icv_len = CCMP_MIC_LEN;
337
if (seq) {
338
for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++)
339
for (j = 0; j < CCMP_PN_LEN; j++)
340
key->u.ccmp.rx_pn[i][j] =
341
seq[CCMP_PN_LEN - j - 1];
342
}
343
/*
344
* Initialize AES key state here as an optimization so that
345
* it does not need to be initialized for every packet.
346
*/
347
key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
348
if (IS_ERR(key->u.ccmp.tfm)) {
349
err = PTR_ERR(key->u.ccmp.tfm);
350
kfree(key);
351
return ERR_PTR(err);
352
}
353
break;
354
case WLAN_CIPHER_SUITE_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];
360
/*
361
* Initialize AES key state here as an optimization so that
362
* it does not need to be initialized for every packet.
363
*/
364
key->u.aes_cmac.tfm =
365
ieee80211_aes_cmac_key_setup(key_data);
366
if (IS_ERR(key->u.aes_cmac.tfm)) {
367
err = PTR_ERR(key->u.aes_cmac.tfm);
368
kfree(key);
369
return ERR_PTR(err);
370
}
371
break;
372
}
373
memcpy(key->conf.key, key_data, key_len);
374
INIT_LIST_HEAD(&key->list);
375
376
return key;
377
}
378
379
static void __ieee80211_key_destroy(struct ieee80211_key *key)
380
{
381
if (!key)
382
return;
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
390
if (key->local)
391
ieee80211_key_disable_hw_accel(key);
392
393
if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
394
ieee80211_aes_key_free(key->u.ccmp.tfm);
395
if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
396
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
397
if (key->local)
398
ieee80211_debugfs_key_remove(key);
399
400
kfree(key);
401
}
402
403
int ieee80211_key_link(struct ieee80211_key *key,
404
struct ieee80211_sub_if_data *sdata,
405
struct sta_info *sta)
406
{
407
struct ieee80211_key *old_key;
408
int idx, ret;
409
bool pairwise;
410
411
BUG_ON(!sdata);
412
BUG_ON(!key);
413
414
pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
415
idx = key->conf.keyidx;
416
key->local = sdata->local;
417
key->sdata = sdata;
418
key->sta = sta;
419
420
if (sta) {
421
/*
422
* some hardware cannot handle TKIP with QoS, so
423
* we indicate whether QoS could be in use.
424
*/
425
if (test_sta_flags(sta, WLAN_STA_WME))
426
key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
427
} else {
428
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
429
struct sta_info *ap;
430
431
/*
432
* We're getting a sta pointer in, so must be under
433
* appropriate locking for sta_info_get().
434
*/
435
436
/* same here, the AP could be using QoS */
437
ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
438
if (ap) {
439
if (test_sta_flags(ap, WLAN_STA_WME))
440
key->conf.flags |=
441
IEEE80211_KEY_FLAG_WMM_STA;
442
}
443
}
444
}
445
446
mutex_lock(&sdata->local->key_mtx);
447
448
if (sta && pairwise)
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]);
452
else
453
old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
454
455
__ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
456
__ieee80211_key_destroy(old_key);
457
458
ieee80211_debugfs_key_add(key);
459
460
ret = ieee80211_key_enable_hw_accel(key);
461
462
mutex_unlock(&sdata->local->key_mtx);
463
464
return ret;
465
}
466
467
void __ieee80211_key_free(struct ieee80211_key *key)
468
{
469
if (!key)
470
return;
471
472
/*
473
* Replace key with nothingness if it was ever used.
474
*/
475
if (key->sdata)
476
__ieee80211_key_replace(key->sdata, key->sta,
477
key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
478
key, NULL);
479
__ieee80211_key_destroy(key);
480
}
481
482
void ieee80211_key_free(struct ieee80211_local *local,
483
struct ieee80211_key *key)
484
{
485
mutex_lock(&local->key_mtx);
486
__ieee80211_key_free(key);
487
mutex_unlock(&local->key_mtx);
488
}
489
490
void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
491
{
492
struct ieee80211_key *key;
493
494
ASSERT_RTNL();
495
496
if (WARN_ON(!ieee80211_sdata_running(sdata)))
497
return;
498
499
mutex_lock(&sdata->local->key_mtx);
500
501
list_for_each_entry(key, &sdata->key_list, list)
502
ieee80211_key_enable_hw_accel(key);
503
504
mutex_unlock(&sdata->local->key_mtx);
505
}
506
507
void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
508
{
509
struct ieee80211_key *key;
510
511
ASSERT_RTNL();
512
513
mutex_lock(&sdata->local->key_mtx);
514
515
list_for_each_entry(key, &sdata->key_list, list)
516
ieee80211_key_disable_hw_accel(key);
517
518
mutex_unlock(&sdata->local->key_mtx);
519
}
520
521
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
522
{
523
struct ieee80211_key *key, *tmp;
524
525
mutex_lock(&sdata->local->key_mtx);
526
527
ieee80211_debugfs_key_remove_mgmt_default(sdata);
528
529
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
530
__ieee80211_key_free(key);
531
532
ieee80211_debugfs_key_update_default(sdata);
533
534
mutex_unlock(&sdata->local->key_mtx);
535
}
536
537