api.c (6521f30273fbec65146a0f16de74b7b402b0f7b0) api.c (cce9e06d100df19a327b19f23adad76e7bf63edd)
1/*
2 * Scatterlist Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
6 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
7 *
8 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
9 * and Nettle, by Niels M�ller.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 *
16 */
17
1/*
2 * Scatterlist Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
6 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
7 *
8 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
9 * and Nettle, by Niels M�ller.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 *
16 */
17
18#include <linux/compiler.h>
19#include <linux/init.h>
20#include <linux/crypto.h>
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/kmod.h>
18#include <linux/errno.h>
19#include <linux/kernel.h>
20#include <linux/kmod.h>
24#include <linux/rwsem.h>
25#include <linux/slab.h>
26#include <linux/string.h>
27#include "internal.h"
28
29LIST_HEAD(crypto_alg_list);
21#include <linux/slab.h>
22#include <linux/string.h>
23#include "internal.h"
24
25LIST_HEAD(crypto_alg_list);
26EXPORT_SYMBOL_GPL(crypto_alg_list);
30DECLARE_RWSEM(crypto_alg_sem);
27DECLARE_RWSEM(crypto_alg_sem);
28EXPORT_SYMBOL_GPL(crypto_alg_sem);
31
32static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
33{
34 atomic_inc(&alg->cra_refcnt);
35 return alg;
36}
37
38static inline void crypto_alg_put(struct crypto_alg *alg)

--- 195 unchanged lines hidden (view full) ---

234 if (alg->cra_exit)
235 alg->cra_exit(tfm);
236 crypto_exit_ops(tfm);
237 crypto_mod_put(alg);
238 memset(tfm, 0, size);
239 kfree(tfm);
240}
241
29
30static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
31{
32 atomic_inc(&alg->cra_refcnt);
33 return alg;
34}
35
36static inline void crypto_alg_put(struct crypto_alg *alg)

--- 195 unchanged lines hidden (view full) ---

232 if (alg->cra_exit)
233 alg->cra_exit(tfm);
234 crypto_exit_ops(tfm);
235 crypto_mod_put(alg);
236 memset(tfm, 0, size);
237 kfree(tfm);
238}
239
242static inline int crypto_set_driver_name(struct crypto_alg *alg)
243{
244 static const char suffix[] = "-generic";
245 char *driver_name = alg->cra_driver_name;
246 int len;
247
248 if (*driver_name)
249 return 0;
250
251 len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
252 if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
253 return -ENAMETOOLONG;
254
255 memcpy(driver_name + len, suffix, sizeof(suffix));
256 return 0;
257}
258
259int crypto_register_alg(struct crypto_alg *alg)
260{
261 int ret;
262 struct crypto_alg *q;
263
264 if (alg->cra_alignmask & (alg->cra_alignmask + 1))
265 return -EINVAL;
266
267 if (alg->cra_alignmask & alg->cra_blocksize)
268 return -EINVAL;
269
270 if (alg->cra_blocksize > PAGE_SIZE / 8)
271 return -EINVAL;
272
273 if (alg->cra_priority < 0)
274 return -EINVAL;
275
276 ret = crypto_set_driver_name(alg);
277 if (unlikely(ret))
278 return ret;
279
280 down_write(&crypto_alg_sem);
281
282 list_for_each_entry(q, &crypto_alg_list, cra_list) {
283 if (q == alg) {
284 ret = -EEXIST;
285 goto out;
286 }
287 }
288
289 list_add(&alg->cra_list, &crypto_alg_list);
290 atomic_set(&alg->cra_refcnt, 1);
291out:
292 up_write(&crypto_alg_sem);
293 return ret;
294}
295
296int crypto_unregister_alg(struct crypto_alg *alg)
297{
298 int ret = -ENOENT;
299 struct crypto_alg *q;
300
301 down_write(&crypto_alg_sem);
302 list_for_each_entry(q, &crypto_alg_list, cra_list) {
303 if (alg == q) {
304 list_del(&alg->cra_list);
305 ret = 0;
306 goto out;
307 }
308 }
309out:
310 up_write(&crypto_alg_sem);
311
312 if (ret)
313 return ret;
314
315 BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
316 if (alg->cra_destroy)
317 alg->cra_destroy(alg);
318
319 return 0;
320}
321
322int crypto_alg_available(const char *name, u32 flags)
323{
324 int ret = 0;
325 struct crypto_alg *alg = crypto_alg_mod_lookup(name);
326
327 if (alg) {
328 crypto_mod_put(alg);
329 ret = 1;
330 }
331
332 return ret;
333}
334
240int crypto_alg_available(const char *name, u32 flags)
241{
242 int ret = 0;
243 struct crypto_alg *alg = crypto_alg_mod_lookup(name);
244
245 if (alg) {
246 crypto_mod_put(alg);
247 ret = 1;
248 }
249
250 return ret;
251}
252
335static int __init init_crypto(void)
336{
337 printk(KERN_INFO "Initializing Cryptographic API\n");
338 crypto_init_proc();
339 return 0;
340}
341
342__initcall(init_crypto);
343
344EXPORT_SYMBOL_GPL(crypto_register_alg);
345EXPORT_SYMBOL_GPL(crypto_unregister_alg);
346EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
347EXPORT_SYMBOL_GPL(crypto_free_tfm);
348EXPORT_SYMBOL_GPL(crypto_alg_available);
253EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
254EXPORT_SYMBOL_GPL(crypto_free_tfm);
255EXPORT_SYMBOL_GPL(crypto_alg_available);