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 - 2023 |
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 <crypto/hash.h> |
41 | #include <crypto/sha3.h> |
42 | #include <linux/fips.h> |
43 | #include <linux/kernel.h> |
44 | #include <linux/module.h> |
45 | #include <linux/slab.h> |
46 | #include <linux/time.h> |
47 | #include <crypto/internal/rng.h> |
48 | |
49 | #include "jitterentropy.h" |
50 | |
51 | #define JENT_CONDITIONING_HASH "sha3-256-generic" |
52 | |
53 | /*************************************************************************** |
54 | * Helper function |
55 | ***************************************************************************/ |
56 | |
57 | void *jent_kvzalloc(unsigned int len) |
58 | { |
59 | return kvzalloc(size: len, GFP_KERNEL); |
60 | } |
61 | |
62 | void jent_kvzfree(void *ptr, unsigned int len) |
63 | { |
64 | memzero_explicit(s: ptr, count: len); |
65 | kvfree(addr: ptr); |
66 | } |
67 | |
68 | void *jent_zalloc(unsigned int len) |
69 | { |
70 | return kzalloc(size: len, GFP_KERNEL); |
71 | } |
72 | |
73 | void jent_zfree(void *ptr) |
74 | { |
75 | kfree_sensitive(objp: ptr); |
76 | } |
77 | |
78 | /* |
79 | * Obtain a high-resolution time stamp value. The time stamp is used to measure |
80 | * the execution time of a given code path and its variations. Hence, the time |
81 | * stamp must have a sufficiently high resolution. |
82 | * |
83 | * Note, if the function returns zero because a given architecture does not |
84 | * implement a high-resolution time stamp, the RNG code's runtime test |
85 | * will detect it and will not produce output. |
86 | */ |
87 | void jent_get_nstime(__u64 *out) |
88 | { |
89 | __u64 tmp = 0; |
90 | |
91 | tmp = random_get_entropy(); |
92 | |
93 | /* |
94 | * If random_get_entropy does not return a value, i.e. it is not |
95 | * implemented for a given architecture, use a clock source. |
96 | * hoping that there are timers we can work with. |
97 | */ |
98 | if (tmp == 0) |
99 | tmp = ktime_get_ns(); |
100 | |
101 | *out = tmp; |
102 | jent_raw_hires_entropy_store(value: tmp); |
103 | } |
104 | |
105 | int jent_hash_time(void *hash_state, __u64 time, u8 *addtl, |
106 | unsigned int addtl_len, __u64 hash_loop_cnt, |
107 | unsigned int stuck) |
108 | { |
109 | struct shash_desc *hash_state_desc = (struct shash_desc *)hash_state; |
110 | SHASH_DESC_ON_STACK(desc, hash_state_desc->tfm); |
111 | u8 intermediary[SHA3_256_DIGEST_SIZE]; |
112 | __u64 j = 0; |
113 | int ret; |
114 | |
115 | desc->tfm = hash_state_desc->tfm; |
116 | |
117 | if (sizeof(intermediary) != crypto_shash_digestsize(tfm: desc->tfm)) { |
118 | pr_warn_ratelimited("Unexpected digest size\n" ); |
119 | return -EINVAL; |
120 | } |
121 | |
122 | /* |
123 | * This loop fills a buffer which is injected into the entropy pool. |
124 | * The main reason for this loop is to execute something over which we |
125 | * can perform a timing measurement. The injection of the resulting |
126 | * data into the pool is performed to ensure the result is used and |
127 | * the compiler cannot optimize the loop away in case the result is not |
128 | * used at all. Yet that data is considered "additional information" |
129 | * considering the terminology from SP800-90A without any entropy. |
130 | * |
131 | * Note, it does not matter which or how much data you inject, we are |
132 | * interested in one Keccack1600 compression operation performed with |
133 | * the crypto_shash_final. |
134 | */ |
135 | for (j = 0; j < hash_loop_cnt; j++) { |
136 | ret = crypto_shash_init(desc) ?: |
137 | crypto_shash_update(desc, data: intermediary, |
138 | len: sizeof(intermediary)) ?: |
139 | crypto_shash_finup(desc, data: addtl, len: addtl_len, out: intermediary); |
140 | if (ret) |
141 | goto err; |
142 | } |
143 | |
144 | /* |
145 | * Inject the data from the previous loop into the pool. This data is |
146 | * not considered to contain any entropy, but it stirs the pool a bit. |
147 | */ |
148 | ret = crypto_shash_update(desc, data: intermediary, len: sizeof(intermediary)); |
149 | if (ret) |
150 | goto err; |
151 | |
152 | /* |
153 | * Insert the time stamp into the hash context representing the pool. |
154 | * |
155 | * If the time stamp is stuck, do not finally insert the value into the |
156 | * entropy pool. Although this operation should not do any harm even |
157 | * when the time stamp has no entropy, SP800-90B requires that any |
158 | * conditioning operation to have an identical amount of input data |
159 | * according to section 3.1.5. |
160 | */ |
161 | if (!stuck) { |
162 | ret = crypto_shash_update(desc: hash_state_desc, data: (u8 *)&time, |
163 | len: sizeof(__u64)); |
164 | } |
165 | |
166 | err: |
167 | shash_desc_zero(desc); |
168 | memzero_explicit(s: intermediary, count: sizeof(intermediary)); |
169 | |
170 | return ret; |
171 | } |
172 | |
173 | int jent_read_random_block(void *hash_state, char *dst, unsigned int dst_len) |
174 | { |
175 | struct shash_desc *hash_state_desc = (struct shash_desc *)hash_state; |
176 | u8 jent_block[SHA3_256_DIGEST_SIZE]; |
177 | /* Obtain data from entropy pool and re-initialize it */ |
178 | int ret = crypto_shash_final(desc: hash_state_desc, out: jent_block) ?: |
179 | crypto_shash_init(desc: hash_state_desc) ?: |
180 | crypto_shash_update(desc: hash_state_desc, data: jent_block, |
181 | len: sizeof(jent_block)); |
182 | |
183 | if (!ret && dst_len) |
184 | memcpy(dst, jent_block, dst_len); |
185 | |
186 | memzero_explicit(s: jent_block, count: sizeof(jent_block)); |
187 | return ret; |
188 | } |
189 | |
190 | /*************************************************************************** |
191 | * Kernel crypto API interface |
192 | ***************************************************************************/ |
193 | |
194 | struct jitterentropy { |
195 | spinlock_t jent_lock; |
196 | struct rand_data *entropy_collector; |
197 | struct crypto_shash *tfm; |
198 | struct shash_desc *sdesc; |
199 | }; |
200 | |
201 | static void jent_kcapi_cleanup(struct crypto_tfm *tfm) |
202 | { |
203 | struct jitterentropy *rng = crypto_tfm_ctx(tfm); |
204 | |
205 | spin_lock(lock: &rng->jent_lock); |
206 | |
207 | if (rng->sdesc) { |
208 | shash_desc_zero(desc: rng->sdesc); |
209 | kfree(objp: rng->sdesc); |
210 | } |
211 | rng->sdesc = NULL; |
212 | |
213 | if (rng->tfm) |
214 | crypto_free_shash(tfm: rng->tfm); |
215 | rng->tfm = NULL; |
216 | |
217 | if (rng->entropy_collector) |
218 | jent_entropy_collector_free(entropy_collector: rng->entropy_collector); |
219 | rng->entropy_collector = NULL; |
220 | spin_unlock(lock: &rng->jent_lock); |
221 | } |
222 | |
223 | static int jent_kcapi_init(struct crypto_tfm *tfm) |
224 | { |
225 | struct jitterentropy *rng = crypto_tfm_ctx(tfm); |
226 | struct crypto_shash *hash; |
227 | struct shash_desc *sdesc; |
228 | int size, ret = 0; |
229 | |
230 | spin_lock_init(&rng->jent_lock); |
231 | |
232 | /* |
233 | * Use SHA3-256 as conditioner. We allocate only the generic |
234 | * implementation as we are not interested in high-performance. The |
235 | * execution time of the SHA3 operation is measured and adds to the |
236 | * Jitter RNG's unpredictable behavior. If we have a slower hash |
237 | * implementation, the execution timing variations are larger. When |
238 | * using a fast implementation, we would need to call it more often |
239 | * as its variations are lower. |
240 | */ |
241 | hash = crypto_alloc_shash(JENT_CONDITIONING_HASH, type: 0, mask: 0); |
242 | if (IS_ERR(ptr: hash)) { |
243 | pr_err("Cannot allocate conditioning digest\n" ); |
244 | return PTR_ERR(ptr: hash); |
245 | } |
246 | rng->tfm = hash; |
247 | |
248 | size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm: hash); |
249 | sdesc = kmalloc(size, GFP_KERNEL); |
250 | if (!sdesc) { |
251 | ret = -ENOMEM; |
252 | goto err; |
253 | } |
254 | |
255 | sdesc->tfm = hash; |
256 | crypto_shash_init(desc: sdesc); |
257 | rng->sdesc = sdesc; |
258 | |
259 | rng->entropy_collector = |
260 | jent_entropy_collector_alloc(CONFIG_CRYPTO_JITTERENTROPY_OSR, flags: 0, |
261 | hash_state: sdesc); |
262 | if (!rng->entropy_collector) { |
263 | ret = -ENOMEM; |
264 | goto err; |
265 | } |
266 | |
267 | spin_lock_init(&rng->jent_lock); |
268 | return 0; |
269 | |
270 | err: |
271 | jent_kcapi_cleanup(tfm); |
272 | return ret; |
273 | } |
274 | |
275 | static int jent_kcapi_random(struct crypto_rng *tfm, |
276 | const u8 *src, unsigned int slen, |
277 | u8 *rdata, unsigned int dlen) |
278 | { |
279 | struct jitterentropy *rng = crypto_rng_ctx(tfm); |
280 | int ret = 0; |
281 | |
282 | spin_lock(lock: &rng->jent_lock); |
283 | |
284 | ret = jent_read_entropy(ec: rng->entropy_collector, data: rdata, len: dlen); |
285 | |
286 | if (ret == -3) { |
287 | /* Handle permanent health test error */ |
288 | /* |
289 | * If the kernel was booted with fips=1, it implies that |
290 | * the entire kernel acts as a FIPS 140 module. In this case |
291 | * an SP800-90B permanent health test error is treated as |
292 | * a FIPS module error. |
293 | */ |
294 | if (fips_enabled) |
295 | panic(fmt: "Jitter RNG permanent health test failure\n" ); |
296 | |
297 | pr_err("Jitter RNG permanent health test failure\n" ); |
298 | ret = -EFAULT; |
299 | } else if (ret == -2) { |
300 | /* Handle intermittent health test error */ |
301 | pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n" ); |
302 | ret = -EAGAIN; |
303 | } else if (ret == -1) { |
304 | /* Handle other errors */ |
305 | ret = -EINVAL; |
306 | } |
307 | |
308 | spin_unlock(lock: &rng->jent_lock); |
309 | |
310 | return ret; |
311 | } |
312 | |
313 | static int jent_kcapi_reset(struct crypto_rng *tfm, |
314 | const u8 *seed, unsigned int slen) |
315 | { |
316 | return 0; |
317 | } |
318 | |
319 | static struct rng_alg jent_alg = { |
320 | .generate = jent_kcapi_random, |
321 | .seed = jent_kcapi_reset, |
322 | .seedsize = 0, |
323 | .base = { |
324 | .cra_name = "jitterentropy_rng" , |
325 | .cra_driver_name = "jitterentropy_rng" , |
326 | .cra_priority = 100, |
327 | .cra_ctxsize = sizeof(struct jitterentropy), |
328 | .cra_module = THIS_MODULE, |
329 | .cra_init = jent_kcapi_init, |
330 | .cra_exit = jent_kcapi_cleanup, |
331 | } |
332 | }; |
333 | |
334 | static int __init jent_mod_init(void) |
335 | { |
336 | SHASH_DESC_ON_STACK(desc, tfm); |
337 | struct crypto_shash *tfm; |
338 | int ret = 0; |
339 | |
340 | jent_testing_init(); |
341 | |
342 | tfm = crypto_alloc_shash(JENT_CONDITIONING_HASH, type: 0, mask: 0); |
343 | if (IS_ERR(ptr: tfm)) { |
344 | jent_testing_exit(); |
345 | return PTR_ERR(ptr: tfm); |
346 | } |
347 | |
348 | desc->tfm = tfm; |
349 | crypto_shash_init(desc); |
350 | ret = jent_entropy_init(CONFIG_CRYPTO_JITTERENTROPY_OSR, flags: 0, hash_state: desc, NULL); |
351 | shash_desc_zero(desc); |
352 | crypto_free_shash(tfm); |
353 | if (ret) { |
354 | /* Handle permanent health test error */ |
355 | if (fips_enabled) |
356 | panic(fmt: "jitterentropy: Initialization failed with host not compliant with requirements: %d\n" , ret); |
357 | |
358 | jent_testing_exit(); |
359 | pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n" , ret); |
360 | return -EFAULT; |
361 | } |
362 | return crypto_register_rng(alg: &jent_alg); |
363 | } |
364 | |
365 | static void __exit jent_mod_exit(void) |
366 | { |
367 | jent_testing_exit(); |
368 | crypto_unregister_rng(alg: &jent_alg); |
369 | } |
370 | |
371 | module_init(jent_mod_init); |
372 | module_exit(jent_mod_exit); |
373 | |
374 | MODULE_LICENSE("Dual BSD/GPL" ); |
375 | MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>" ); |
376 | MODULE_DESCRIPTION("Non-physical True Random Number Generator based on CPU Jitter" ); |
377 | MODULE_ALIAS_CRYPTO("jitterentropy_rng" ); |
378 | |