Root/
1 | /* |
2 | * Cryptographic API. |
3 | * |
4 | * RNG operations. |
5 | * |
6 | * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com> |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the Free |
10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. |
12 | * |
13 | */ |
14 | |
15 | #include <asm/atomic.h> |
16 | #include <crypto/internal/rng.h> |
17 | #include <linux/err.h> |
18 | #include <linux/module.h> |
19 | #include <linux/mutex.h> |
20 | #include <linux/random.h> |
21 | #include <linux/seq_file.h> |
22 | #include <linux/slab.h> |
23 | #include <linux/string.h> |
24 | |
25 | static DEFINE_MUTEX(crypto_default_rng_lock); |
26 | struct crypto_rng *crypto_default_rng; |
27 | EXPORT_SYMBOL_GPL(crypto_default_rng); |
28 | static int crypto_default_rng_refcnt; |
29 | |
30 | static int rngapi_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) |
31 | { |
32 | u8 *buf = NULL; |
33 | int err; |
34 | |
35 | if (!seed && slen) { |
36 | buf = kmalloc(slen, GFP_KERNEL); |
37 | if (!buf) |
38 | return -ENOMEM; |
39 | |
40 | get_random_bytes(buf, slen); |
41 | seed = buf; |
42 | } |
43 | |
44 | err = crypto_rng_alg(tfm)->rng_reset(tfm, seed, slen); |
45 | |
46 | kfree(buf); |
47 | return err; |
48 | } |
49 | |
50 | static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask) |
51 | { |
52 | struct rng_alg *alg = &tfm->__crt_alg->cra_rng; |
53 | struct rng_tfm *ops = &tfm->crt_rng; |
54 | |
55 | ops->rng_gen_random = alg->rng_make_random; |
56 | ops->rng_reset = rngapi_reset; |
57 | |
58 | return 0; |
59 | } |
60 | |
61 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) |
62 | __attribute__ ((unused)); |
63 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) |
64 | { |
65 | seq_printf(m, "type : rng\n"); |
66 | seq_printf(m, "seedsize : %u\n", alg->cra_rng.seedsize); |
67 | } |
68 | |
69 | static unsigned int crypto_rng_ctxsize(struct crypto_alg *alg, u32 type, |
70 | u32 mask) |
71 | { |
72 | return alg->cra_ctxsize; |
73 | } |
74 | |
75 | const struct crypto_type crypto_rng_type = { |
76 | .ctxsize = crypto_rng_ctxsize, |
77 | .init = crypto_init_rng_ops, |
78 | #ifdef CONFIG_PROC_FS |
79 | .show = crypto_rng_show, |
80 | #endif |
81 | }; |
82 | EXPORT_SYMBOL_GPL(crypto_rng_type); |
83 | |
84 | int crypto_get_default_rng(void) |
85 | { |
86 | struct crypto_rng *rng; |
87 | int err; |
88 | |
89 | mutex_lock(&crypto_default_rng_lock); |
90 | if (!crypto_default_rng) { |
91 | rng = crypto_alloc_rng("stdrng", 0, 0); |
92 | err = PTR_ERR(rng); |
93 | if (IS_ERR(rng)) |
94 | goto unlock; |
95 | |
96 | err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng)); |
97 | if (err) { |
98 | crypto_free_rng(rng); |
99 | goto unlock; |
100 | } |
101 | |
102 | crypto_default_rng = rng; |
103 | } |
104 | |
105 | crypto_default_rng_refcnt++; |
106 | err = 0; |
107 | |
108 | unlock: |
109 | mutex_unlock(&crypto_default_rng_lock); |
110 | |
111 | return err; |
112 | } |
113 | EXPORT_SYMBOL_GPL(crypto_get_default_rng); |
114 | |
115 | void crypto_put_default_rng(void) |
116 | { |
117 | mutex_lock(&crypto_default_rng_lock); |
118 | if (!--crypto_default_rng_refcnt) { |
119 | crypto_free_rng(crypto_default_rng); |
120 | crypto_default_rng = NULL; |
121 | } |
122 | mutex_unlock(&crypto_default_rng_lock); |
123 | } |
124 | EXPORT_SYMBOL_GPL(crypto_put_default_rng); |
125 | |
126 | MODULE_LICENSE("GPL"); |
127 | MODULE_DESCRIPTION("Random Number Generator"); |
128 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9