1/* 2 * Host AP crypto routines 3 * 4 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com> 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. See README and COPYING for 10 * more details. 11 * 12 */ 13 14//#include <linux/config.h> 15#include <linux/version.h> 16#include <linux/module.h> 17#include <linux/init.h> 18#include <linux/slab.h> 19#include <asm/string.h> 20#include <asm/errno.h> 21 22#include "ieee80211.h" 23 24MODULE_AUTHOR("Jouni Malinen"); 25MODULE_DESCRIPTION("HostAP crypto"); 26MODULE_LICENSE("GPL"); 27 28struct ieee80211_crypto_alg { 29 struct list_head list; 30 struct ieee80211_crypto_ops *ops; 31}; 32 33 34struct ieee80211_crypto { 35 struct list_head algs; 36 spinlock_t lock; 37}; 38 39static struct ieee80211_crypto *hcrypt; 40 41void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, 42 int force) 43{ 44 struct list_head *ptr, *n; 45 struct ieee80211_crypt_data *entry; 46 47 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; 48 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { 49 entry = list_entry(ptr, struct ieee80211_crypt_data, list); 50 51 if (atomic_read(&entry->refcnt) != 0 && !force) 52 continue; 53 54 list_del(ptr); 55 56 if (entry->ops) 57 entry->ops->deinit(entry->priv); 58 kfree(entry); 59 } 60} 61 62void ieee80211_crypt_deinit_handler(unsigned long data) 63{ 64 struct ieee80211_device *ieee = (struct ieee80211_device *)data; 65 unsigned long flags; 66 67 spin_lock_irqsave(&ieee->lock, flags); 68 ieee80211_crypt_deinit_entries(ieee, 0); 69 if (!list_empty(&ieee->crypt_deinit_list)) { 70 printk(KERN_DEBUG "%s: entries remaining in delayed crypt " 71 "deletion list\n", ieee->dev->name); 72 ieee->crypt_deinit_timer.expires = jiffies + HZ; 73 add_timer(&ieee->crypt_deinit_timer); 74 } 75 spin_unlock_irqrestore(&ieee->lock, flags); 76 77} 78 79void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, 80 struct ieee80211_crypt_data **crypt) 81{ 82 struct ieee80211_crypt_data *tmp; 83 unsigned long flags; 84 85 if (*crypt == NULL) 86 return; 87 88 tmp = *crypt; 89 *crypt = NULL; 90 91 /* must not run ops->deinit() while there may be pending encrypt or 92 * decrypt operations. Use a list of delayed deinits to avoid needing 93 * locking. */ 94 95 spin_lock_irqsave(&ieee->lock, flags); 96 list_add(&tmp->list, &ieee->crypt_deinit_list); 97 if (!timer_pending(&ieee->crypt_deinit_timer)) { 98 ieee->crypt_deinit_timer.expires = jiffies + HZ; 99 add_timer(&ieee->crypt_deinit_timer); 100 } 101 spin_unlock_irqrestore(&ieee->lock, flags); 102} 103 104int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) 105{ 106 unsigned long flags; 107 struct ieee80211_crypto_alg *alg; 108 109 if (hcrypt == NULL) 110 return -1; 111 112 alg = kzalloc(sizeof(*alg), GFP_KERNEL); 113 if (alg == NULL) 114 return -ENOMEM; 115 116 alg->ops = ops; 117 118 spin_lock_irqsave(&hcrypt->lock, flags); 119 list_add(&alg->list, &hcrypt->algs); 120 spin_unlock_irqrestore(&hcrypt->lock, flags); 121 122 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", 123 ops->name); 124 125 return 0; 126} 127 128int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) 129{ 130 unsigned long flags; 131 struct list_head *ptr; 132 struct ieee80211_crypto_alg *del_alg = NULL; 133 134 if (hcrypt == NULL) 135 return -1; 136 137 spin_lock_irqsave(&hcrypt->lock, flags); 138 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { 139 struct ieee80211_crypto_alg *alg = 140 (struct ieee80211_crypto_alg *) ptr; 141 if (alg->ops == ops) { 142 list_del(&alg->list); 143 del_alg = alg; 144 break; 145 } 146 } 147 spin_unlock_irqrestore(&hcrypt->lock, flags); 148 149 if (del_alg) { 150 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " 151 "'%s'\n", ops->name); 152 kfree(del_alg); 153 } 154 155 return del_alg ? 0 : -1; 156} 157 158 159struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name) 160{ 161 unsigned long flags; 162 struct list_head *ptr; 163 struct ieee80211_crypto_alg *found_alg = NULL; 164 165 if (hcrypt == NULL) 166 return NULL; 167 168 spin_lock_irqsave(&hcrypt->lock, flags); 169 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { 170 struct ieee80211_crypto_alg *alg = 171 (struct ieee80211_crypto_alg *) ptr; 172 if (strcmp(alg->ops->name, name) == 0) { 173 found_alg = alg; 174 break; 175 } 176 } 177 spin_unlock_irqrestore(&hcrypt->lock, flags); 178 179 if (found_alg) 180 return found_alg->ops; 181 else 182 return NULL; 183} 184 185 186static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } 187static void ieee80211_crypt_null_deinit(void *priv) {} 188 189static struct ieee80211_crypto_ops ieee80211_crypt_null = { 190 .name = "NULL", 191 .init = ieee80211_crypt_null_init, 192 .deinit = ieee80211_crypt_null_deinit, 193 .encrypt_mpdu = NULL, 194 .decrypt_mpdu = NULL, 195 .encrypt_msdu = NULL, 196 .decrypt_msdu = NULL, 197 .set_key = NULL, 198 .get_key = NULL, 199 .extra_prefix_len = 0, 200 .extra_postfix_len = 0, 201 .owner = THIS_MODULE, 202}; 203 204 205int ieee80211_crypto_init(void) 206{ 207 int ret = -ENOMEM; 208 209 hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); 210 if (!hcrypt) 211 goto out; 212 213 INIT_LIST_HEAD(&hcrypt->algs); 214 spin_lock_init(&hcrypt->lock); 215 216 ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null); 217 if (ret < 0) { 218 kfree(hcrypt); 219 hcrypt = NULL; 220 } 221out: 222 return ret; 223} 224 225 226void ieee80211_crypto_deinit(void) 227{ 228 struct list_head *ptr, *n; 229 struct ieee80211_crypto_alg *alg = NULL; 230 231 if (hcrypt == NULL) 232 return; 233 234 list_for_each_safe(ptr, n, &hcrypt->algs) { 235 alg = list_entry(ptr, struct ieee80211_crypto_alg, list); 236 if (alg) { 237 list_del(ptr); 238 printk(KERN_DEBUG 239 "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", 240 alg->ops->name); 241 kfree(alg); 242 } 243 } 244 kfree(hcrypt); 245} 246