[MAC80211]: split out some key functions from ieee80211.c
[safe/jmp/linux-2.6] / net / mac80211 / key.c
1 /*
2  * Copyright 2002-2005, Instant802 Networks, Inc.
3  * Copyright 2005-2006, Devicescape Software, Inc.
4  * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <net/mac80211.h>
12 #include "ieee80211_i.h"
13 #include "debugfs_key.h"
14 #include "aes_ccm.h"
15
16 struct ieee80211_key_conf *
17 ieee80211_key_data2conf(struct ieee80211_local *local,
18                         const struct ieee80211_key *data)
19 {
20         struct ieee80211_key_conf *conf;
21
22         conf = kmalloc(sizeof(*conf) + data->keylen, GFP_ATOMIC);
23         if (!conf)
24                 return NULL;
25
26         conf->hw_key_idx = data->hw_key_idx;
27         conf->alg = data->alg;
28         conf->keylen = data->keylen;
29         conf->flags = 0;
30         if (data->force_sw_encrypt)
31                 conf->flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
32         conf->keyidx = data->keyidx;
33         if (data->default_tx_key)
34                 conf->flags |= IEEE80211_KEY_DEFAULT_TX_KEY;
35         if (local->default_wep_only)
36                 conf->flags |= IEEE80211_KEY_DEFAULT_WEP_ONLY;
37         memcpy(conf->key, data->key, data->keylen);
38
39         return conf;
40 }
41
42 struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
43                                           int idx, size_t key_len, gfp_t flags)
44 {
45         struct ieee80211_key *key;
46
47         key = kzalloc(sizeof(struct ieee80211_key) + key_len, flags);
48         if (!key)
49                 return NULL;
50         kref_init(&key->kref);
51         return key;
52 }
53
54 static void ieee80211_key_release(struct kref *kref)
55 {
56         struct ieee80211_key *key;
57
58         key = container_of(kref, struct ieee80211_key, kref);
59         if (key->alg == ALG_CCMP)
60                 ieee80211_aes_key_free(key->u.ccmp.tfm);
61         ieee80211_debugfs_key_remove(key);
62         kfree(key);
63 }
64
65 void ieee80211_key_free(struct ieee80211_key *key)
66 {
67         if (key)
68                 kref_put(&key->kref, ieee80211_key_release);
69 }