cfg80211: allow vendor specific cipher suites
[deliverable/linux.git] / net / mac80211 / key.c
CommitLineData
1f5a7e47
JB
1/*
2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
3b96766f 5 * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
1f5a7e47
JB
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
11a843b7
JB
12#include <linux/if_ether.h>
13#include <linux/etherdevice.h>
14#include <linux/list.h>
d4e46a3d 15#include <linux/rcupdate.h>
db4d1169 16#include <linux/rtnetlink.h>
5a0e3ad6 17#include <linux/slab.h>
1f5a7e47
JB
18#include <net/mac80211.h>
19#include "ieee80211_i.h"
24487981 20#include "driver-ops.h"
1f5a7e47
JB
21#include "debugfs_key.h"
22#include "aes_ccm.h"
3cfcf6ac 23#include "aes_cmac.h"
1f5a7e47 24
11a843b7 25
dbbea671
JB
26/**
27 * DOC: Key handling basics
11a843b7
JB
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 each key
34 * that is eligible the hardware is asked to enable that key but if
35 * it cannot do that they key is simply kept for software encryption.
36 * There is currently no way of knowing this except by looking into
37 * debugfs.
38 *
ad0e2b5a 39 * All key operations are protected internally.
db4d1169 40 *
3b96766f
JB
41 * Within mac80211, key references are, just as STA structure references,
42 * protected by RCU. Note, however, that some things are unprotected,
43 * namely the key->sta dereferences within the hardware acceleration
ad0e2b5a
JB
44 * functions. This means that sta_info_destroy() must remove the key
45 * which waits for an RCU grace period.
11a843b7
JB
46 */
47
48static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
11a843b7 49
ad0e2b5a 50static void assert_key_lock(struct ieee80211_local *local)
3b96766f 51{
ad0e2b5a 52 WARN_ON(!mutex_is_locked(&local->key_mtx));
3b96766f
JB
53}
54
dc822b5d 55static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
11a843b7 56{
11a843b7 57 if (key->sta)
dc822b5d 58 return &key->sta->sta;
11a843b7 59
dc822b5d 60 return NULL;
11a843b7
JB
61}
62
63static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
64{
dc822b5d
JB
65 struct ieee80211_sub_if_data *sdata;
66 struct ieee80211_sta *sta;
11a843b7
JB
67 int ret;
68
3b96766f
JB
69 might_sleep();
70
11a843b7
JB
71 if (!key->local->ops->set_key)
72 return;
73
ad0e2b5a
JB
74 assert_key_lock(key->local);
75
dc822b5d
JB
76 sta = get_sta_for_key(key);
77
78 sdata = key->sdata;
79 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
80 sdata = container_of(sdata->bss,
81 struct ieee80211_sub_if_data,
82 u.ap);
11a843b7 83
12375ef9 84 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
11a843b7 85
ad0e2b5a 86 if (!ret)
11a843b7
JB
87 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
88
89 if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
0fb9a9ec
JP
90 wiphy_err(key->local->hw.wiphy,
91 "failed to set key (%d, %pM) to hardware (%d)\n",
92 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
11a843b7
JB
93}
94
95static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
96{
dc822b5d
JB
97 struct ieee80211_sub_if_data *sdata;
98 struct ieee80211_sta *sta;
11a843b7
JB
99 int ret;
100
3b96766f
JB
101 might_sleep();
102
db4d1169 103 if (!key || !key->local->ops->set_key)
11a843b7
JB
104 return;
105
ad0e2b5a
JB
106 assert_key_lock(key->local);
107
108 if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
11a843b7
JB
109 return;
110
dc822b5d
JB
111 sta = get_sta_for_key(key);
112 sdata = key->sdata;
113
114 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
115 sdata = container_of(sdata->bss,
116 struct ieee80211_sub_if_data,
117 u.ap);
11a843b7 118
12375ef9 119 ret = drv_set_key(key->local, DISABLE_KEY, sdata,
24487981 120 sta, &key->conf);
11a843b7
JB
121
122 if (ret)
0fb9a9ec
JP
123 wiphy_err(key->local->hw.wiphy,
124 "failed to remove key (%d, %pM) from hardware (%d)\n",
125 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
11a843b7 126
3b96766f 127 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
3b96766f
JB
128}
129
130static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
131 int idx)
132{
133 struct ieee80211_key *key = NULL;
134
ad0e2b5a
JB
135 assert_key_lock(sdata->local);
136
3b96766f
JB
137 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
138 key = sdata->keys[idx];
139
140 rcu_assign_pointer(sdata->default_key, key);
141
ad0e2b5a
JB
142 if (key) {
143 ieee80211_debugfs_key_remove_default(key->sdata);
144 ieee80211_debugfs_key_add_default(key->sdata);
145 }
3b96766f
JB
146}
147
148void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx)
149{
ad0e2b5a 150 mutex_lock(&sdata->local->key_mtx);
3b96766f 151 __ieee80211_set_default_key(sdata, idx);
ad0e2b5a 152 mutex_unlock(&sdata->local->key_mtx);
3b96766f
JB
153}
154
3cfcf6ac
JM
155static void
156__ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
157{
158 struct ieee80211_key *key = NULL;
159
ad0e2b5a
JB
160 assert_key_lock(sdata->local);
161
3cfcf6ac
JM
162 if (idx >= NUM_DEFAULT_KEYS &&
163 idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
164 key = sdata->keys[idx];
165
166 rcu_assign_pointer(sdata->default_mgmt_key, key);
167
ad0e2b5a
JB
168 if (key) {
169 ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
170 ieee80211_debugfs_key_add_mgmt_default(key->sdata);
171 }
3cfcf6ac
JM
172}
173
174void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
175 int idx)
176{
ad0e2b5a 177 mutex_lock(&sdata->local->key_mtx);
3cfcf6ac 178 __ieee80211_set_default_mgmt_key(sdata, idx);
ad0e2b5a 179 mutex_unlock(&sdata->local->key_mtx);
3cfcf6ac
JM
180}
181
3b96766f
JB
182
183static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
184 struct sta_info *sta,
185 struct ieee80211_key *old,
186 struct ieee80211_key *new)
187{
3cfcf6ac 188 int idx, defkey, defmgmtkey;
3b96766f
JB
189
190 if (new)
191 list_add(&new->list, &sdata->key_list);
192
193 if (sta) {
194 rcu_assign_pointer(sta->key, new);
195 } else {
196 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
197
198 if (old)
199 idx = old->conf.keyidx;
200 else
201 idx = new->conf.keyidx;
202
203 defkey = old && sdata->default_key == old;
3cfcf6ac 204 defmgmtkey = old && sdata->default_mgmt_key == old;
3b96766f
JB
205
206 if (defkey && !new)
207 __ieee80211_set_default_key(sdata, -1);
3cfcf6ac
JM
208 if (defmgmtkey && !new)
209 __ieee80211_set_default_mgmt_key(sdata, -1);
3b96766f
JB
210
211 rcu_assign_pointer(sdata->keys[idx], new);
212 if (defkey && new)
213 __ieee80211_set_default_key(sdata, new->conf.keyidx);
3cfcf6ac
JM
214 if (defmgmtkey && new)
215 __ieee80211_set_default_mgmt_key(sdata,
216 new->conf.keyidx);
3b96766f
JB
217 }
218
219 if (old) {
220 /*
221 * We'll use an empty list to indicate that the key
222 * has already been removed.
223 */
224 list_del_init(&old->list);
225 }
11a843b7
JB
226}
227
97359d12 228struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
faa8fdc8
JM
229 const u8 *key_data,
230 size_t seq_len, const u8 *seq)
1f5a7e47
JB
231{
232 struct ieee80211_key *key;
1ac62ba7 233 int i, j, err;
1f5a7e47 234
3cfcf6ac 235 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
11a843b7
JB
236
237 key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
1f5a7e47 238 if (!key)
1ac62ba7 239 return ERR_PTR(-ENOMEM);
11a843b7
JB
240
241 /*
242 * Default to software encryption; we'll later upload the
243 * key to the hardware if possible.
244 */
11a843b7
JB
245 key->conf.flags = 0;
246 key->flags = 0;
247
97359d12 248 key->conf.cipher = cipher;
11a843b7
JB
249 key->conf.keyidx = idx;
250 key->conf.keylen = key_len;
97359d12
JB
251 switch (cipher) {
252 case WLAN_CIPHER_SUITE_WEP40:
253 case WLAN_CIPHER_SUITE_WEP104:
76708dee
FF
254 key->conf.iv_len = WEP_IV_LEN;
255 key->conf.icv_len = WEP_ICV_LEN;
256 break;
97359d12 257 case WLAN_CIPHER_SUITE_TKIP:
76708dee
FF
258 key->conf.iv_len = TKIP_IV_LEN;
259 key->conf.icv_len = TKIP_ICV_LEN;
9f26a952 260 if (seq) {
faa8fdc8
JM
261 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
262 key->u.tkip.rx[i].iv32 =
263 get_unaligned_le32(&seq[2]);
264 key->u.tkip.rx[i].iv16 =
265 get_unaligned_le16(seq);
266 }
267 }
76708dee 268 break;
97359d12 269 case WLAN_CIPHER_SUITE_CCMP:
76708dee
FF
270 key->conf.iv_len = CCMP_HDR_LEN;
271 key->conf.icv_len = CCMP_MIC_LEN;
9f26a952 272 if (seq) {
9190252c 273 for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++)
faa8fdc8
JM
274 for (j = 0; j < CCMP_PN_LEN; j++)
275 key->u.ccmp.rx_pn[i][j] =
276 seq[CCMP_PN_LEN - j - 1];
277 }
11a843b7
JB
278 /*
279 * Initialize AES key state here as an optimization so that
280 * it does not need to be initialized for every packet.
281 */
282 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
1ac62ba7
BH
283 if (IS_ERR(key->u.ccmp.tfm)) {
284 err = PTR_ERR(key->u.ccmp.tfm);
3b96766f 285 kfree(key);
1ac62ba7 286 key = ERR_PTR(err);
11a843b7 287 }
60ae0f20
JB
288 break;
289 case WLAN_CIPHER_SUITE_AES_CMAC:
290 key->conf.iv_len = 0;
291 key->conf.icv_len = sizeof(struct ieee80211_mmie);
292 if (seq)
293 for (j = 0; j < 6; j++)
294 key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
3cfcf6ac
JM
295 /*
296 * Initialize AES key state here as an optimization so that
297 * it does not need to be initialized for every packet.
298 */
299 key->u.aes_cmac.tfm =
300 ieee80211_aes_cmac_key_setup(key_data);
1ac62ba7
BH
301 if (IS_ERR(key->u.aes_cmac.tfm)) {
302 err = PTR_ERR(key->u.aes_cmac.tfm);
3cfcf6ac 303 kfree(key);
1ac62ba7 304 key = ERR_PTR(err);
3cfcf6ac 305 }
60ae0f20 306 break;
3cfcf6ac 307 }
60ae0f20
JB
308 memcpy(key->conf.key, key_data, key_len);
309 INIT_LIST_HEAD(&key->list);
3cfcf6ac 310
db4d1169
JB
311 return key;
312}
11a843b7 313
ad0e2b5a
JB
314static void __ieee80211_key_destroy(struct ieee80211_key *key)
315{
316 if (!key)
317 return;
318
32162a4d
JM
319 if (key->local)
320 ieee80211_key_disable_hw_accel(key);
ad0e2b5a 321
97359d12 322 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
ad0e2b5a 323 ieee80211_aes_key_free(key->u.ccmp.tfm);
97359d12 324 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
ad0e2b5a 325 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
32162a4d
JM
326 if (key->local)
327 ieee80211_debugfs_key_remove(key);
ad0e2b5a
JB
328
329 kfree(key);
330}
331
db4d1169
JB
332void ieee80211_key_link(struct ieee80211_key *key,
333 struct ieee80211_sub_if_data *sdata,
334 struct sta_info *sta)
335{
336 struct ieee80211_key *old_key;
337 int idx;
338
db4d1169
JB
339 BUG_ON(!sdata);
340 BUG_ON(!key);
341
342 idx = key->conf.keyidx;
343 key->local = sdata->local;
344 key->sdata = sdata;
345 key->sta = sta;
346
11a843b7 347 if (sta) {
11a843b7
JB
348 /*
349 * some hardware cannot handle TKIP with QoS, so
350 * we indicate whether QoS could be in use.
351 */
07346f81 352 if (test_sta_flags(sta, WLAN_STA_WME))
11a843b7 353 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
c6adbd21
ID
354
355 /*
356 * This key is for a specific sta interface,
357 * inform the driver that it should try to store
358 * this key as pairwise key.
359 */
360 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
11a843b7 361 } else {
05c914fe 362 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
11a843b7
JB
363 struct sta_info *ap;
364
3b96766f
JB
365 /*
366 * We're getting a sta pointer in,
367 * so must be under RCU read lock.
368 */
d0709a65 369
11a843b7 370 /* same here, the AP could be using QoS */
abe60632 371 ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
11a843b7 372 if (ap) {
07346f81 373 if (test_sta_flags(ap, WLAN_STA_WME))
11a843b7
JB
374 key->conf.flags |=
375 IEEE80211_KEY_FLAG_WMM_STA;
11a843b7
JB
376 }
377 }
11a843b7
JB
378 }
379
ad0e2b5a 380 mutex_lock(&sdata->local->key_mtx);
3b96766f 381
d4e46a3d 382 if (sta)
db4d1169 383 old_key = sta->key;
d4e46a3d 384 else
db4d1169
JB
385 old_key = sdata->keys[idx];
386
387 __ieee80211_key_replace(sdata, sta, old_key, key);
ad0e2b5a 388 __ieee80211_key_destroy(old_key);
d4e46a3d 389
ad0e2b5a 390 ieee80211_debugfs_key_add(key);
db4d1169 391
ad0e2b5a 392 ieee80211_key_enable_hw_accel(key);
523d2f69 393
ad0e2b5a 394 mutex_unlock(&sdata->local->key_mtx);
1f5a7e47
JB
395}
396
3a245766 397static void __ieee80211_key_free(struct ieee80211_key *key)
1f5a7e47 398{
3b96766f
JB
399 /*
400 * Replace key with nothingness if it was ever used.
401 */
3a245766 402 if (key->sdata)
3b96766f
JB
403 __ieee80211_key_replace(key->sdata, key->sta,
404 key, NULL);
ad0e2b5a 405 __ieee80211_key_destroy(key);
3b96766f 406}
d4e46a3d 407
32162a4d
JM
408void ieee80211_key_free(struct ieee80211_local *local,
409 struct ieee80211_key *key)
3b96766f 410{
3a245766 411 if (!key)
3b96766f
JB
412 return;
413
ad0e2b5a 414 mutex_lock(&local->key_mtx);
3a245766 415 __ieee80211_key_free(key);
ad0e2b5a 416 mutex_unlock(&local->key_mtx);
3a245766
JB
417}
418
ad0e2b5a 419void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
3a245766
JB
420{
421 struct ieee80211_key *key;
11a843b7 422
3a245766 423 ASSERT_RTNL();
11a843b7 424
9607e6b6 425 if (WARN_ON(!ieee80211_sdata_running(sdata)))
3a245766 426 return;
11a843b7 427
ad0e2b5a 428 mutex_lock(&sdata->local->key_mtx);
11a843b7 429
ad0e2b5a
JB
430 list_for_each_entry(key, &sdata->key_list, list)
431 ieee80211_key_enable_hw_accel(key);
3b96766f 432
ad0e2b5a 433 mutex_unlock(&sdata->local->key_mtx);
11a843b7
JB
434}
435
ad0e2b5a 436void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
11a843b7
JB
437{
438 struct ieee80211_key *key;
439
ad0e2b5a 440 ASSERT_RTNL();
db4d1169 441
ad0e2b5a 442 mutex_lock(&sdata->local->key_mtx);
11a843b7 443
ad0e2b5a
JB
444 list_for_each_entry(key, &sdata->key_list, list)
445 ieee80211_key_disable_hw_accel(key);
11a843b7 446
ad0e2b5a 447 mutex_unlock(&sdata->local->key_mtx);
3b96766f 448}
11a843b7 449
3b96766f
JB
450void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
451{
452 struct ieee80211_key *key, *tmp;
db4d1169 453
ad0e2b5a 454 mutex_lock(&sdata->local->key_mtx);
3b96766f
JB
455
456 ieee80211_debugfs_key_remove_default(sdata);
3cfcf6ac 457 ieee80211_debugfs_key_remove_mgmt_default(sdata);
3b96766f
JB
458
459 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
3a245766 460 __ieee80211_key_free(key);
3b96766f 461
ad0e2b5a 462 mutex_unlock(&sdata->local->key_mtx);
11a843b7 463}
This page took 0.305421 seconds and 5 git commands to generate.