827 lines · c
1/*2 * Non-physical true random number generator based on timing jitter --3 * Jitter RNG standalone code.4 *5 * Copyright Stephan Mueller <smueller@chronox.de>, 2015 - 20236 *7 * Design8 * ======9 *10 * See https://www.chronox.de/jent.html11 *12 * License13 * =======14 *15 * Redistribution and use in source and binary forms, with or without16 * modification, are permitted provided that the following conditions17 * are met:18 * 1. Redistributions of source code must retain the above copyright19 * notice, and the entire permission notice in its entirety,20 * including the disclaimer of warranties.21 * 2. Redistributions in binary form must reproduce the above copyright22 * notice, this list of conditions and the following disclaimer in the23 * documentation and/or other materials provided with the distribution.24 * 3. The name of the author may not be used to endorse or promote25 * products derived from this software without specific prior26 * written permission.27 *28 * ALTERNATIVELY, this product may be distributed under the terms of29 * the GNU General Public License, in which case the provisions of the GPL2 are30 * required INSTEAD OF the above restrictions. (This clause is31 * necessary due to a potential bad interaction between the GPL and32 * the restrictions contained in a BSD-style copyright.)33 *34 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES36 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF37 * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE38 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT40 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF42 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE44 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH45 * DAMAGE.46 */47 48/*49 * This Jitterentropy RNG is based on the jitterentropy library50 * version 3.4.0 provided at https://www.chronox.de/jent.html51 */52 53#ifdef __OPTIMIZE__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."55#endif56 57typedef unsigned long long __u64;58typedef long long __s64;59typedef unsigned int __u32;60typedef unsigned char u8;61#define NULL ((void *) 0)62 63/* The entropy pool */64struct rand_data {65 /* SHA3-256 is used as conditioner */66#define DATA_SIZE_BITS 25667 /* all data values that are vital to maintain the security68 * of the RNG are marked as SENSITIVE. A user must not69 * access that information while the RNG executes its loops to70 * calculate the next random value. */71 void *hash_state; /* SENSITIVE hash state entropy pool */72 __u64 prev_time; /* SENSITIVE Previous time stamp */73 __u64 last_delta; /* SENSITIVE stuck test */74 __s64 last_delta2; /* SENSITIVE stuck test */75 76 unsigned int flags; /* Flags used to initialize */77 unsigned int osr; /* Oversample rate */78#define JENT_MEMORY_ACCESSLOOPS 12879#define JENT_MEMORY_SIZE \80 (CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS * \81 CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE)82 unsigned char *mem; /* Memory access location with size of83 * memblocks * memblocksize */84 unsigned int memlocation; /* Pointer to byte in *mem */85 unsigned int memblocks; /* Number of memory blocks in *mem */86 unsigned int memblocksize; /* Size of one memory block in bytes */87 unsigned int memaccessloops; /* Number of memory accesses per random88 * bit generation */89 90 /* Repetition Count Test */91 unsigned int rct_count; /* Number of stuck values */92 93 /* Adaptive Proportion Test cutoff values */94 unsigned int apt_cutoff; /* Intermittent health test failure */95 unsigned int apt_cutoff_permanent; /* Permanent health test failure */96#define JENT_APT_WINDOW_SIZE 512 /* Data window size */97 /* LSB of time stamp to process */98#define JENT_APT_LSB 1699#define JENT_APT_WORD_MASK (JENT_APT_LSB - 1)100 unsigned int apt_observations; /* Number of collected observations */101 unsigned int apt_count; /* APT counter */102 unsigned int apt_base; /* APT base reference */103 unsigned int health_failure; /* Record health failure */104 105 unsigned int apt_base_set:1; /* APT base reference set? */106};107 108/* Flags that can be used to initialize the RNG */109#define JENT_DISABLE_MEMORY_ACCESS (1<<2) /* Disable memory access for more110 * entropy, saves MEMORY_SIZE RAM for111 * entropy collector */112 113/* -- error codes for init function -- */114#define JENT_ENOTIME 1 /* Timer service not available */115#define JENT_ECOARSETIME 2 /* Timer too coarse for RNG */116#define JENT_ENOMONOTONIC 3 /* Timer is not monotonic increasing */117#define JENT_EVARVAR 5 /* Timer does not produce variations of118 * variations (2nd derivation of time is119 * zero). */120#define JENT_ESTUCK 8 /* Too many stuck results during init. */121#define JENT_EHEALTH 9 /* Health test failed during initialization */122#define JENT_ERCT 10 /* RCT failed during initialization */123#define JENT_EHASH 11 /* Hash self test failed */124#define JENT_EMEM 12 /* Can't allocate memory for initialization */125 126#define JENT_RCT_FAILURE 1 /* Failure in RCT health test. */127#define JENT_APT_FAILURE 2 /* Failure in APT health test. */128#define JENT_PERMANENT_FAILURE_SHIFT 16129#define JENT_PERMANENT_FAILURE(x) (x << JENT_PERMANENT_FAILURE_SHIFT)130#define JENT_RCT_FAILURE_PERMANENT JENT_PERMANENT_FAILURE(JENT_RCT_FAILURE)131#define JENT_APT_FAILURE_PERMANENT JENT_PERMANENT_FAILURE(JENT_APT_FAILURE)132 133/*134 * The output n bits can receive more than n bits of min entropy, of course,135 * but the fixed output of the conditioning function can only asymptotically136 * approach the output size bits of min entropy, not attain that bound. Random137 * maps will tend to have output collisions, which reduces the creditable138 * output entropy (that is what SP 800-90B Section 3.1.5.1.2 attempts to bound).139 *140 * The value "64" is justified in Appendix A.4 of the current 90C draft,141 * and aligns with NIST's in "epsilon" definition in this document, which is142 * that a string can be considered "full entropy" if you can bound the min143 * entropy in each bit of output to at least 1-epsilon, where epsilon is144 * required to be <= 2^(-32).145 */146#define JENT_ENTROPY_SAFETY_FACTOR 64147 148#include <linux/fips.h>149#include <linux/minmax.h>150#include "jitterentropy.h"151 152/***************************************************************************153 * Adaptive Proportion Test154 *155 * This test complies with SP800-90B section 4.4.2.156 ***************************************************************************/157 158/*159 * See the SP 800-90B comment #10b for the corrected cutoff for the SP 800-90B160 * APT.161 * https://www.untruth.org/~josh/sp80090b/UL%20SP800-90B-final%20comments%20v1.9%2020191212.pdf162 * In the syntax of R, this is C = 2 + qbinom(1 − 2^(−30), 511, 2^(-1/osr)).163 * (The original formula wasn't correct because the first symbol must164 * necessarily have been observed, so there is no chance of observing 0 of these165 * symbols.)166 *167 * For the alpha < 2^-53, R cannot be used as it uses a float data type without168 * arbitrary precision. A SageMath script is used to calculate those cutoff169 * values.170 *171 * For any value above 14, this yields the maximal allowable value of 512172 * (by FIPS 140-2 IG 7.19 Resolution # 16, we cannot choose a cutoff value that173 * renders the test unable to fail).174 */175static const unsigned int jent_apt_cutoff_lookup[15] = {176 325, 422, 459, 477, 488, 494, 499, 502,177 505, 507, 508, 509, 510, 511, 512 };178static const unsigned int jent_apt_cutoff_permanent_lookup[15] = {179 355, 447, 479, 494, 502, 507, 510, 512,180 512, 512, 512, 512, 512, 512, 512 };181#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))182 183static void jent_apt_init(struct rand_data *ec, unsigned int osr)184{185 /*186 * Establish the apt_cutoff based on the presumed entropy rate of187 * 1/osr.188 */189 if (osr >= ARRAY_SIZE(jent_apt_cutoff_lookup)) {190 ec->apt_cutoff = jent_apt_cutoff_lookup[191 ARRAY_SIZE(jent_apt_cutoff_lookup) - 1];192 ec->apt_cutoff_permanent = jent_apt_cutoff_permanent_lookup[193 ARRAY_SIZE(jent_apt_cutoff_permanent_lookup) - 1];194 } else {195 ec->apt_cutoff = jent_apt_cutoff_lookup[osr - 1];196 ec->apt_cutoff_permanent =197 jent_apt_cutoff_permanent_lookup[osr - 1];198 }199}200/*201 * Reset the APT counter202 *203 * @ec [in] Reference to entropy collector204 */205static void jent_apt_reset(struct rand_data *ec, unsigned int delta_masked)206{207 /* Reset APT counter */208 ec->apt_count = 0;209 ec->apt_base = delta_masked;210 ec->apt_observations = 0;211}212 213/*214 * Insert a new entropy event into APT215 *216 * @ec [in] Reference to entropy collector217 * @delta_masked [in] Masked time delta to process218 */219static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)220{221 /* Initialize the base reference */222 if (!ec->apt_base_set) {223 ec->apt_base = delta_masked;224 ec->apt_base_set = 1;225 return;226 }227 228 if (delta_masked == ec->apt_base) {229 ec->apt_count++;230 231 /* Note, ec->apt_count starts with one. */232 if (ec->apt_count >= ec->apt_cutoff_permanent)233 ec->health_failure |= JENT_APT_FAILURE_PERMANENT;234 else if (ec->apt_count >= ec->apt_cutoff)235 ec->health_failure |= JENT_APT_FAILURE;236 }237 238 ec->apt_observations++;239 240 if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)241 jent_apt_reset(ec, delta_masked);242}243 244/***************************************************************************245 * Stuck Test and its use as Repetition Count Test246 *247 * The Jitter RNG uses an enhanced version of the Repetition Count Test248 * (RCT) specified in SP800-90B section 4.4.1. Instead of counting identical249 * back-to-back values, the input to the RCT is the counting of the stuck250 * values during the generation of one Jitter RNG output block.251 *252 * The RCT is applied with an alpha of 2^{-30} compliant to FIPS 140-2 IG 9.8.253 *254 * During the counting operation, the Jitter RNG always calculates the RCT255 * cut-off value of C. If that value exceeds the allowed cut-off value,256 * the Jitter RNG output block will be calculated completely but discarded at257 * the end. The caller of the Jitter RNG is informed with an error code.258 ***************************************************************************/259 260/*261 * Repetition Count Test as defined in SP800-90B section 4.4.1262 *263 * @ec [in] Reference to entropy collector264 * @stuck [in] Indicator whether the value is stuck265 */266static void jent_rct_insert(struct rand_data *ec, int stuck)267{268 if (stuck) {269 ec->rct_count++;270 271 /*272 * The cutoff value is based on the following consideration:273 * alpha = 2^-30 or 2^-60 as recommended in SP800-90B.274 * In addition, we require an entropy value H of 1/osr as this275 * is the minimum entropy required to provide full entropy.276 * Note, we collect (DATA_SIZE_BITS + ENTROPY_SAFETY_FACTOR)*osr277 * deltas for inserting them into the entropy pool which should278 * then have (close to) DATA_SIZE_BITS bits of entropy in the279 * conditioned output.280 *281 * Note, ec->rct_count (which equals to value B in the pseudo282 * code of SP800-90B section 4.4.1) starts with zero. Hence283 * we need to subtract one from the cutoff value as calculated284 * following SP800-90B. Thus C = ceil(-log_2(alpha)/H) = 30*osr285 * or 60*osr.286 */287 if ((unsigned int)ec->rct_count >= (60 * ec->osr)) {288 ec->rct_count = -1;289 ec->health_failure |= JENT_RCT_FAILURE_PERMANENT;290 } else if ((unsigned int)ec->rct_count >= (30 * ec->osr)) {291 ec->rct_count = -1;292 ec->health_failure |= JENT_RCT_FAILURE;293 }294 } else {295 /* Reset RCT */296 ec->rct_count = 0;297 }298}299 300static inline __u64 jent_delta(__u64 prev, __u64 next)301{302#define JENT_UINT64_MAX (__u64)(~((__u64) 0))303 return (prev < next) ? (next - prev) :304 (JENT_UINT64_MAX - prev + 1 + next);305}306 307/*308 * Stuck test by checking the:309 * 1st derivative of the jitter measurement (time delta)310 * 2nd derivative of the jitter measurement (delta of time deltas)311 * 3rd derivative of the jitter measurement (delta of delta of time deltas)312 *313 * All values must always be non-zero.314 *315 * @ec [in] Reference to entropy collector316 * @current_delta [in] Jitter time delta317 *318 * @return319 * 0 jitter measurement not stuck (good bit)320 * 1 jitter measurement stuck (reject bit)321 */322static int jent_stuck(struct rand_data *ec, __u64 current_delta)323{324 __u64 delta2 = jent_delta(ec->last_delta, current_delta);325 __u64 delta3 = jent_delta(ec->last_delta2, delta2);326 327 ec->last_delta = current_delta;328 ec->last_delta2 = delta2;329 330 /*331 * Insert the result of the comparison of two back-to-back time332 * deltas.333 */334 jent_apt_insert(ec, current_delta);335 336 if (!current_delta || !delta2 || !delta3) {337 /* RCT with a stuck bit */338 jent_rct_insert(ec, 1);339 return 1;340 }341 342 /* RCT with a non-stuck bit */343 jent_rct_insert(ec, 0);344 345 return 0;346}347 348/*349 * Report any health test failures350 *351 * @ec [in] Reference to entropy collector352 *353 * @return a bitmask indicating which tests failed354 * 0 No health test failure355 * 1 RCT failure356 * 2 APT failure357 * 1<<JENT_PERMANENT_FAILURE_SHIFT RCT permanent failure358 * 2<<JENT_PERMANENT_FAILURE_SHIFT APT permanent failure359 */360static unsigned int jent_health_failure(struct rand_data *ec)361{362 /* Test is only enabled in FIPS mode */363 if (!fips_enabled)364 return 0;365 366 return ec->health_failure;367}368 369/***************************************************************************370 * Noise sources371 ***************************************************************************/372 373/*374 * Update of the loop count used for the next round of375 * an entropy collection.376 *377 * Input:378 * @bits is the number of low bits of the timer to consider379 * @min is the number of bits we shift the timer value to the right at380 * the end to make sure we have a guaranteed minimum value381 *382 * @return Newly calculated loop counter383 */384static __u64 jent_loop_shuffle(unsigned int bits, unsigned int min)385{386 __u64 time = 0;387 __u64 shuffle = 0;388 unsigned int i = 0;389 unsigned int mask = (1<<bits) - 1;390 391 jent_get_nstime(&time);392 393 /*394 * We fold the time value as much as possible to ensure that as many395 * bits of the time stamp are included as possible.396 */397 for (i = 0; ((DATA_SIZE_BITS + bits - 1) / bits) > i; i++) {398 shuffle ^= time & mask;399 time = time >> bits;400 }401 402 /*403 * We add a lower boundary value to ensure we have a minimum404 * RNG loop count.405 */406 return (shuffle + (1<<min));407}408 409/*410 * CPU Jitter noise source -- this is the noise source based on the CPU411 * execution time jitter412 *413 * This function injects the individual bits of the time value into the414 * entropy pool using a hash.415 *416 * ec [in] entropy collector417 * time [in] time stamp to be injected418 * stuck [in] Is the time stamp identified as stuck?419 *420 * Output:421 * updated hash context in the entropy collector or error code422 */423static int jent_condition_data(struct rand_data *ec, __u64 time, int stuck)424{425#define SHA3_HASH_LOOP (1<<3)426 struct {427 int rct_count;428 unsigned int apt_observations;429 unsigned int apt_count;430 unsigned int apt_base;431 } addtl = {432 ec->rct_count,433 ec->apt_observations,434 ec->apt_count,435 ec->apt_base436 };437 438 return jent_hash_time(ec->hash_state, time, (u8 *)&addtl, sizeof(addtl),439 SHA3_HASH_LOOP, stuck);440}441 442/*443 * Memory Access noise source -- this is a noise source based on variations in444 * memory access times445 *446 * This function performs memory accesses which will add to the timing447 * variations due to an unknown amount of CPU wait states that need to be448 * added when accessing memory. The memory size should be larger than the L1449 * caches as outlined in the documentation and the associated testing.450 *451 * The L1 cache has a very high bandwidth, albeit its access rate is usually452 * slower than accessing CPU registers. Therefore, L1 accesses only add minimal453 * variations as the CPU has hardly to wait. Starting with L2, significant454 * variations are added because L2 typically does not belong to the CPU any more455 * and therefore a wider range of CPU wait states is necessary for accesses.456 * L3 and real memory accesses have even a wider range of wait states. However,457 * to reliably access either L3 or memory, the ec->mem memory must be quite458 * large which is usually not desirable.459 *460 * @ec [in] Reference to the entropy collector with the memory access data -- if461 * the reference to the memory block to be accessed is NULL, this noise462 * source is disabled463 * @loop_cnt [in] if a value not equal to 0 is set, use the given value464 * number of loops to perform the LFSR465 */466static void jent_memaccess(struct rand_data *ec, __u64 loop_cnt)467{468 unsigned int wrap = 0;469 __u64 i = 0;470#define MAX_ACC_LOOP_BIT 7471#define MIN_ACC_LOOP_BIT 0472 __u64 acc_loop_cnt =473 jent_loop_shuffle(MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT);474 475 if (NULL == ec || NULL == ec->mem)476 return;477 wrap = ec->memblocksize * ec->memblocks;478 479 /*480 * testing purposes -- allow test app to set the counter, not481 * needed during runtime482 */483 if (loop_cnt)484 acc_loop_cnt = loop_cnt;485 486 for (i = 0; i < (ec->memaccessloops + acc_loop_cnt); i++) {487 unsigned char *tmpval = ec->mem + ec->memlocation;488 /*489 * memory access: just add 1 to one byte,490 * wrap at 255 -- memory access implies read491 * from and write to memory location492 */493 *tmpval = (*tmpval + 1) & 0xff;494 /*495 * Addition of memblocksize - 1 to pointer496 * with wrap around logic to ensure that every497 * memory location is hit evenly498 */499 ec->memlocation = ec->memlocation + ec->memblocksize - 1;500 ec->memlocation = ec->memlocation % wrap;501 }502}503 504/***************************************************************************505 * Start of entropy processing logic506 ***************************************************************************/507/*508 * This is the heart of the entropy generation: calculate time deltas and509 * use the CPU jitter in the time deltas. The jitter is injected into the510 * entropy pool.511 *512 * WARNING: ensure that ->prev_time is primed before using the output513 * of this function! This can be done by calling this function514 * and not using its result.515 *516 * @ec [in] Reference to entropy collector517 *518 * @return result of stuck test519 */520static int jent_measure_jitter(struct rand_data *ec, __u64 *ret_current_delta)521{522 __u64 time = 0;523 __u64 current_delta = 0;524 int stuck;525 526 /* Invoke one noise source before time measurement to add variations */527 jent_memaccess(ec, 0);528 529 /*530 * Get time stamp and calculate time delta to previous531 * invocation to measure the timing variations532 */533 jent_get_nstime(&time);534 current_delta = jent_delta(ec->prev_time, time);535 ec->prev_time = time;536 537 /* Check whether we have a stuck measurement. */538 stuck = jent_stuck(ec, current_delta);539 540 /* Now call the next noise sources which also injects the data */541 if (jent_condition_data(ec, current_delta, stuck))542 stuck = 1;543 544 /* return the raw entropy value */545 if (ret_current_delta)546 *ret_current_delta = current_delta;547 548 return stuck;549}550 551/*552 * Generator of one 64 bit random number553 * Function fills rand_data->hash_state554 *555 * @ec [in] Reference to entropy collector556 */557static void jent_gen_entropy(struct rand_data *ec)558{559 unsigned int k = 0, safety_factor = 0;560 561 if (fips_enabled)562 safety_factor = JENT_ENTROPY_SAFETY_FACTOR;563 564 /* priming of the ->prev_time value */565 jent_measure_jitter(ec, NULL);566 567 while (!jent_health_failure(ec)) {568 /* If a stuck measurement is received, repeat measurement */569 if (jent_measure_jitter(ec, NULL))570 continue;571 572 /*573 * We multiply the loop value with ->osr to obtain the574 * oversampling rate requested by the caller575 */576 if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr))577 break;578 }579}580 581/*582 * Entry function: Obtain entropy for the caller.583 *584 * This function invokes the entropy gathering logic as often to generate585 * as many bytes as requested by the caller. The entropy gathering logic586 * creates 64 bit per invocation.587 *588 * This function truncates the last 64 bit entropy value output to the exact589 * size specified by the caller.590 *591 * @ec [in] Reference to entropy collector592 * @data [in] pointer to buffer for storing random data -- buffer must already593 * exist594 * @len [in] size of the buffer, specifying also the requested number of random595 * in bytes596 *597 * @return 0 when request is fulfilled or an error598 *599 * The following error codes can occur:600 * -1 entropy_collector is NULL or the generation failed601 * -2 Intermittent health failure602 * -3 Permanent health failure603 */604int jent_read_entropy(struct rand_data *ec, unsigned char *data,605 unsigned int len)606{607 unsigned char *p = data;608 609 if (!ec)610 return -1;611 612 while (len > 0) {613 unsigned int tocopy, health_test_result;614 615 jent_gen_entropy(ec);616 617 health_test_result = jent_health_failure(ec);618 if (health_test_result > JENT_PERMANENT_FAILURE_SHIFT) {619 /*620 * At this point, the Jitter RNG instance is considered621 * as a failed instance. There is no rerun of the622 * startup test any more, because the caller623 * is assumed to not further use this instance.624 */625 return -3;626 } else if (health_test_result) {627 /*628 * Perform startup health tests and return permanent629 * error if it fails.630 */631 if (jent_entropy_init(0, 0, NULL, ec)) {632 /* Mark the permanent error */633 ec->health_failure &=634 JENT_RCT_FAILURE_PERMANENT |635 JENT_APT_FAILURE_PERMANENT;636 return -3;637 }638 639 return -2;640 }641 642 tocopy = min(DATA_SIZE_BITS / 8, len);643 if (jent_read_random_block(ec->hash_state, p, tocopy))644 return -1;645 646 len -= tocopy;647 p += tocopy;648 }649 650 return 0;651}652 653/***************************************************************************654 * Initialization logic655 ***************************************************************************/656 657struct rand_data *jent_entropy_collector_alloc(unsigned int osr,658 unsigned int flags,659 void *hash_state)660{661 struct rand_data *entropy_collector;662 663 entropy_collector = jent_zalloc(sizeof(struct rand_data));664 if (!entropy_collector)665 return NULL;666 667 if (!(flags & JENT_DISABLE_MEMORY_ACCESS)) {668 /* Allocate memory for adding variations based on memory669 * access670 */671 entropy_collector->mem = jent_kvzalloc(JENT_MEMORY_SIZE);672 if (!entropy_collector->mem) {673 jent_zfree(entropy_collector);674 return NULL;675 }676 entropy_collector->memblocksize =677 CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE;678 entropy_collector->memblocks =679 CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS;680 entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS;681 }682 683 /* verify and set the oversampling rate */684 if (osr == 0)685 osr = 1; /* H_submitter = 1 / osr */686 entropy_collector->osr = osr;687 entropy_collector->flags = flags;688 689 entropy_collector->hash_state = hash_state;690 691 /* Initialize the APT */692 jent_apt_init(entropy_collector, osr);693 694 /* fill the data pad with non-zero values */695 jent_gen_entropy(entropy_collector);696 697 return entropy_collector;698}699 700void jent_entropy_collector_free(struct rand_data *entropy_collector)701{702 jent_kvzfree(entropy_collector->mem, JENT_MEMORY_SIZE);703 entropy_collector->mem = NULL;704 jent_zfree(entropy_collector);705}706 707int jent_entropy_init(unsigned int osr, unsigned int flags, void *hash_state,708 struct rand_data *p_ec)709{710 /*711 * If caller provides an allocated ec, reuse it which implies that the712 * health test entropy data is used to further still the available713 * entropy pool.714 */715 struct rand_data *ec = p_ec;716 int i, time_backwards = 0, ret = 0, ec_free = 0;717 unsigned int health_test_result;718 719 if (!ec) {720 ec = jent_entropy_collector_alloc(osr, flags, hash_state);721 if (!ec)722 return JENT_EMEM;723 ec_free = 1;724 } else {725 /* Reset the APT */726 jent_apt_reset(ec, 0);727 /* Ensure that a new APT base is obtained */728 ec->apt_base_set = 0;729 /* Reset the RCT */730 ec->rct_count = 0;731 /* Reset intermittent, leave permanent health test result */732 ec->health_failure &= (~JENT_RCT_FAILURE);733 ec->health_failure &= (~JENT_APT_FAILURE);734 }735 736 /* We could perform statistical tests here, but the problem is737 * that we only have a few loop counts to do testing. These738 * loop counts may show some slight skew and we produce739 * false positives.740 *741 * Moreover, only old systems show potentially problematic742 * jitter entropy that could potentially be caught here. But743 * the RNG is intended for hardware that is available or widely744 * used, but not old systems that are long out of favor. Thus,745 * no statistical tests.746 */747 748 /*749 * We could add a check for system capabilities such as clock_getres or750 * check for CONFIG_X86_TSC, but it does not make much sense as the751 * following sanity checks verify that we have a high-resolution752 * timer.753 */754 /*755 * TESTLOOPCOUNT needs some loops to identify edge systems. 100 is756 * definitely too little.757 *758 * SP800-90B requires at least 1024 initial test cycles.759 */760#define TESTLOOPCOUNT 1024761#define CLEARCACHE 100762 for (i = 0; (TESTLOOPCOUNT + CLEARCACHE) > i; i++) {763 __u64 start_time = 0, end_time = 0, delta = 0;764 765 /* Invoke core entropy collection logic */766 jent_measure_jitter(ec, &delta);767 end_time = ec->prev_time;768 start_time = ec->prev_time - delta;769 770 /* test whether timer works */771 if (!start_time || !end_time) {772 ret = JENT_ENOTIME;773 goto out;774 }775 776 /*777 * test whether timer is fine grained enough to provide778 * delta even when called shortly after each other -- this779 * implies that we also have a high resolution timer780 */781 if (!delta || (end_time == start_time)) {782 ret = JENT_ECOARSETIME;783 goto out;784 }785 786 /*787 * up to here we did not modify any variable that will be788 * evaluated later, but we already performed some work. Thus we789 * already have had an impact on the caches, branch prediction,790 * etc. with the goal to clear it to get the worst case791 * measurements.792 */793 if (i < CLEARCACHE)794 continue;795 796 /* test whether we have an increasing timer */797 if (!(end_time > start_time))798 time_backwards++;799 }800 801 /*802 * we allow up to three times the time running backwards.803 * CLOCK_REALTIME is affected by adjtime and NTP operations. Thus,804 * if such an operation just happens to interfere with our test, it805 * should not fail. The value of 3 should cover the NTP case being806 * performed during our test run.807 */808 if (time_backwards > 3) {809 ret = JENT_ENOMONOTONIC;810 goto out;811 }812 813 /* Did we encounter a health test failure? */814 health_test_result = jent_health_failure(ec);815 if (health_test_result) {816 ret = (health_test_result & JENT_RCT_FAILURE) ? JENT_ERCT :817 JENT_EHEALTH;818 goto out;819 }820 821out:822 if (ec_free)823 jent_entropy_collector_free(ec);824 825 return ret;826}827