aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2015-06-23 10:18:54 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-06-25 11:18:32 -0400
commitdfc9fa91938bd0cd5597a3da33d613986149a1e6 (patch)
tree4eeef33d2c2046592acb662f59adb0d3c97e6017 /crypto
parentaefbef10e3ae6e2c6e3c54f906f10b34c73a2c66 (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/Makefile4
-rw-r--r--crypto/jitterentropy-kcapi.c208
-rw-r--r--crypto/jitterentropy.c213
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
106obj-$(CONFIG_CRYPTO_RNG2) += rng.o 106obj-$(CONFIG_CRYPTO_RNG2) += rng.o
107obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o 107obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
108obj-$(CONFIG_CRYPTO_DRBG) += drbg.o 108obj-$(CONFIG_CRYPTO_DRBG) += drbg.o
109obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy.o 109obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o
110CFLAGS_jitterentropy.o = -O0
111jitterentropy_rng-y := jitterentropy.o jitterentropy-kcapi.o
110obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o 112obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
111obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o 113obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
112obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o 114obj-$(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
48struct rand_data;
49int jent_read_entropy(struct rand_data *ec, unsigned char *data,
50 unsigned int len);
51int jent_entropy_init(void);
52struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
53 unsigned int flags);
54void 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
65void *jent_zalloc(unsigned int len)
66{
67 return kzalloc(len, GFP_KERNEL);
68}
69
70void jent_zfree(void *ptr)
71{
72 kzfree(ptr);
73}
74
75int jent_fips_enabled(void)
76{
77 return fips_enabled;
78}
79
80void jent_panic(char *s)
81{
82 panic(s);
83}
84
85void jent_memcpy(void *dest, const void *src, unsigned int n)
86{
87 memcpy(dest, src, n);
88}
89
90void 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
120struct jitterentropy {
121 spinlock_t jent_lock;
122 struct rand_data *entropy_collector;
123};
124
125static 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
138static 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
149static 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
163static int jent_kcapi_reset(struct crypto_rng *tfm,
164 const u8 *seed, unsigned int slen)
165{
166 return 0;
167}
168
169static 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
185static 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
197static void __exit jent_mod_exit(void)
198{
199 crypto_unregister_rng(&jent_alg);
200}
201
202module_init(jent_mod_init);
203module_exit(jent_mod_exit);
204
205MODULE_LICENSE("Dual BSD/GPL");
206MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
207MODULE_DESCRIPTION("Non-physical True Random Number Generator based on CPU Jitter");
208MODULE_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> 57typedef unsigned long long __u64;
57#include <linux/crypto.h> 58typedef long long __s64;
58#include <crypto/internal/rng.h> 59typedef unsigned int __u32;
60#define NULL ((void *) 0)
59 61
60/* The entropy pool */ 62/* The entropy pool */
61struct rand_data { 63struct 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
113static inline void jent_get_nstime(__u64 *out) 113void jent_get_nstime(__u64 *out);
114{ 114__u64 jent_rol64(__u64 word, unsigned int shift);
115 struct timespec ts; 115void *jent_zalloc(unsigned int len);
116 __u64 tmp = 0; 116void jent_zfree(void *ptr);
117 117int jent_fips_enabled(void);
118 tmp = random_get_entropy(); 118void jent_panic(char *s);
119 119void 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")
237static __u64 jent_fold_time(struct rand_data *ec, __u64 time, 202static __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")
297static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt) 259static 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")
387static __u64 jent_measure_jitter(struct rand_data *ec) 346static __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")
519static void jent_gen_entropy(struct rand_data *ec) 475static 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 */
590static void jent_fips_test(struct rand_data *ec) 545static 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 */
630static ssize_t jent_read_entropy(struct rand_data *ec, u8 *data, size_t len) 584int 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
659static struct rand_data *jent_entropy_collector_alloc(unsigned int osr, 614struct 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
699static void jent_entropy_collector_free(struct rand_data *entropy_collector) 654void 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
709static int jent_entropy_init(void) 664int 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
840struct jitterentropy {
841 spinlock_t jent_lock;
842 struct rand_data *entropy_collector;
843};
844
845static 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
858static 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
869static 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
883static int jent_kcapi_reset(struct crypto_rng *tfm,
884 const u8 *seed, unsigned int slen)
885{
886 return 0;
887}
888
889static 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
905static 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
917static void __exit jent_mod_exit(void)
918{
919 crypto_unregister_rng(&jent_alg);
920}
921
922module_init(jent_mod_init);
923module_exit(jent_mod_exit);
924
925MODULE_LICENSE("Dual BSD/GPL");
926MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
927MODULE_DESCRIPTION("Non-physical True Random Number Generator based on CPU Jitter");
928MODULE_ALIAS_CRYPTO("jitterentropy_rng");