diff options
author | Stephan Mueller <smueller@chronox.de> | 2015-06-23 10:18:54 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-06-25 11:18:32 -0400 |
commit | dfc9fa91938bd0cd5597a3da33d613986149a1e6 (patch) | |
tree | 4eeef33d2c2046592acb662f59adb0d3c97e6017 /crypto | |
parent | aefbef10e3ae6e2c6e3c54f906f10b34c73a2c66 (diff) |
crypto: jitterentropy - avoid compiler warnings
The core of the Jitter RNG is intended to be compiled with -O0. To
ensure that the Jitter RNG can be compiled on all architectures,
separate out the RNG core into a stand-alone C file that can be compiled
with -O0 which does not depend on any kernel include file.
As no kernel includes can be used in the C file implementing the core
RNG, any dependencies on kernel code must be extracted.
A second file provides the link to the kernel and the kernel crypto API
that can be compiled with the regular compile options of the kernel.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/Makefile | 4 | ||||
-rw-r--r-- | crypto/jitterentropy-kcapi.c | 208 | ||||
-rw-r--r-- | crypto/jitterentropy.c | 213 |
3 files changed, 248 insertions, 177 deletions
diff --git a/crypto/Makefile b/crypto/Makefile index 0077476f5024..a16a7e7f2d60 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
@@ -106,7 +106,9 @@ obj-$(CONFIG_CRYPTO_842) += 842.o | |||
106 | obj-$(CONFIG_CRYPTO_RNG2) += rng.o | 106 | obj-$(CONFIG_CRYPTO_RNG2) += rng.o |
107 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o | 107 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o |
108 | obj-$(CONFIG_CRYPTO_DRBG) += drbg.o | 108 | obj-$(CONFIG_CRYPTO_DRBG) += drbg.o |
109 | obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy.o | 109 | obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o |
110 | CFLAGS_jitterentropy.o = -O0 | ||
111 | jitterentropy_rng-y := jitterentropy.o jitterentropy-kcapi.o | ||
110 | obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o | 112 | obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o |
111 | obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o | 113 | obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o |
112 | obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o | 114 | obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o |
diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c new file mode 100644 index 000000000000..b32d834144cd --- /dev/null +++ b/crypto/jitterentropy-kcapi.c | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * Non-physical true random number generator based on timing jitter -- | ||
3 | * Linux Kernel Crypto API specific code | ||
4 | * | ||
5 | * Copyright Stephan Mueller <smueller@chronox.de>, 2015 | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, and the entire permission notice in its entirety, | ||
12 | * including the disclaimer of warranties. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. The name of the author may not be used to endorse or promote | ||
17 | * products derived from this software without specific prior | ||
18 | * written permission. | ||
19 | * | ||
20 | * ALTERNATIVELY, this product may be distributed under the terms of | ||
21 | * the GNU General Public License, in which case the provisions of the GPL2 are | ||
22 | * required INSTEAD OF the above restrictions. (This clause is | ||
23 | * necessary due to a potential bad interaction between the GPL and | ||
24 | * the restrictions contained in a BSD-style copyright.) | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
28 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF | ||
29 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE | ||
30 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
31 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT | ||
32 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
33 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
36 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH | ||
37 | * DAMAGE. | ||
38 | */ | ||
39 | |||
40 | #include <linux/module.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/module.h> | ||
43 | #include <linux/fips.h> | ||
44 | #include <linux/time.h> | ||
45 | #include <linux/crypto.h> | ||
46 | #include <crypto/internal/rng.h> | ||
47 | |||
48 | struct rand_data; | ||
49 | int jent_read_entropy(struct rand_data *ec, unsigned char *data, | ||
50 | unsigned int len); | ||
51 | int jent_entropy_init(void); | ||
52 | struct rand_data *jent_entropy_collector_alloc(unsigned int osr, | ||
53 | unsigned int flags); | ||
54 | void jent_entropy_collector_free(struct rand_data *entropy_collector); | ||
55 | |||
56 | /*************************************************************************** | ||
57 | * Helper function | ||
58 | ***************************************************************************/ | ||
59 | |||
60 | __u64 jent_rol64(__u64 word, unsigned int shift) | ||
61 | { | ||
62 | return rol64(word, shift); | ||
63 | } | ||
64 | |||
65 | void *jent_zalloc(unsigned int len) | ||
66 | { | ||
67 | return kzalloc(len, GFP_KERNEL); | ||
68 | } | ||
69 | |||
70 | void jent_zfree(void *ptr) | ||
71 | { | ||
72 | kzfree(ptr); | ||
73 | } | ||
74 | |||
75 | int jent_fips_enabled(void) | ||
76 | { | ||
77 | return fips_enabled; | ||
78 | } | ||
79 | |||
80 | void jent_panic(char *s) | ||
81 | { | ||
82 | panic(s); | ||
83 | } | ||
84 | |||
85 | void jent_memcpy(void *dest, const void *src, unsigned int n) | ||
86 | { | ||
87 | memcpy(dest, src, n); | ||
88 | } | ||
89 | |||
90 | void jent_get_nstime(__u64 *out) | ||
91 | { | ||
92 | struct timespec ts; | ||
93 | __u64 tmp = 0; | ||
94 | |||
95 | tmp = random_get_entropy(); | ||
96 | |||
97 | /* | ||
98 | * If random_get_entropy does not return a value (which is possible on, | ||
99 | * for example, MIPS), invoke __getnstimeofday | ||
100 | * hoping that there are timers we can work with. | ||
101 | * | ||
102 | * The list of available timers can be obtained from | ||
103 | * /sys/devices/system/clocksource/clocksource0/available_clocksource | ||
104 | * and are registered with clocksource_register() | ||
105 | */ | ||
106 | if ((0 == tmp) && | ||
107 | (0 == __getnstimeofday(&ts))) { | ||
108 | tmp = ts.tv_sec; | ||
109 | tmp = tmp << 32; | ||
110 | tmp = tmp | ts.tv_nsec; | ||
111 | } | ||
112 | |||
113 | *out = tmp; | ||
114 | } | ||
115 | |||
116 | /*************************************************************************** | ||
117 | * Kernel crypto API interface | ||
118 | ***************************************************************************/ | ||
119 | |||
120 | struct jitterentropy { | ||
121 | spinlock_t jent_lock; | ||
122 | struct rand_data *entropy_collector; | ||
123 | }; | ||
124 | |||
125 | static int jent_kcapi_init(struct crypto_tfm *tfm) | ||
126 | { | ||
127 | struct jitterentropy *rng = crypto_tfm_ctx(tfm); | ||
128 | int ret = 0; | ||
129 | |||
130 | rng->entropy_collector = jent_entropy_collector_alloc(1, 0); | ||
131 | if (!rng->entropy_collector) | ||
132 | ret = -ENOMEM; | ||
133 | |||
134 | spin_lock_init(&rng->jent_lock); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | static void jent_kcapi_cleanup(struct crypto_tfm *tfm) | ||
139 | { | ||
140 | struct jitterentropy *rng = crypto_tfm_ctx(tfm); | ||
141 | |||
142 | spin_lock(&rng->jent_lock); | ||
143 | if (rng->entropy_collector) | ||
144 | jent_entropy_collector_free(rng->entropy_collector); | ||
145 | rng->entropy_collector = NULL; | ||
146 | spin_unlock(&rng->jent_lock); | ||
147 | } | ||
148 | |||
149 | static int jent_kcapi_random(struct crypto_rng *tfm, | ||
150 | const u8 *src, unsigned int slen, | ||
151 | u8 *rdata, unsigned int dlen) | ||
152 | { | ||
153 | struct jitterentropy *rng = crypto_rng_ctx(tfm); | ||
154 | int ret = 0; | ||
155 | |||
156 | spin_lock(&rng->jent_lock); | ||
157 | ret = jent_read_entropy(rng->entropy_collector, rdata, dlen); | ||
158 | spin_unlock(&rng->jent_lock); | ||
159 | |||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | static int jent_kcapi_reset(struct crypto_rng *tfm, | ||
164 | const u8 *seed, unsigned int slen) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static struct rng_alg jent_alg = { | ||
170 | .generate = jent_kcapi_random, | ||
171 | .seed = jent_kcapi_reset, | ||
172 | .seedsize = 0, | ||
173 | .base = { | ||
174 | .cra_name = "jitterentropy_rng", | ||
175 | .cra_driver_name = "jitterentropy_rng", | ||
176 | .cra_priority = 100, | ||
177 | .cra_ctxsize = sizeof(struct jitterentropy), | ||
178 | .cra_module = THIS_MODULE, | ||
179 | .cra_init = jent_kcapi_init, | ||
180 | .cra_exit = jent_kcapi_cleanup, | ||
181 | |||
182 | } | ||
183 | }; | ||
184 | |||
185 | static int __init jent_mod_init(void) | ||
186 | { | ||
187 | int ret = 0; | ||
188 | |||
189 | ret = jent_entropy_init(); | ||
190 | if (ret) { | ||
191 | pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret); | ||
192 | return -EFAULT; | ||
193 | } | ||
194 | return crypto_register_rng(&jent_alg); | ||
195 | } | ||
196 | |||
197 | static void __exit jent_mod_exit(void) | ||
198 | { | ||
199 | crypto_unregister_rng(&jent_alg); | ||
200 | } | ||
201 | |||
202 | module_init(jent_mod_init); | ||
203 | module_exit(jent_mod_exit); | ||
204 | |||
205 | MODULE_LICENSE("Dual BSD/GPL"); | ||
206 | MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>"); | ||
207 | MODULE_DESCRIPTION("Non-physical True Random Number Generator based on CPU Jitter"); | ||
208 | MODULE_ALIAS_CRYPTO("jitterentropy_rng"); | ||
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c index d3c30452edee..6dfb220b183c 100644 --- a/crypto/jitterentropy.c +++ b/crypto/jitterentropy.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Non-physical true random number generator based on timing jitter. | 2 | * Non-physical true random number generator based on timing jitter -- |
3 | * Jitter RNG standalone code. | ||
3 | * | 4 | * |
4 | * Copyright Stephan Mueller <smueller@chronox.de>, 2014 | 5 | * Copyright Stephan Mueller <smueller@chronox.de>, 2015 |
5 | * | 6 | * |
6 | * Design | 7 | * Design |
7 | * ====== | 8 | * ====== |
@@ -49,13 +50,14 @@ | |||
49 | * version 1.1.0 provided at http://www.chronox.de/jent.html | 50 | * version 1.1.0 provided at http://www.chronox.de/jent.html |
50 | */ | 51 | */ |
51 | 52 | ||
52 | #include <linux/module.h> | 53 | #ifdef __OPTIMIZE__ |
53 | #include <linux/slab.h> | 54 | #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy.c." |
54 | #include <linux/module.h> | 55 | #endif |
55 | #include <linux/fips.h> | 56 | |
56 | #include <linux/time.h> | 57 | typedef unsigned long long __u64; |
57 | #include <linux/crypto.h> | 58 | typedef long long __s64; |
58 | #include <crypto/internal/rng.h> | 59 | typedef unsigned int __u32; |
60 | #define NULL ((void *) 0) | ||
59 | 61 | ||
60 | /* The entropy pool */ | 62 | /* The entropy pool */ |
61 | struct rand_data { | 63 | struct rand_data { |
@@ -93,8 +95,6 @@ struct rand_data { | |||
93 | * entropy, saves MEMORY_SIZE RAM for | 95 | * entropy, saves MEMORY_SIZE RAM for |
94 | * entropy collector */ | 96 | * entropy collector */ |
95 | 97 | ||
96 | #define DRIVER_NAME "jitterentropy" | ||
97 | |||
98 | /* -- error codes for init function -- */ | 98 | /* -- error codes for init function -- */ |
99 | #define JENT_ENOTIME 1 /* Timer service not available */ | 99 | #define JENT_ENOTIME 1 /* Timer service not available */ |
100 | #define JENT_ECOARSETIME 2 /* Timer too coarse for RNG */ | 100 | #define JENT_ECOARSETIME 2 /* Timer too coarse for RNG */ |
@@ -110,32 +110,13 @@ struct rand_data { | |||
110 | * Helper functions | 110 | * Helper functions |
111 | ***************************************************************************/ | 111 | ***************************************************************************/ |
112 | 112 | ||
113 | static inline void jent_get_nstime(__u64 *out) | 113 | void jent_get_nstime(__u64 *out); |
114 | { | 114 | __u64 jent_rol64(__u64 word, unsigned int shift); |
115 | struct timespec ts; | 115 | void *jent_zalloc(unsigned int len); |
116 | __u64 tmp = 0; | 116 | void jent_zfree(void *ptr); |
117 | 117 | int jent_fips_enabled(void); | |
118 | tmp = random_get_entropy(); | 118 | void jent_panic(char *s); |
119 | 119 | void jent_memcpy(void *dest, const void *src, unsigned int n); | |
120 | /* | ||
121 | * If random_get_entropy does not return a value (which is possible on, | ||
122 | * for example, MIPS), invoke __getnstimeofday | ||
123 | * hoping that there are timers we can work with. | ||
124 | * | ||
125 | * The list of available timers can be obtained from | ||
126 | * /sys/devices/system/clocksource/clocksource0/available_clocksource | ||
127 | * and are registered with clocksource_register() | ||
128 | */ | ||
129 | if ((0 == tmp) && | ||
130 | (0 == __getnstimeofday(&ts))) { | ||
131 | tmp = ts.tv_sec; | ||
132 | tmp = tmp << 32; | ||
133 | tmp = tmp | ts.tv_nsec; | ||
134 | } | ||
135 | |||
136 | *out = tmp; | ||
137 | } | ||
138 | |||
139 | 120 | ||
140 | /** | 121 | /** |
141 | * Update of the loop count used for the next round of | 122 | * Update of the loop count used for the next round of |
@@ -184,20 +165,6 @@ static __u64 jent_loop_shuffle(struct rand_data *ec, | |||
184 | * Noise sources | 165 | * Noise sources |
185 | ***************************************************************************/ | 166 | ***************************************************************************/ |
186 | 167 | ||
187 | /* | ||
188 | * The disabling of the optimizations is performed as documented and assessed | ||
189 | * thoroughly in http://www.chronox.de/jent.html. However, instead of disabling | ||
190 | * the optimization of the entire C file, only the main functions the jitter is | ||
191 | * measured for are not optimized. These functions include the noise sources as | ||
192 | * well as the main functions triggering the noise sources. As the time | ||
193 | * measurement is done from one invocation of the jitter noise source to the | ||
194 | * next, even the execution jitter of the code invoking the noise sources | ||
195 | * contribute to the overall randomness as well. The behavior of the RNG and the | ||
196 | * statistical characteristics when only the mentioned functions are not | ||
197 | * optimized is almost equal to the a completely non-optimized RNG compilation | ||
198 | * as tested with the test tools provided at the initially mentioned web site. | ||
199 | */ | ||
200 | |||
201 | /** | 168 | /** |
202 | * CPU Jitter noise source -- this is the noise source based on the CPU | 169 | * CPU Jitter noise source -- this is the noise source based on the CPU |
203 | * execution time jitter | 170 | * execution time jitter |
@@ -232,8 +199,6 @@ static __u64 jent_loop_shuffle(struct rand_data *ec, | |||
232 | * | 199 | * |
233 | * @return Number of loops the folding operation is performed | 200 | * @return Number of loops the folding operation is performed |
234 | */ | 201 | */ |
235 | #pragma GCC push_options | ||
236 | #pragma GCC optimize ("-O0") | ||
237 | static __u64 jent_fold_time(struct rand_data *ec, __u64 time, | 202 | static __u64 jent_fold_time(struct rand_data *ec, __u64 time, |
238 | __u64 *folded, __u64 loop_cnt) | 203 | __u64 *folded, __u64 loop_cnt) |
239 | { | 204 | { |
@@ -263,7 +228,6 @@ static __u64 jent_fold_time(struct rand_data *ec, __u64 time, | |||
263 | *folded = new; | 228 | *folded = new; |
264 | return fold_loop_cnt; | 229 | return fold_loop_cnt; |
265 | } | 230 | } |
266 | #pragma GCC pop_options | ||
267 | 231 | ||
268 | /** | 232 | /** |
269 | * Memory Access noise source -- this is a noise source based on variations in | 233 | * Memory Access noise source -- this is a noise source based on variations in |
@@ -292,8 +256,6 @@ static __u64 jent_fold_time(struct rand_data *ec, __u64 time, | |||
292 | * | 256 | * |
293 | * @return Number of memory access operations | 257 | * @return Number of memory access operations |
294 | */ | 258 | */ |
295 | #pragma GCC push_options | ||
296 | #pragma GCC optimize ("-O0") | ||
297 | static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt) | 259 | static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt) |
298 | { | 260 | { |
299 | unsigned char *tmpval = NULL; | 261 | unsigned char *tmpval = NULL; |
@@ -333,7 +295,6 @@ static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt) | |||
333 | } | 295 | } |
334 | return i; | 296 | return i; |
335 | } | 297 | } |
336 | #pragma GCC pop_options | ||
337 | 298 | ||
338 | /*************************************************************************** | 299 | /*************************************************************************** |
339 | * Start of entropy processing logic | 300 | * Start of entropy processing logic |
@@ -382,8 +343,6 @@ static void jent_stuck(struct rand_data *ec, __u64 current_delta) | |||
382 | * | 343 | * |
383 | * @return One random bit | 344 | * @return One random bit |
384 | */ | 345 | */ |
385 | #pragma GCC push_options | ||
386 | #pragma GCC optimize ("-O0") | ||
387 | static __u64 jent_measure_jitter(struct rand_data *ec) | 346 | static __u64 jent_measure_jitter(struct rand_data *ec) |
388 | { | 347 | { |
389 | __u64 time = 0; | 348 | __u64 time = 0; |
@@ -413,7 +372,6 @@ static __u64 jent_measure_jitter(struct rand_data *ec) | |||
413 | 372 | ||
414 | return data; | 373 | return data; |
415 | } | 374 | } |
416 | #pragma GCC pop_options | ||
417 | 375 | ||
418 | /** | 376 | /** |
419 | * Von Neuman unbias as explained in RFC 4086 section 4.2. As shown in the | 377 | * Von Neuman unbias as explained in RFC 4086 section 4.2. As shown in the |
@@ -502,7 +460,7 @@ static void jent_stir_pool(struct rand_data *entropy_collector) | |||
502 | */ | 460 | */ |
503 | if ((entropy_collector->data >> i) & 1) | 461 | if ((entropy_collector->data >> i) & 1) |
504 | mixer.u64 ^= constant.u64; | 462 | mixer.u64 ^= constant.u64; |
505 | mixer.u64 = rol64(mixer.u64, 1); | 463 | mixer.u64 = jent_rol64(mixer.u64, 1); |
506 | } | 464 | } |
507 | entropy_collector->data ^= mixer.u64; | 465 | entropy_collector->data ^= mixer.u64; |
508 | } | 466 | } |
@@ -514,8 +472,6 @@ static void jent_stir_pool(struct rand_data *entropy_collector) | |||
514 | * Input: | 472 | * Input: |
515 | * @ec Reference to entropy collector | 473 | * @ec Reference to entropy collector |
516 | */ | 474 | */ |
517 | #pragma GCC push_options | ||
518 | #pragma GCC optimize ("-O0") | ||
519 | static void jent_gen_entropy(struct rand_data *ec) | 475 | static void jent_gen_entropy(struct rand_data *ec) |
520 | { | 476 | { |
521 | unsigned int k = 0; | 477 | unsigned int k = 0; |
@@ -565,7 +521,7 @@ static void jent_gen_entropy(struct rand_data *ec) | |||
565 | ec->data ^= ((ec->data >> 30) & 1); | 521 | ec->data ^= ((ec->data >> 30) & 1); |
566 | ec->data ^= ((ec->data >> 27) & 1); | 522 | ec->data ^= ((ec->data >> 27) & 1); |
567 | ec->data ^= ((ec->data >> 22) & 1); | 523 | ec->data ^= ((ec->data >> 22) & 1); |
568 | ec->data = rol64(ec->data, 1); | 524 | ec->data = jent_rol64(ec->data, 1); |
569 | 525 | ||
570 | /* | 526 | /* |
571 | * We multiply the loop value with ->osr to obtain the | 527 | * We multiply the loop value with ->osr to obtain the |
@@ -577,7 +533,6 @@ static void jent_gen_entropy(struct rand_data *ec) | |||
577 | if (ec->stir) | 533 | if (ec->stir) |
578 | jent_stir_pool(ec); | 534 | jent_stir_pool(ec); |
579 | } | 535 | } |
580 | #pragma GCC pop_options | ||
581 | 536 | ||
582 | /** | 537 | /** |
583 | * The continuous test required by FIPS 140-2 -- the function automatically | 538 | * The continuous test required by FIPS 140-2 -- the function automatically |
@@ -589,7 +544,7 @@ static void jent_gen_entropy(struct rand_data *ec) | |||
589 | */ | 544 | */ |
590 | static void jent_fips_test(struct rand_data *ec) | 545 | static void jent_fips_test(struct rand_data *ec) |
591 | { | 546 | { |
592 | if (!fips_enabled) | 547 | if (!jent_fips_enabled()) |
593 | return; | 548 | return; |
594 | 549 | ||
595 | /* prime the FIPS test */ | 550 | /* prime the FIPS test */ |
@@ -599,12 +554,11 @@ static void jent_fips_test(struct rand_data *ec) | |||
599 | } | 554 | } |
600 | 555 | ||
601 | if (ec->data == ec->old_data) | 556 | if (ec->data == ec->old_data) |
602 | panic(DRIVER_NAME ": Duplicate output detected\n"); | 557 | jent_panic("jitterentropy: Duplicate output detected\n"); |
603 | 558 | ||
604 | ec->old_data = ec->data; | 559 | ec->old_data = ec->data; |
605 | } | 560 | } |
606 | 561 | ||
607 | |||
608 | /** | 562 | /** |
609 | * Entry function: Obtain entropy for the caller. | 563 | * Entry function: Obtain entropy for the caller. |
610 | * | 564 | * |
@@ -627,15 +581,16 @@ static void jent_fips_test(struct rand_data *ec) | |||
627 | * The following error codes can occur: | 581 | * The following error codes can occur: |
628 | * -1 entropy_collector is NULL | 582 | * -1 entropy_collector is NULL |
629 | */ | 583 | */ |
630 | static ssize_t jent_read_entropy(struct rand_data *ec, u8 *data, size_t len) | 584 | int jent_read_entropy(struct rand_data *ec, unsigned char *data, |
585 | unsigned int len) | ||
631 | { | 586 | { |
632 | u8 *p = data; | 587 | unsigned char *p = data; |
633 | 588 | ||
634 | if (!ec) | 589 | if (!ec) |
635 | return -EINVAL; | 590 | return -1; |
636 | 591 | ||
637 | while (0 < len) { | 592 | while (0 < len) { |
638 | size_t tocopy; | 593 | unsigned int tocopy; |
639 | 594 | ||
640 | jent_gen_entropy(ec); | 595 | jent_gen_entropy(ec); |
641 | jent_fips_test(ec); | 596 | jent_fips_test(ec); |
@@ -643,7 +598,7 @@ static ssize_t jent_read_entropy(struct rand_data *ec, u8 *data, size_t len) | |||
643 | tocopy = (DATA_SIZE_BITS / 8); | 598 | tocopy = (DATA_SIZE_BITS / 8); |
644 | else | 599 | else |
645 | tocopy = len; | 600 | tocopy = len; |
646 | memcpy(p, &ec->data, tocopy); | 601 | jent_memcpy(p, &ec->data, tocopy); |
647 | 602 | ||
648 | len -= tocopy; | 603 | len -= tocopy; |
649 | p += tocopy; | 604 | p += tocopy; |
@@ -656,12 +611,12 @@ static ssize_t jent_read_entropy(struct rand_data *ec, u8 *data, size_t len) | |||
656 | * Initialization logic | 611 | * Initialization logic |
657 | ***************************************************************************/ | 612 | ***************************************************************************/ |
658 | 613 | ||
659 | static struct rand_data *jent_entropy_collector_alloc(unsigned int osr, | 614 | struct rand_data *jent_entropy_collector_alloc(unsigned int osr, |
660 | unsigned int flags) | 615 | unsigned int flags) |
661 | { | 616 | { |
662 | struct rand_data *entropy_collector; | 617 | struct rand_data *entropy_collector; |
663 | 618 | ||
664 | entropy_collector = kzalloc(sizeof(struct rand_data), GFP_KERNEL); | 619 | entropy_collector = jent_zalloc(sizeof(struct rand_data)); |
665 | if (!entropy_collector) | 620 | if (!entropy_collector) |
666 | return NULL; | 621 | return NULL; |
667 | 622 | ||
@@ -669,9 +624,9 @@ static struct rand_data *jent_entropy_collector_alloc(unsigned int osr, | |||
669 | /* Allocate memory for adding variations based on memory | 624 | /* Allocate memory for adding variations based on memory |
670 | * access | 625 | * access |
671 | */ | 626 | */ |
672 | entropy_collector->mem = kzalloc(JENT_MEMORY_SIZE, GFP_KERNEL); | 627 | entropy_collector->mem = jent_zalloc(JENT_MEMORY_SIZE); |
673 | if (!entropy_collector->mem) { | 628 | if (!entropy_collector->mem) { |
674 | kfree(entropy_collector); | 629 | jent_zfree(entropy_collector); |
675 | return NULL; | 630 | return NULL; |
676 | } | 631 | } |
677 | entropy_collector->memblocksize = JENT_MEMORY_BLOCKSIZE; | 632 | entropy_collector->memblocksize = JENT_MEMORY_BLOCKSIZE; |
@@ -696,17 +651,17 @@ static struct rand_data *jent_entropy_collector_alloc(unsigned int osr, | |||
696 | return entropy_collector; | 651 | return entropy_collector; |
697 | } | 652 | } |
698 | 653 | ||
699 | static void jent_entropy_collector_free(struct rand_data *entropy_collector) | 654 | void jent_entropy_collector_free(struct rand_data *entropy_collector) |
700 | { | 655 | { |
701 | if (entropy_collector->mem) | 656 | if (entropy_collector->mem) |
702 | kzfree(entropy_collector->mem); | 657 | jent_zfree(entropy_collector->mem); |
703 | entropy_collector->mem = NULL; | 658 | entropy_collector->mem = NULL; |
704 | if (entropy_collector) | 659 | if (entropy_collector) |
705 | kzfree(entropy_collector); | 660 | jent_zfree(entropy_collector); |
706 | entropy_collector = NULL; | 661 | entropy_collector = NULL; |
707 | } | 662 | } |
708 | 663 | ||
709 | static int jent_entropy_init(void) | 664 | int jent_entropy_init(void) |
710 | { | 665 | { |
711 | int i; | 666 | int i; |
712 | __u64 delta_sum = 0; | 667 | __u64 delta_sum = 0; |
@@ -832,97 +787,3 @@ static int jent_entropy_init(void) | |||
832 | 787 | ||
833 | return 0; | 788 | return 0; |
834 | } | 789 | } |
835 | |||
836 | /*************************************************************************** | ||
837 | * Kernel crypto API interface | ||
838 | ***************************************************************************/ | ||
839 | |||
840 | struct jitterentropy { | ||
841 | spinlock_t jent_lock; | ||
842 | struct rand_data *entropy_collector; | ||
843 | }; | ||
844 | |||
845 | static int jent_kcapi_init(struct crypto_tfm *tfm) | ||
846 | { | ||
847 | struct jitterentropy *rng = crypto_tfm_ctx(tfm); | ||
848 | int ret = 0; | ||
849 | |||
850 | rng->entropy_collector = jent_entropy_collector_alloc(1, 0); | ||
851 | if (!rng->entropy_collector) | ||
852 | ret = -ENOMEM; | ||
853 | |||
854 | spin_lock_init(&rng->jent_lock); | ||
855 | return ret; | ||
856 | } | ||
857 | |||
858 | static void jent_kcapi_cleanup(struct crypto_tfm *tfm) | ||
859 | { | ||
860 | struct jitterentropy *rng = crypto_tfm_ctx(tfm); | ||
861 | |||
862 | spin_lock(&rng->jent_lock); | ||
863 | if (rng->entropy_collector) | ||
864 | jent_entropy_collector_free(rng->entropy_collector); | ||
865 | rng->entropy_collector = NULL; | ||
866 | spin_unlock(&rng->jent_lock); | ||
867 | } | ||
868 | |||
869 | static int jent_kcapi_random(struct crypto_rng *tfm, | ||
870 | const u8 *src, unsigned int slen, | ||
871 | u8 *rdata, unsigned int dlen) | ||
872 | { | ||
873 | struct jitterentropy *rng = crypto_rng_ctx(tfm); | ||
874 | int ret = 0; | ||
875 | |||
876 | spin_lock(&rng->jent_lock); | ||
877 | ret = jent_read_entropy(rng->entropy_collector, rdata, dlen); | ||
878 | spin_unlock(&rng->jent_lock); | ||
879 | |||
880 | return ret; | ||
881 | } | ||
882 | |||
883 | static int jent_kcapi_reset(struct crypto_rng *tfm, | ||
884 | const u8 *seed, unsigned int slen) | ||
885 | { | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | static struct rng_alg jent_alg = { | ||
890 | .generate = jent_kcapi_random, | ||
891 | .seed = jent_kcapi_reset, | ||
892 | .seedsize = 0, | ||
893 | .base = { | ||
894 | .cra_name = "jitterentropy_rng", | ||
895 | .cra_driver_name = "jitterentropy_rng", | ||
896 | .cra_priority = 100, | ||
897 | .cra_ctxsize = sizeof(struct jitterentropy), | ||
898 | .cra_module = THIS_MODULE, | ||
899 | .cra_init = jent_kcapi_init, | ||
900 | .cra_exit = jent_kcapi_cleanup, | ||
901 | |||
902 | } | ||
903 | }; | ||
904 | |||
905 | static int __init jent_mod_init(void) | ||
906 | { | ||
907 | int ret = 0; | ||
908 | |||
909 | ret = jent_entropy_init(); | ||
910 | if (ret) { | ||
911 | pr_info(DRIVER_NAME ": Initialization failed with host not compliant with requirements: %d\n", ret); | ||
912 | return -EFAULT; | ||
913 | } | ||
914 | return crypto_register_rng(&jent_alg); | ||
915 | } | ||
916 | |||
917 | static void __exit jent_mod_exit(void) | ||
918 | { | ||
919 | crypto_unregister_rng(&jent_alg); | ||
920 | } | ||
921 | |||
922 | module_init(jent_mod_init); | ||
923 | module_exit(jent_mod_exit); | ||
924 | |||
925 | MODULE_LICENSE("Dual BSD/GPL"); | ||
926 | MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>"); | ||
927 | MODULE_DESCRIPTION("Non-physical True Random Number Generator based on CPU Jitter"); | ||
928 | MODULE_ALIAS_CRYPTO("jitterentropy_rng"); | ||