1ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman/*
2ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman * Host AP crypto routines
3ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman *
4ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
5ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman *
7ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman * This program is free software; you can redistribute it and/or modify
8ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman * it under the terms of the GNU General Public License version 2 as
9ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman * published by the Free Software Foundation. See README and COPYING for
10ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman * more details.
11ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman *
12ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman */
13ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
14ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman#include <linux/module.h>
15ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman#include <linux/init.h>
16ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman#include <linux/slab.h>
17a44325f98563c39bc63311db7471b848153e49feLarry Finger#include <linux/string.h>
18a44325f98563c39bc63311db7471b848153e49feLarry Finger#include <linux/errno.h>
19ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
2094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "rtllib.h"
21ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
2294a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstruct rtllib_crypto_alg {
23ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	struct list_head list;
2432c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan	struct lib80211_crypto_ops *ops;
25ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman};
26ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
27ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
2894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstruct rtllib_crypto {
29ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	struct list_head algs;
30ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spinlock_t lock;
31ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman};
32ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
3394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic struct rtllib_crypto *hcrypt;
34ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
350ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennanvoid rtllib_crypt_deinit_entries(struct lib80211_crypt_info *info,
36ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman					   int force)
37ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
38ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	struct list_head *ptr, *n;
3932c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan	struct lib80211_crypt_data *entry;
40ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
410ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	for (ptr = info->crypt_deinit_list.next, n = ptr->next;
420ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	     ptr != &info->crypt_deinit_list; ptr = n, n = ptr->next) {
4332c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan		entry = list_entry(ptr, struct lib80211_crypt_data, list);
44ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
45ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		if (atomic_read(&entry->refcnt) != 0 && !force)
46ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman			continue;
47ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
48ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		list_del(ptr);
49ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
50a010a3375227efbd6b8ac11b99c34c807a77c45aHerton Ronaldo Krzesinski		if (entry->ops)
51ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman			entry->ops->deinit(entry->priv);
52ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		kfree(entry);
53ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
54ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
553b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(rtllib_crypt_deinit_entries);
56ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
5794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid rtllib_crypt_deinit_handler(unsigned long data)
58ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
590ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
60ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	unsigned long flags;
61ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
620ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	spin_lock_irqsave(info->lock, flags);
630ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	rtllib_crypt_deinit_entries(info, 0);
640ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	if (!list_empty(&info->crypt_deinit_list)) {
65ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
660ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan		       "deletion list\n", info->name);
670ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan		info->crypt_deinit_timer.expires = jiffies + HZ;
680ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan		add_timer(&info->crypt_deinit_timer);
69ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
700ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	spin_unlock_irqrestore(info->lock, flags);
71ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
72ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
733b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(rtllib_crypt_deinit_handler);
74ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
750ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennanvoid rtllib_crypt_delayed_deinit(struct lib80211_crypt_info *info,
760ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan				 struct lib80211_crypt_data **crypt)
77ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
7832c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan	struct lib80211_crypt_data *tmp;
79ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	unsigned long flags;
80ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
81ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (*crypt == NULL)
82ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return;
83ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
84ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	tmp = *crypt;
85ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	*crypt = NULL;
86ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
87ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	/* must not run ops->deinit() while there may be pending encrypt or
88ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	 * decrypt operations. Use a list of delayed deinits to avoid needing
89ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	 * locking. */
90ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
910ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	spin_lock_irqsave(info->lock, flags);
920ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	list_add(&tmp->list, &info->crypt_deinit_list);
930ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	if (!timer_pending(&info->crypt_deinit_timer)) {
940ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan		info->crypt_deinit_timer.expires = jiffies + HZ;
950ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan		add_timer(&info->crypt_deinit_timer);
96ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
970ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan	spin_unlock_irqrestore(info->lock, flags);
98ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
993b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(rtllib_crypt_delayed_deinit);
100ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
10132c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennanint rtllib_register_crypto_ops(struct lib80211_crypto_ops *ops)
102ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
103ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	unsigned long flags;
10494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	struct rtllib_crypto_alg *alg;
105ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
106ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (hcrypt == NULL)
107ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return -1;
108ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
109929fa2a42e75e0c6ded89c450bd0f668e32190d7Thomas Meyer	alg = kzalloc(sizeof(*alg), GFP_KERNEL);
110ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (alg == NULL)
111ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return -ENOMEM;
112ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
113ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	alg->ops = ops;
114ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
115ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spin_lock_irqsave(&hcrypt->lock, flags);
116ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	list_add(&alg->list, &hcrypt->algs);
117ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spin_unlock_irqrestore(&hcrypt->lock, flags);
118ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
11994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	printk(KERN_DEBUG "rtllib_crypt: registered algorithm '%s'\n",
120ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	       ops->name);
121ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
122ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	return 0;
123ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
1243b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(rtllib_register_crypto_ops);
125ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
12632c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennanint rtllib_unregister_crypto_ops(struct lib80211_crypto_ops *ops)
127ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
128ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	unsigned long flags;
129ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	struct list_head *ptr;
13094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	struct rtllib_crypto_alg *del_alg = NULL;
131ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
132ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (hcrypt == NULL)
133ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return -1;
134ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
135ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spin_lock_irqsave(&hcrypt->lock, flags);
136ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
13794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		struct rtllib_crypto_alg *alg =
13894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			(struct rtllib_crypto_alg *) ptr;
139ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		if (alg->ops == ops) {
140ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman			list_del(&alg->list);
141ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman			del_alg = alg;
142ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman			break;
143ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		}
144ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
145ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spin_unlock_irqrestore(&hcrypt->lock, flags);
146ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
147ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (del_alg) {
14894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm "
149ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		       "'%s'\n", ops->name);
150ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		kfree(del_alg);
151ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
152ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
153ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	return del_alg ? 0 : -1;
154ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
1553b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(rtllib_unregister_crypto_ops);
156ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
157ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
15832c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennanstruct lib80211_crypto_ops *rtllib_get_crypto_ops(const char *name)
159ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
160ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	unsigned long flags;
161ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	struct list_head *ptr;
16294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	struct rtllib_crypto_alg *found_alg = NULL;
163ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
164ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (hcrypt == NULL)
165ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return NULL;
166ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
167ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spin_lock_irqsave(&hcrypt->lock, flags);
168ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
16994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		struct rtllib_crypto_alg *alg =
17094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			(struct rtllib_crypto_alg *) ptr;
171ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		if (strcmp(alg->ops->name, name) == 0) {
172ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman			found_alg = alg;
173ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman			break;
174ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		}
175ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
176ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spin_unlock_irqrestore(&hcrypt->lock, flags);
177ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
178ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (found_alg)
179ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return found_alg->ops;
180ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	else
181ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return NULL;
182ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
1833b28499c5519e59fbe9c2dea49ece5a3665be787Sean MacLennanEXPORT_SYMBOL(rtllib_get_crypto_ops);
184ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
185ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
18694a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void * rtllib_crypt_null_init(int keyidx) { return (void *) 1; }
18794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void rtllib_crypt_null_deinit(void *priv) {}
188ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
18932c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennanstatic struct lib80211_crypto_ops rtllib_crypt_null = {
190ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.name			= "NULL",
19194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	.init			= rtllib_crypt_null_init,
19294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger	.deinit			= rtllib_crypt_null_deinit,
193ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.encrypt_mpdu		= NULL,
194ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.decrypt_mpdu		= NULL,
195ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.encrypt_msdu		= NULL,
196ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.decrypt_msdu		= NULL,
197ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.set_key		= NULL,
198ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.get_key		= NULL,
19932c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan	.extra_mpdu_prefix_len	= 0,
20032c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan	.extra_mpdu_postfix_len	= 0,
20132c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan	.extra_msdu_prefix_len	= 0,
20232c44cb5b9fdc6eaa445bd622008dd672a3dd1a7Sean MacLennan	.extra_msdu_postfix_len	= 0,
203ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	.owner			= THIS_MODULE,
204ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman};
205ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
206ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
20794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerint __init rtllib_crypto_init(void)
208ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
209ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	int ret = -ENOMEM;
210ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
211929fa2a42e75e0c6ded89c450bd0f668e32190d7Thomas Meyer	hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
212ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (!hcrypt)
213ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		goto out;
214ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
215ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	INIT_LIST_HEAD(&hcrypt->algs);
216ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	spin_lock_init(&hcrypt->lock);
217ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
2183b148be0df8e45a0259d7e84001cf02e897af614Sean MacLennan	ret = lib80211_register_crypto_ops(&rtllib_crypt_null);
219ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (ret < 0) {
220ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		kfree(hcrypt);
221ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		hcrypt = NULL;
222ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
223ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartmanout:
224ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	return ret;
225ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
226ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
227ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
22894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid __exit rtllib_crypto_deinit(void)
229ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman{
230ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	struct list_head *ptr, *n;
231ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
232ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	if (hcrypt == NULL)
233ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		return;
234ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
235ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
236ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	     ptr = n, n = ptr->next) {
23794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		struct rtllib_crypto_alg *alg =
23894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger			(struct rtllib_crypto_alg *) ptr;
239ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		list_del(ptr);
24094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger		printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm "
241ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		       "'%s' (deinit)\n", alg->ops->name);
242ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman		kfree(alg);
243ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	}
244ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman
245ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman	kfree(hcrypt);
246ecdfa44610fa18678c3dd481af75368b9800c6c7Greg Kroah-Hartman}
247d37e0208df563af9c6fada84e620aabed581b3a8Sean MacLennan
248d37e0208df563af9c6fada84e620aabed581b3a8Sean MacLennanmodule_init(rtllib_crypto_init);
249d37e0208df563af9c6fada84e620aabed581b3a8Sean MacLennanmodule_exit(rtllib_crypto_deinit);
250d37e0208df563af9c6fada84e620aabed581b3a8Sean MacLennan
251d37e0208df563af9c6fada84e620aabed581b3a8Sean MacLennanMODULE_LICENSE("GPL");
252