00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifdef HOSTAP_CRYPT_MODULE
00013 #ifndef EXPORT_SYMTAB
00014 #define EXPORT_SYMTAB
00015 #endif
00016
00017 #include <linux/config.h>
00018 #include <linux/version.h>
00019 #include <linux/module.h>
00020 #include <linux/init.h>
00021 #include <linux/slab.h>
00022 #include <asm/string.h>
00023 #include <asm/errno.h>
00024
00025 #include "hostap_crypt.h"
00026 #include "hostap_compat.h"
00027
00028 MODULE_AUTHOR("Jouni Malinen");
00029 MODULE_DESCRIPTION("Host AP crypto");
00030 MODULE_LICENSE("GPL");
00031 #endif
00032
00033
00034 struct hostap_crypto_alg {
00035 struct list_head list;
00036 struct hostap_crypto_ops *ops;
00037 };
00038
00039
00040 struct hostap_crypto {
00041 struct list_head algs;
00042 spinlock_t lock;
00043 };
00044
00045 static struct hostap_crypto *hcrypt;
00046
00047
00048 int hostap_register_crypto_ops(struct hostap_crypto_ops *ops)
00049 {
00050 unsigned long flags;
00051 struct hostap_crypto_alg *alg;
00052
00053 if (hcrypt == NULL)
00054 return -1;
00055
00056 alg = (struct hostap_crypto_alg *) kmalloc(sizeof(*alg), GFP_KERNEL);
00057 if (alg == NULL)
00058 return -ENOMEM;
00059
00060 memset(alg, 0, sizeof(*alg));
00061 alg->ops = ops;
00062
00063 spin_lock_irqsave(&hcrypt->lock, flags);
00064 list_add(&alg->list, &hcrypt->algs);
00065 spin_unlock_irqrestore(&hcrypt->lock, flags);
00066
00067 printk(KERN_DEBUG "hostap_crypt: registered algorithm '%s'\n",
00068 ops->name);
00069
00070 return 0;
00071 }
00072
00073
00074 int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops)
00075 {
00076 unsigned long flags;
00077 struct list_head *ptr;
00078 struct hostap_crypto_alg *del_alg = NULL;
00079
00080 if (hcrypt == NULL)
00081 return -1;
00082
00083 spin_lock_irqsave(&hcrypt->lock, flags);
00084 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
00085 struct hostap_crypto_alg *alg =
00086 (struct hostap_crypto_alg *) ptr;
00087 if (alg->ops == ops) {
00088 list_del(&alg->list);
00089 del_alg = alg;
00090 break;
00091 }
00092 }
00093 spin_unlock_irqrestore(&hcrypt->lock, flags);
00094
00095 if (del_alg) {
00096 printk(KERN_DEBUG "hostap_crypt: unregistered algorithm "
00097 "'%s'\n", ops->name);
00098 kfree(del_alg);
00099 }
00100
00101 return del_alg ? 0 : -1;
00102 }
00103
00104
00105 struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name)
00106 {
00107 unsigned long flags;
00108 struct list_head *ptr;
00109 struct hostap_crypto_alg *found_alg = NULL;
00110
00111 if (hcrypt == NULL)
00112 return NULL;
00113
00114 spin_lock_irqsave(&hcrypt->lock, flags);
00115 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
00116 struct hostap_crypto_alg *alg =
00117 (struct hostap_crypto_alg *) ptr;
00118 if (strcmp(alg->ops->name, name) == 0) {
00119 found_alg = alg;
00120 break;
00121 }
00122 }
00123 spin_unlock_irqrestore(&hcrypt->lock, flags);
00124
00125 if (found_alg)
00126 return found_alg->ops;
00127 else
00128 return NULL;
00129 }
00130
00131
00132 static void * hostap_crypt_null_init(void) { return (void *) 1; }
00133 static void hostap_crypt_null_deinit(void *priv) {}
00134
00135 static struct hostap_crypto_ops hostap_crypt_null = {
00136 .name = "NULL",
00137 .init = hostap_crypt_null_init,
00138 .deinit = hostap_crypt_null_deinit,
00139 .encrypt = NULL,
00140 .decrypt = NULL,
00141 .set_key = NULL,
00142 .get_key = NULL,
00143 .set_key_idx = NULL,
00144 .get_key_idx = NULL,
00145 .extra_prefix_len = 0,
00146 .extra_postfix_len = 0
00147 };
00148
00149
00150 static int __init hostap_crypto_init(void)
00151 {
00152 hcrypt = (struct hostap_crypto *) kmalloc(sizeof(*hcrypt), GFP_KERNEL);
00153 if (hcrypt == NULL)
00154 return -ENOMEM;
00155
00156 memset(hcrypt, 0, sizeof(*hcrypt));
00157 INIT_LIST_HEAD(&hcrypt->algs);
00158 spin_lock_init(&hcrypt->lock);
00159
00160 (void) hostap_register_crypto_ops(&hostap_crypt_null);
00161
00162 return 0;
00163 }
00164
00165
00166 static void __exit hostap_crypto_deinit(void)
00167 {
00168 struct list_head *ptr, *n;
00169
00170 if (hcrypt == NULL)
00171 return;
00172
00173 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
00174 ptr = n, n = ptr->next) {
00175 struct hostap_crypto_alg *alg =
00176 (struct hostap_crypto_alg *) ptr;
00177 list_del(ptr);
00178 printk(KERN_DEBUG "hostap_crypt: unregistered algorithm "
00179 "'%s' (deinit)\n", alg->ops->name);
00180 kfree(alg);
00181 }
00182
00183 kfree(hcrypt);
00184 }
00185
00186
00187 EXPORT_SYMBOL(hostap_register_crypto_ops);
00188 EXPORT_SYMBOL(hostap_unregister_crypto_ops);
00189 EXPORT_SYMBOL(hostap_get_crypto_ops);
00190
00191 #ifdef HOSTAP_CRYPT_MODULE
00192 module_init(hostap_crypto_init);
00193 module_exit(hostap_crypto_deinit);
00194 #endif