/src/libgcrypt/random/jitterentropy-base.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Non-physical true random number generator based on timing jitter. |
3 | | * |
4 | | * Copyright Stephan Mueller <smueller@chronox.de>, 2014 - 2021 |
5 | | * |
6 | | * Design |
7 | | * ====== |
8 | | * |
9 | | * See documentation in doc/ folder. |
10 | | * |
11 | | * Interface |
12 | | * ========= |
13 | | * |
14 | | * See documentation in jitterentropy(3) man page. |
15 | | * |
16 | | * License: see LICENSE file in root directory |
17 | | * |
18 | | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
19 | | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
20 | | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF |
21 | | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE |
22 | | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
23 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
24 | | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
25 | | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
26 | | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
28 | | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH |
29 | | * DAMAGE. |
30 | | */ |
31 | | |
32 | | #include "jitterentropy.h" |
33 | | |
34 | | #include "jitterentropy-base.h" |
35 | | #include "jitterentropy-gcd.h" |
36 | | #include "jitterentropy-health.h" |
37 | | #include "jitterentropy-noise.h" |
38 | | #include "jitterentropy-timer.h" |
39 | | #include "jitterentropy-sha3.h" |
40 | | |
41 | 0 | #define MAJVERSION 3 /* API / ABI incompatible changes, functional changes that |
42 | | * require consumer to be updated (as long as this number |
43 | | * is zero, the API is not considered stable and can |
44 | | * change without a bump of the major version) */ |
45 | 0 | #define MINVERSION 3 /* API compatible, ABI may change, functional |
46 | | * enhancements only, consumer can be left unchanged if |
47 | | * enhancements are not considered */ |
48 | 0 | #define PATCHLEVEL 0 /* API / ABI compatible, no functional changes, no |
49 | | * enhancements, bug fixes only */ |
50 | | |
51 | | /*************************************************************************** |
52 | | * Jitter RNG Static Definitions |
53 | | * |
54 | | * None of the following should be altered |
55 | | ***************************************************************************/ |
56 | | |
57 | | #ifdef __OPTIMIZE__ |
58 | | #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy.c." |
59 | | #endif |
60 | | |
61 | | /* |
62 | | * JENT_POWERUP_TESTLOOPCOUNT needs some loops to identify edge |
63 | | * systems. 100 is definitely too little. |
64 | | * |
65 | | * SP800-90B requires at least 1024 initial test cycles. |
66 | | */ |
67 | 0 | #define JENT_POWERUP_TESTLOOPCOUNT 1024 |
68 | | |
69 | | /** |
70 | | * jent_version() - Return machine-usable version number of jent library |
71 | | * |
72 | | * The function returns a version number that is monotonic increasing |
73 | | * for newer versions. The version numbers are multiples of 100. For example, |
74 | | * version 1.2.3 is converted to 1020300 -- the last two digits are reserved |
75 | | * for future use. |
76 | | * |
77 | | * The result of this function can be used in comparing the version number |
78 | | * in a calling program if version-specific calls need to be make. |
79 | | * |
80 | | * @return Version number of jitterentropy library |
81 | | */ |
82 | | JENT_PRIVATE_STATIC |
83 | | unsigned int jent_version(void) |
84 | 0 | { |
85 | 0 | unsigned int version = 0; |
86 | |
|
87 | 0 | version = MAJVERSION * 1000000; |
88 | 0 | version += MINVERSION * 10000; |
89 | 0 | version += PATCHLEVEL * 100; |
90 | |
|
91 | 0 | return version; |
92 | 0 | } |
93 | | |
94 | | /*************************************************************************** |
95 | | * Helper |
96 | | ***************************************************************************/ |
97 | | |
98 | | /* Calculate log2 of given value assuming that the value is a power of 2 */ |
99 | | static inline unsigned int jent_log2_simple(unsigned int val) |
100 | 0 | { |
101 | 0 | unsigned int idx = 0; |
102 | |
|
103 | 0 | while (val >>= 1) |
104 | 0 | idx++; |
105 | 0 | return idx; |
106 | 0 | } |
107 | | |
108 | | /* Increase the memory size by one step */ |
109 | | static inline unsigned int jent_update_memsize(unsigned int flags) |
110 | 0 | { |
111 | 0 | unsigned int global_max = JENT_FLAGS_TO_MAX_MEMSIZE( |
112 | 0 | JENT_MAX_MEMSIZE_MAX); |
113 | 0 | unsigned int max; |
114 | |
|
115 | 0 | max = JENT_FLAGS_TO_MAX_MEMSIZE(flags); |
116 | |
|
117 | 0 | if (!max) { |
118 | | /* |
119 | | * The safe starting value is the amount of memory we allocated |
120 | | * last round. |
121 | | */ |
122 | 0 | max = jent_log2_simple(JENT_MEMORY_SIZE); |
123 | | /* Adjust offset */ |
124 | 0 | max = (max > JENT_MAX_MEMSIZE_OFFSET) ? |
125 | 0 | max - JENT_MAX_MEMSIZE_OFFSET : 0; |
126 | 0 | } else { |
127 | 0 | max++; |
128 | 0 | } |
129 | |
|
130 | 0 | max = (max > global_max) ? global_max : max; |
131 | | |
132 | | /* Clear out the max size */ |
133 | 0 | flags &= ~JENT_MAX_MEMSIZE_MASK; |
134 | | /* Set the freshly calculated max size */ |
135 | 0 | flags |= JENT_MAX_MEMSIZE_TO_FLAGS(max); |
136 | |
|
137 | 0 | return flags; |
138 | 0 | } |
139 | | |
140 | | /*************************************************************************** |
141 | | * Random Number Generation |
142 | | ***************************************************************************/ |
143 | | |
144 | | /** |
145 | | * Entry function: Obtain entropy for the caller. |
146 | | * |
147 | | * This function invokes the entropy gathering logic as often to generate |
148 | | * as many bytes as requested by the caller. The entropy gathering logic |
149 | | * creates 64 bit per invocation. |
150 | | * |
151 | | * This function truncates the last 64 bit entropy value output to the exact |
152 | | * size specified by the caller. |
153 | | * |
154 | | * @ec [in] Reference to entropy collector |
155 | | * @data [out] pointer to buffer for storing random data -- buffer must |
156 | | * already exist |
157 | | * @len [in] size of the buffer, specifying also the requested number of random |
158 | | * in bytes |
159 | | * |
160 | | * @return number of bytes returned when request is fulfilled or an error |
161 | | * |
162 | | * The following error codes can occur: |
163 | | * -1 entropy_collector is NULL |
164 | | * -2 RCT failed |
165 | | * -3 APT test failed |
166 | | * -4 The timer cannot be initialized |
167 | | * -5 LAG failure |
168 | | */ |
169 | | JENT_PRIVATE_STATIC |
170 | | ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len) |
171 | 0 | { |
172 | 0 | char *p = data; |
173 | 0 | size_t orig_len = len; |
174 | 0 | int ret = 0; |
175 | |
|
176 | 0 | if (NULL == ec) |
177 | 0 | return -1; |
178 | | |
179 | 0 | if (jent_notime_settick(ec)) |
180 | 0 | return -4; |
181 | | |
182 | 0 | while (len > 0) { |
183 | 0 | size_t tocopy; |
184 | 0 | unsigned int health_test_result; |
185 | |
|
186 | 0 | jent_random_data(ec); |
187 | |
|
188 | 0 | if ((health_test_result = jent_health_failure(ec))) { |
189 | 0 | if (health_test_result & JENT_RCT_FAILURE) |
190 | 0 | ret = -2; |
191 | 0 | else if (health_test_result & JENT_APT_FAILURE) |
192 | 0 | ret = -3; |
193 | 0 | else |
194 | 0 | ret = -5; |
195 | |
|
196 | 0 | goto err; |
197 | 0 | } |
198 | | |
199 | 0 | if ((DATA_SIZE_BITS / 8) < len) |
200 | 0 | tocopy = (DATA_SIZE_BITS / 8); |
201 | 0 | else |
202 | 0 | tocopy = len; |
203 | 0 | memcpy(p, &ec->data, tocopy); |
204 | |
|
205 | 0 | len -= tocopy; |
206 | 0 | p += tocopy; |
207 | 0 | } |
208 | | |
209 | | /* |
210 | | * To be on the safe side, we generate one more round of entropy |
211 | | * which we do not give out to the caller. That round shall ensure |
212 | | * that in case the calling application crashes, memory dumps, pages |
213 | | * out, or due to the CPU Jitter RNG lingering in memory for long |
214 | | * time without being moved and an attacker cracks the application, |
215 | | * all he reads in the entropy pool is a value that is NEVER EVER |
216 | | * being used for anything. Thus, he does NOT see the previous value |
217 | | * that was returned to the caller for cryptographic purposes. |
218 | | */ |
219 | | /* |
220 | | * If we use secured memory, do not use that precaution as the secure |
221 | | * memory protects the entropy pool. Moreover, note that using this |
222 | | * call reduces the speed of the RNG by up to half |
223 | | */ |
224 | | #ifndef JENT_CPU_JITTERENTROPY_SECURE_MEMORY |
225 | | jent_random_data(ec); |
226 | | #endif |
227 | | |
228 | 0 | err: |
229 | 0 | jent_notime_unsettick(ec); |
230 | 0 | return ret ? ret : (ssize_t)orig_len; |
231 | 0 | } |
232 | | |
233 | | static struct rand_data *_jent_entropy_collector_alloc(unsigned int osr, |
234 | | unsigned int flags); |
235 | | |
236 | | /** |
237 | | * Entry function: Obtain entropy for the caller. |
238 | | * |
239 | | * This is a service function to jent_read_entropy() with the difference |
240 | | * that it automatically re-allocates the entropy collector if a health |
241 | | * test failure is observed. Before reallocation, a new power-on health test |
242 | | * is performed. The allocation of the new entropy collector automatically |
243 | | * increases the OSR by one. This is done based on the idea that a health |
244 | | * test failure indicates that the assumed entropy rate is too high. |
245 | | * |
246 | | * Note the function returns with an health test error if the OSR is |
247 | | * getting too large. If an error is returned by this function, the Jitter RNG |
248 | | * is not safe to be used on the current system. |
249 | | * |
250 | | * @ec [in] Reference to entropy collector - this is a double pointer as |
251 | | * The entropy collector may be freed and reallocated. |
252 | | * @data [out] pointer to buffer for storing random data -- buffer must |
253 | | * already exist |
254 | | * @len [in] size of the buffer, specifying also the requested number of random |
255 | | * in bytes |
256 | | * |
257 | | * @return see jent_read_entropy() |
258 | | */ |
259 | | JENT_PRIVATE_STATIC |
260 | | ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len) |
261 | 0 | { |
262 | 0 | char *p = data; |
263 | 0 | size_t orig_len = len; |
264 | 0 | ssize_t ret = 0; |
265 | |
|
266 | 0 | if (!ec) |
267 | 0 | return -1; |
268 | | |
269 | 0 | while (len > 0) { |
270 | 0 | unsigned int osr, flags, max_mem_set; |
271 | |
|
272 | 0 | ret = jent_read_entropy(*ec, p, len); |
273 | |
|
274 | 0 | switch (ret) { |
275 | 0 | case -1: |
276 | 0 | case -4: |
277 | 0 | return ret; |
278 | 0 | case -2: |
279 | 0 | case -3: |
280 | 0 | case -5: |
281 | 0 | osr = (*ec)->osr + 1; |
282 | 0 | flags = (*ec)->flags; |
283 | 0 | max_mem_set = (*ec)->max_mem_set; |
284 | | |
285 | | /* generic arbitrary cutoff */ |
286 | 0 | if (osr > 20) |
287 | 0 | return ret; |
288 | | |
289 | | /* |
290 | | * If the caller did not set any specific maximum value |
291 | | * let the Jitter RNG increase the maximum memory by |
292 | | * one step. |
293 | | */ |
294 | 0 | if (!max_mem_set) |
295 | 0 | flags = jent_update_memsize(flags); |
296 | | |
297 | | /* |
298 | | * re-allocate entropy collector with higher OSR and |
299 | | * memory size |
300 | | */ |
301 | 0 | jent_entropy_collector_free(*ec); |
302 | | |
303 | | /* Perform new health test with updated OSR */ |
304 | 0 | if (jent_entropy_init_ex(osr, flags)) |
305 | 0 | return -1; |
306 | | |
307 | 0 | *ec = _jent_entropy_collector_alloc(osr, flags); |
308 | 0 | if (!*ec) |
309 | 0 | return -1; |
310 | | |
311 | | /* Remember whether caller configured memory size */ |
312 | 0 | (*ec)->max_mem_set = !!max_mem_set; |
313 | |
|
314 | 0 | break; |
315 | | |
316 | 0 | default: |
317 | 0 | len -= (size_t)ret; |
318 | 0 | p += (size_t)ret; |
319 | 0 | } |
320 | 0 | } |
321 | | |
322 | 0 | return (ssize_t)orig_len; |
323 | 0 | } |
324 | | |
325 | | /*************************************************************************** |
326 | | * Initialization logic |
327 | | ***************************************************************************/ |
328 | | |
329 | | /* |
330 | | * Obtain memory size to allocate for memory access variations. |
331 | | * |
332 | | * The maximum variations we can get from the memory access is when we allocate |
333 | | * a bit more memory than we have as data cache. But allocating as much |
334 | | * memory as we have as data cache might strain the resources on the system |
335 | | * more than necessary. |
336 | | * |
337 | | * On a lot of systems it is not necessary to need so much memory as the |
338 | | * variations coming from the general Jitter RNG execution commonly provide |
339 | | * large amount of variations. |
340 | | * |
341 | | * Thus, the default is: |
342 | | * |
343 | | * min(JENT_MEMORY_SIZE, data cache size) |
344 | | * |
345 | | * In case the data cache size cannot be obtained, use JENT_MEMORY_SIZE. |
346 | | * |
347 | | * If the caller provides a maximum memory size, use |
348 | | * min(provided max memory, data cache size). |
349 | | */ |
350 | | static inline uint32_t jent_memsize(unsigned int flags) |
351 | 0 | { |
352 | 0 | uint32_t memsize, max_memsize; |
353 | |
|
354 | 0 | max_memsize = JENT_FLAGS_TO_MAX_MEMSIZE(flags); |
355 | |
|
356 | 0 | if (max_memsize == 0) { |
357 | 0 | max_memsize = JENT_MEMORY_SIZE; |
358 | 0 | } else { |
359 | 0 | max_memsize = UINT32_C(1) << (max_memsize + |
360 | 0 | JENT_MAX_MEMSIZE_OFFSET); |
361 | 0 | } |
362 | | |
363 | | /* Allocate memory for adding variations based on memory access */ |
364 | 0 | memsize = jent_cache_size_roundup(); |
365 | | |
366 | | /* Limit the memory as defined by caller */ |
367 | 0 | memsize = (memsize > max_memsize) ? max_memsize : memsize; |
368 | | |
369 | | /* Set a value if none was found */ |
370 | 0 | if (!memsize) |
371 | 0 | memsize = JENT_MEMORY_SIZE; |
372 | |
|
373 | 0 | return memsize; |
374 | 0 | } |
375 | | |
376 | | static int jent_selftest_run = 0; |
377 | | |
378 | | static struct rand_data |
379 | | *jent_entropy_collector_alloc_internal(unsigned int osr, unsigned int flags) |
380 | 0 | { |
381 | 0 | struct rand_data *entropy_collector; |
382 | | |
383 | | /* |
384 | | * Requesting disabling and forcing of internal timer |
385 | | * makes no sense. |
386 | | */ |
387 | 0 | if ((flags & JENT_DISABLE_INTERNAL_TIMER) && |
388 | 0 | (flags & JENT_FORCE_INTERNAL_TIMER)) |
389 | 0 | return NULL; |
390 | | |
391 | | /* Force the self test to be run */ |
392 | 0 | if (!jent_selftest_run && jent_entropy_init_ex(osr, flags)) |
393 | 0 | return NULL; |
394 | | |
395 | | /* |
396 | | * If the initial test code concludes to force the internal timer |
397 | | * and the user requests it not to be used, do not allocate |
398 | | * the Jitter RNG instance. |
399 | | */ |
400 | 0 | if (jent_notime_forced() && (flags & JENT_DISABLE_INTERNAL_TIMER)) |
401 | 0 | return NULL; |
402 | | |
403 | 0 | entropy_collector = jent_zalloc(sizeof(struct rand_data)); |
404 | 0 | if (NULL == entropy_collector) |
405 | 0 | return NULL; |
406 | | |
407 | 0 | if (!(flags & JENT_DISABLE_MEMORY_ACCESS)) { |
408 | 0 | uint32_t memsize = jent_memsize(flags); |
409 | |
|
410 | 0 | entropy_collector->mem = _gcry_calloc (1, memsize); |
411 | |
|
412 | 0 | #ifdef JENT_RANDOM_MEMACCESS |
413 | | /* |
414 | | * Transform the size into a mask - it is assumed that size is |
415 | | * a power of 2. |
416 | | */ |
417 | 0 | entropy_collector->memmask = memsize - 1; |
418 | | #else /* JENT_RANDOM_MEMACCESS */ |
419 | | entropy_collector->memblocksize = memsize / JENT_MEMORY_BLOCKS; |
420 | | entropy_collector->memblocks = JENT_MEMORY_BLOCKS; |
421 | | |
422 | | /* sanity check */ |
423 | | if (entropy_collector->memblocksize * |
424 | | entropy_collector->memblocks != memsize) |
425 | | goto err; |
426 | | |
427 | | #endif /* JENT_RANDOM_MEMACCESS */ |
428 | |
|
429 | 0 | if (entropy_collector->mem == NULL) |
430 | 0 | goto err; |
431 | 0 | entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS; |
432 | 0 | } |
433 | | |
434 | | /* verify and set the oversampling rate */ |
435 | 0 | if (osr < JENT_MIN_OSR) |
436 | 0 | osr = JENT_MIN_OSR; |
437 | 0 | entropy_collector->osr = osr; |
438 | 0 | entropy_collector->flags = flags; |
439 | |
|
440 | 0 | if (jent_fips_enabled() || (flags & JENT_FORCE_FIPS)) |
441 | 0 | entropy_collector->fips_enabled = 1; |
442 | | |
443 | | /* Initialize the APT */ |
444 | 0 | jent_apt_init(entropy_collector, osr); |
445 | | |
446 | | /* Initialize the Lag Predictor Test */ |
447 | 0 | jent_lag_init(entropy_collector, osr); |
448 | | |
449 | | /* Was jent_entropy_init run (establishing the common GCD)? */ |
450 | 0 | if (jent_gcd_get(&entropy_collector->jent_common_timer_gcd)) { |
451 | | /* |
452 | | * It was not. This should probably be an error, but this |
453 | | * behavior breaks the test code. Set the gcd to a value that |
454 | | * won't hurt anything. |
455 | | */ |
456 | 0 | entropy_collector->jent_common_timer_gcd = 1; |
457 | 0 | } |
458 | | |
459 | | /* |
460 | | * Use timer-less noise source - note, OSR must be set in |
461 | | * entropy_collector! |
462 | | */ |
463 | 0 | if (!(flags & JENT_DISABLE_INTERNAL_TIMER)) { |
464 | 0 | if (jent_notime_enable(entropy_collector, flags)) |
465 | 0 | goto err; |
466 | 0 | } |
467 | | |
468 | 0 | return entropy_collector; |
469 | | |
470 | 0 | err: |
471 | 0 | if (entropy_collector->mem != NULL) |
472 | 0 | jent_zfree(entropy_collector->mem, JENT_MEMORY_SIZE); |
473 | 0 | jent_zfree(entropy_collector, sizeof(struct rand_data)); |
474 | 0 | return NULL; |
475 | 0 | } |
476 | | |
477 | | static struct rand_data *_jent_entropy_collector_alloc(unsigned int osr, |
478 | | unsigned int flags) |
479 | 0 | { |
480 | 0 | struct rand_data *ec = jent_entropy_collector_alloc_internal(osr, |
481 | 0 | flags); |
482 | |
|
483 | 0 | if (!ec) |
484 | 0 | return ec; |
485 | | |
486 | | /* fill the data pad with non-zero values */ |
487 | 0 | if (jent_notime_settick(ec)) { |
488 | 0 | jent_entropy_collector_free(ec); |
489 | 0 | return NULL; |
490 | 0 | } |
491 | 0 | jent_random_data(ec); |
492 | 0 | jent_notime_unsettick(ec); |
493 | |
|
494 | 0 | return ec; |
495 | 0 | } |
496 | | |
497 | | JENT_PRIVATE_STATIC |
498 | | struct rand_data *jent_entropy_collector_alloc(unsigned int osr, |
499 | | unsigned int flags) |
500 | 0 | { |
501 | 0 | struct rand_data *ec = _jent_entropy_collector_alloc(osr, flags); |
502 | | |
503 | | /* Remember that the caller provided a maximum size flag */ |
504 | 0 | if (ec) |
505 | 0 | ec->max_mem_set = !!JENT_FLAGS_TO_MAX_MEMSIZE(flags); |
506 | |
|
507 | 0 | return ec; |
508 | 0 | } |
509 | | |
510 | | JENT_PRIVATE_STATIC |
511 | | void jent_entropy_collector_free(struct rand_data *entropy_collector) |
512 | 0 | { |
513 | 0 | if (entropy_collector != NULL) { |
514 | 0 | jent_notime_disable(entropy_collector); |
515 | 0 | if (entropy_collector->mem != NULL) { |
516 | 0 | jent_zfree(entropy_collector->mem, |
517 | 0 | jent_memsize(entropy_collector->flags)); |
518 | 0 | entropy_collector->mem = NULL; |
519 | 0 | } |
520 | 0 | jent_zfree(entropy_collector, sizeof(struct rand_data)); |
521 | 0 | } |
522 | 0 | } |
523 | | |
524 | | int jent_time_entropy_init(unsigned int osr, unsigned int flags) |
525 | 0 | { |
526 | 0 | struct rand_data *ec; |
527 | 0 | uint64_t *delta_history; |
528 | 0 | int i, time_backwards = 0, count_stuck = 0, ret = 0; |
529 | 0 | unsigned int health_test_result; |
530 | |
|
531 | 0 | delta_history = jent_gcd_init(JENT_POWERUP_TESTLOOPCOUNT); |
532 | 0 | if (!delta_history) |
533 | 0 | return EMEM; |
534 | | |
535 | 0 | if (flags & JENT_FORCE_INTERNAL_TIMER) |
536 | 0 | jent_notime_force(); |
537 | 0 | else |
538 | 0 | flags |= JENT_DISABLE_INTERNAL_TIMER; |
539 | | |
540 | | /* |
541 | | * If the start-up health tests (including the APT and RCT) are not |
542 | | * run, then the entropy source is not 90B compliant. We could test if |
543 | | * fips_enabled should be set using the jent_fips_enabled() function, |
544 | | * but this can be overridden using the JENT_FORCE_FIPS flag, which |
545 | | * isn't passed in yet. It is better to run the tests on the small |
546 | | * amount of data that we have, which should not fail unless things |
547 | | * are really bad. |
548 | | */ |
549 | 0 | flags |= JENT_FORCE_FIPS; |
550 | 0 | ec = jent_entropy_collector_alloc_internal(osr, flags); |
551 | 0 | if (!ec) { |
552 | 0 | ret = EMEM; |
553 | 0 | goto out; |
554 | 0 | } |
555 | | |
556 | 0 | if (jent_notime_settick(ec)) { |
557 | 0 | ret = EMEM; |
558 | 0 | goto out; |
559 | 0 | } |
560 | | |
561 | | /* To initialize the prior time. */ |
562 | 0 | jent_measure_jitter(ec, 0, NULL); |
563 | | |
564 | | /* We could perform statistical tests here, but the problem is |
565 | | * that we only have a few loop counts to do testing. These |
566 | | * loop counts may show some slight skew leading to false positives. |
567 | | */ |
568 | | |
569 | | /* |
570 | | * We could add a check for system capabilities such as clock_getres or |
571 | | * check for CONFIG_X86_TSC, but it does not make much sense as the |
572 | | * following sanity checks verify that we have a high-resolution |
573 | | * timer. |
574 | | */ |
575 | 0 | #define CLEARCACHE 100 |
576 | 0 | for (i = -CLEARCACHE; i < JENT_POWERUP_TESTLOOPCOUNT; i++) { |
577 | 0 | uint64_t start_time = 0, end_time = 0, delta = 0; |
578 | 0 | unsigned int stuck; |
579 | | |
580 | | /* Invoke core entropy collection logic */ |
581 | 0 | stuck = jent_measure_jitter(ec, 0, &delta); |
582 | 0 | end_time = ec->prev_time; |
583 | 0 | start_time = ec->prev_time - delta; |
584 | | |
585 | | /* test whether timer works */ |
586 | 0 | if (!start_time || !end_time) { |
587 | 0 | ret = ENOTIME; |
588 | 0 | goto out; |
589 | 0 | } |
590 | | |
591 | | /* |
592 | | * test whether timer is fine grained enough to provide |
593 | | * delta even when called shortly after each other -- this |
594 | | * implies that we also have a high resolution timer |
595 | | */ |
596 | 0 | if (!delta || (end_time == start_time)) { |
597 | 0 | ret = ECOARSETIME; |
598 | 0 | goto out; |
599 | 0 | } |
600 | | |
601 | | /* |
602 | | * up to here we did not modify any variable that will be |
603 | | * evaluated later, but we already performed some work. Thus we |
604 | | * already have had an impact on the caches, branch prediction, |
605 | | * etc. with the goal to clear it to get the worst case |
606 | | * measurements. |
607 | | */ |
608 | 0 | if (i < 0) |
609 | 0 | continue; |
610 | | |
611 | 0 | if (stuck) |
612 | 0 | count_stuck++; |
613 | | |
614 | | /* test whether we have an increasing timer */ |
615 | 0 | if (!(end_time > start_time)) |
616 | 0 | time_backwards++; |
617 | | |
618 | | /* Watch for common adjacent GCD values */ |
619 | 0 | jent_gcd_add_value(delta_history, delta, i); |
620 | 0 | } |
621 | | |
622 | | /* |
623 | | * we allow up to three times the time running backwards. |
624 | | * CLOCK_REALTIME is affected by adjtime and NTP operations. Thus, |
625 | | * if such an operation just happens to interfere with our test, it |
626 | | * should not fail. The value of 3 should cover the NTP case being |
627 | | * performed during our test run. |
628 | | */ |
629 | 0 | if (time_backwards > 3) { |
630 | 0 | ret = ENOMONOTONIC; |
631 | 0 | goto out; |
632 | 0 | } |
633 | | |
634 | | /* First, did we encounter a health test failure? */ |
635 | 0 | if ((health_test_result = jent_health_failure(ec))) { |
636 | 0 | ret = (health_test_result & JENT_RCT_FAILURE) ? ERCT : EHEALTH; |
637 | 0 | goto out; |
638 | 0 | } |
639 | | |
640 | 0 | ret = jent_gcd_analyze(delta_history, JENT_POWERUP_TESTLOOPCOUNT); |
641 | 0 | if (ret) |
642 | 0 | goto out; |
643 | | |
644 | | /* |
645 | | * If we have more than 90% stuck results, then this Jitter RNG is |
646 | | * likely to not work well. |
647 | | */ |
648 | 0 | if (JENT_STUCK_INIT_THRES(JENT_POWERUP_TESTLOOPCOUNT) < count_stuck) |
649 | 0 | ret = ESTUCK; |
650 | |
|
651 | 0 | out: |
652 | 0 | jent_gcd_fini(delta_history, JENT_POWERUP_TESTLOOPCOUNT); |
653 | |
|
654 | 0 | if ((flags & JENT_FORCE_INTERNAL_TIMER) && ec) |
655 | 0 | jent_notime_unsettick(ec); |
656 | |
|
657 | 0 | jent_entropy_collector_free(ec); |
658 | |
|
659 | 0 | return ret; |
660 | 0 | } |
661 | | |
662 | | static inline int jent_entropy_init_common_pre(void) |
663 | 0 | { |
664 | 0 | int ret; |
665 | |
|
666 | 0 | jent_notime_block_switch(); |
667 | |
|
668 | 0 | if (sha3_tester()) |
669 | 0 | return EHASH; |
670 | | |
671 | 0 | ret = jent_gcd_selftest(); |
672 | |
|
673 | 0 | jent_selftest_run = 1; |
674 | |
|
675 | 0 | return ret; |
676 | 0 | } |
677 | | |
678 | | static inline int jent_entropy_init_common_post(int ret) |
679 | 0 | { |
680 | | /* Unmark the execution of the self tests if they failed. */ |
681 | 0 | if (ret) |
682 | 0 | jent_selftest_run = 0; |
683 | |
|
684 | 0 | return ret; |
685 | 0 | } |
686 | | |
687 | | JENT_PRIVATE_STATIC |
688 | | int jent_entropy_init(void) |
689 | 0 | { |
690 | 0 | int ret = jent_entropy_init_common_pre(); |
691 | |
|
692 | 0 | if (ret) |
693 | 0 | return ret; |
694 | | |
695 | 0 | ret = jent_time_entropy_init(0, JENT_DISABLE_INTERNAL_TIMER); |
696 | |
|
697 | | #ifdef JENT_CONF_ENABLE_INTERNAL_TIMER |
698 | | if (ret) |
699 | | ret = jent_time_entropy_init(0, JENT_FORCE_INTERNAL_TIMER); |
700 | | #endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ |
701 | |
|
702 | 0 | return jent_entropy_init_common_post(ret); |
703 | 0 | } |
704 | | |
705 | | JENT_PRIVATE_STATIC |
706 | | int jent_entropy_init_ex(unsigned int osr, unsigned int flags) |
707 | 0 | { |
708 | 0 | int ret = jent_entropy_init_common_pre(); |
709 | |
|
710 | 0 | if (ret) |
711 | 0 | return ret; |
712 | | |
713 | | /* Test without internal timer unless caller does not want it */ |
714 | 0 | if (!(flags & JENT_FORCE_INTERNAL_TIMER)) |
715 | 0 | ret = jent_time_entropy_init(osr, |
716 | 0 | flags | JENT_DISABLE_INTERNAL_TIMER); |
717 | |
|
718 | | #ifdef JENT_CONF_ENABLE_INTERNAL_TIMER |
719 | | /* Test with internal timer unless caller does not want it */ |
720 | | if (ret && !(flags & JENT_DISABLE_INTERNAL_TIMER)) |
721 | | ret = jent_time_entropy_init(osr, |
722 | | flags | JENT_FORCE_INTERNAL_TIMER); |
723 | | #endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ |
724 | |
|
725 | 0 | return jent_entropy_init_common_post(ret); |
726 | 0 | } |
727 | | |
728 | | #ifdef JENT_CONF_ENABLE_INTERNAL_TIMER |
729 | | JENT_PRIVATE_STATIC |
730 | | int jent_entropy_switch_notime_impl(struct jent_notime_thread *new_thread) |
731 | | { |
732 | | return jent_notime_switch(new_thread); |
733 | | } |
734 | | #endif |