LCOV - code coverage report
Current view: top level - crypto - jitterentropy.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 77 162 47.5 %
Date: 2022-04-01 14:35:51 Functions: 4 11 36.4 %
Branches: 31 74 41.9 %

           Branch data     Line data    Source code
       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 - 2019
       6                 :            :  *
       7                 :            :  * Design
       8                 :            :  * ======
       9                 :            :  *
      10                 :            :  * See http://www.chronox.de/jent.html
      11                 :            :  *
      12                 :            :  * License
      13                 :            :  * =======
      14                 :            :  *
      15                 :            :  * Redistribution and use in source and binary forms, with or without
      16                 :            :  * modification, are permitted provided that the following conditions
      17                 :            :  * are met:
      18                 :            :  * 1. Redistributions of source code must retain the above copyright
      19                 :            :  *    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 copyright
      22                 :            :  *    notice, this list of conditions and the following disclaimer in the
      23                 :            :  *    documentation and/or other materials provided with the distribution.
      24                 :            :  * 3. The name of the author may not be used to endorse or promote
      25                 :            :  *    products derived from this software without specific prior
      26                 :            :  *    written permission.
      27                 :            :  *
      28                 :            :  * ALTERNATIVELY, this product may be distributed under the terms of
      29                 :            :  * the GNU General Public License, in which case the provisions of the GPL2 are
      30                 :            :  * required INSTEAD OF the above restrictions.  (This clause is
      31                 :            :  * necessary due to a potential bad interaction between the GPL and
      32                 :            :  * the restrictions contained in a BSD-style copyright.)
      33                 :            :  *
      34                 :            :  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
      35                 :            :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      36                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
      37                 :            :  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
      38                 :            :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      39                 :            :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
      40                 :            :  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
      41                 :            :  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
      42                 :            :  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      43                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
      44                 :            :  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
      45                 :            :  * DAMAGE.
      46                 :            :  */
      47                 :            : 
      48                 :            : /*
      49                 :            :  * This Jitterentropy RNG is based on the jitterentropy library
      50                 :            :  * version 2.1.2 provided at http://www.chronox.de/jent.html
      51                 :            :  */
      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                 :            : #endif
      56                 :            : 
      57                 :            : typedef unsigned long long      __u64;
      58                 :            : typedef long long               __s64;
      59                 :            : typedef unsigned int            __u32;
      60                 :            : #define NULL    ((void *) 0)
      61                 :            : 
      62                 :            : /* The entropy pool */
      63                 :            : struct rand_data {
      64                 :            :         /* all data values that are vital to maintain the security
      65                 :            :          * of the RNG are marked as SENSITIVE. A user must not
      66                 :            :          * access that information while the RNG executes its loops to
      67                 :            :          * calculate the next random value. */
      68                 :            :         __u64 data;             /* SENSITIVE Actual random number */
      69                 :            :         __u64 old_data;         /* SENSITIVE Previous random number */
      70                 :            :         __u64 prev_time;        /* SENSITIVE Previous time stamp */
      71                 :            : #define DATA_SIZE_BITS ((sizeof(__u64)) * 8)
      72                 :            :         __u64 last_delta;       /* SENSITIVE stuck test */
      73                 :            :         __s64 last_delta2;      /* SENSITIVE stuck test */
      74                 :            :         unsigned int osr;       /* Oversample rate */
      75                 :            : #define JENT_MEMORY_BLOCKS 64
      76                 :            : #define JENT_MEMORY_BLOCKSIZE 32
      77                 :            : #define JENT_MEMORY_ACCESSLOOPS 128
      78                 :            : #define JENT_MEMORY_SIZE (JENT_MEMORY_BLOCKS*JENT_MEMORY_BLOCKSIZE)
      79                 :            :         unsigned char *mem;     /* Memory access location with size of
      80                 :            :                                  * memblocks * memblocksize */
      81                 :            :         unsigned int memlocation; /* Pointer to byte in *mem */
      82                 :            :         unsigned int memblocks; /* Number of memory blocks in *mem */
      83                 :            :         unsigned int memblocksize; /* Size of one memory block in bytes */
      84                 :            :         unsigned int memaccessloops; /* Number of memory accesses per random
      85                 :            :                                       * bit generation */
      86                 :            : };
      87                 :            : 
      88                 :            : /* Flags that can be used to initialize the RNG */
      89                 :            : #define JENT_DISABLE_MEMORY_ACCESS (1<<2) /* Disable memory access for more
      90                 :            :                                            * entropy, saves MEMORY_SIZE RAM for
      91                 :            :                                            * entropy collector */
      92                 :            : 
      93                 :            : /* -- error codes for init function -- */
      94                 :            : #define JENT_ENOTIME            1 /* Timer service not available */
      95                 :            : #define JENT_ECOARSETIME        2 /* Timer too coarse for RNG */
      96                 :            : #define JENT_ENOMONOTONIC       3 /* Timer is not monotonic increasing */
      97                 :            : #define JENT_EVARVAR            5 /* Timer does not produce variations of
      98                 :            :                                    * variations (2nd derivation of time is
      99                 :            :                                    * zero). */
     100                 :            : #define JENT_ESTUCK             8 /* Too many stuck results during init. */
     101                 :            : 
     102                 :            : /***************************************************************************
     103                 :            :  * Helper functions
     104                 :            :  ***************************************************************************/
     105                 :            : 
     106                 :            : #include "jitterentropy.h"
     107                 :            : 
     108                 :            : /**
     109                 :            :  * Update of the loop count used for the next round of
     110                 :            :  * an entropy collection.
     111                 :            :  *
     112                 :            :  * Input:
     113                 :            :  * @ec entropy collector struct -- may be NULL
     114                 :            :  * @bits is the number of low bits of the timer to consider
     115                 :            :  * @min is the number of bits we shift the timer value to the right at
     116                 :            :  *      the end to make sure we have a guaranteed minimum value
     117                 :            :  *
     118                 :            :  * @return Newly calculated loop counter
     119                 :            :  */
     120                 :       8400 : static __u64 jent_loop_shuffle(struct rand_data *ec,
     121                 :            :                                unsigned int bits, unsigned int min)
     122                 :            : {
     123                 :       8400 :         __u64 time = 0;
     124                 :       8400 :         __u64 shuffle = 0;
     125                 :       8400 :         unsigned int i = 0;
     126                 :       8400 :         unsigned int mask = (1<<bits) - 1;
     127                 :            : 
     128                 :       8400 :         jent_get_nstime(&time);
     129                 :            :         /*
     130                 :            :          * Mix the current state of the random number into the shuffle
     131                 :            :          * calculation to balance that shuffle a bit more.
     132                 :            :          */
     133         [ +  - ]:       8400 :         if (ec)
     134                 :       8400 :                 time ^= ec->data;
     135                 :            :         /*
     136                 :            :          * We fold the time value as much as possible to ensure that as many
     137                 :            :          * bits of the time stamp are included as possible.
     138                 :            :          */
     139         [ +  + ]:     142800 :         for (i = 0; ((DATA_SIZE_BITS + bits - 1) / bits) > i; i++) {
     140                 :     134400 :                 shuffle ^= time & mask;
     141                 :     134400 :                 time = time >> bits;
     142                 :            :         }
     143                 :            : 
     144                 :            :         /*
     145                 :            :          * We add a lower boundary value to ensure we have a minimum
     146                 :            :          * RNG loop count.
     147                 :            :          */
     148                 :       8400 :         return (shuffle + (1<<min));
     149                 :            : }
     150                 :            : 
     151                 :            : /***************************************************************************
     152                 :            :  * Noise sources
     153                 :            :  ***************************************************************************/
     154                 :            : 
     155                 :            : /**
     156                 :            :  * CPU Jitter noise source -- this is the noise source based on the CPU
     157                 :            :  *                            execution time jitter
     158                 :            :  *
     159                 :            :  * This function injects the individual bits of the time value into the
     160                 :            :  * entropy pool using an LFSR.
     161                 :            :  *
     162                 :            :  * The code is deliberately inefficient with respect to the bit shifting
     163                 :            :  * and shall stay that way. This function is the root cause why the code
     164                 :            :  * shall be compiled without optimization. This function not only acts as
     165                 :            :  * folding operation, but this function's execution is used to measure
     166                 :            :  * the CPU execution time jitter. Any change to the loop in this function
     167                 :            :  * implies that careful retesting must be done.
     168                 :            :  *
     169                 :            :  * Input:
     170                 :            :  * @ec entropy collector struct
     171                 :            :  * @time time stamp to be injected
     172                 :            :  * @loop_cnt if a value not equal to 0 is set, use the given value as number of
     173                 :            :  *           loops to perform the folding
     174                 :            :  *
     175                 :            :  * Output:
     176                 :            :  * updated ec->data
     177                 :            :  *
     178                 :            :  * @return Number of loops the folding operation is performed
     179                 :            :  */
     180                 :       8400 : static __u64 jent_lfsr_time(struct rand_data *ec, __u64 time, __u64 loop_cnt)
     181                 :            : {
     182                 :            :         unsigned int i;
     183                 :       8400 :         __u64 j = 0;
     184                 :       8400 :         __u64 new = 0;
     185                 :            : #define MAX_FOLD_LOOP_BIT 4
     186                 :            : #define MIN_FOLD_LOOP_BIT 0
     187                 :            :         __u64 fold_loop_cnt =
     188                 :       8400 :                 jent_loop_shuffle(ec, MAX_FOLD_LOOP_BIT, MIN_FOLD_LOOP_BIT);
     189                 :            : 
     190                 :            :         /*
     191                 :            :          * testing purposes -- allow test app to set the counter, not
     192                 :            :          * needed during runtime
     193                 :            :          */
     194         [ -  + ]:       8400 :         if (loop_cnt)
     195                 :          0 :                 fold_loop_cnt = loop_cnt;
     196         [ +  + ]:      79882 :         for (j = 0; j < fold_loop_cnt; j++) {
     197                 :      71482 :                 new = ec->data;
     198         [ +  + ]:    4646330 :                 for (i = 1; (DATA_SIZE_BITS) >= i; i++) {
     199                 :    4574848 :                         __u64 tmp = time << (DATA_SIZE_BITS - i);
     200                 :            : 
     201                 :    4574848 :                         tmp = tmp >> (DATA_SIZE_BITS - 1);
     202                 :            : 
     203                 :            :                         /*
     204                 :            :                         * Fibonacci LSFR with polynomial of
     205                 :            :                         *  x^64 + x^61 + x^56 + x^31 + x^28 + x^23 + 1 which is
     206                 :            :                         *  primitive according to
     207                 :            :                         *   http://poincare.matf.bg.ac.rs/~ezivkovm/publications/primpol1.pdf
     208                 :            :                         * (the shift values are the polynomial values minus one
     209                 :            :                         * due to counting bits from 0 to 63). As the current
     210                 :            :                         * position is always the LSB, the polynomial only needs
     211                 :            :                         * to shift data in from the left without wrap.
     212                 :            :                         */
     213                 :    4574848 :                         tmp ^= ((new >> 63) & 1);
     214                 :    4574848 :                         tmp ^= ((new >> 60) & 1);
     215                 :    4574848 :                         tmp ^= ((new >> 55) & 1);
     216                 :    4574848 :                         tmp ^= ((new >> 30) & 1);
     217                 :    4574848 :                         tmp ^= ((new >> 27) & 1);
     218                 :    4574848 :                         tmp ^= ((new >> 22) & 1);
     219                 :    4574848 :                         new <<= 1;
     220                 :    4574848 :                         new ^= tmp;
     221                 :            :                 }
     222                 :            :         }
     223                 :       8400 :         ec->data = new;
     224                 :            : 
     225                 :       8400 :         return fold_loop_cnt;
     226                 :            : }
     227                 :            : 
     228                 :            : /**
     229                 :            :  * Memory Access noise source -- this is a noise source based on variations in
     230                 :            :  *                               memory access times
     231                 :            :  *
     232                 :            :  * This function performs memory accesses which will add to the timing
     233                 :            :  * variations due to an unknown amount of CPU wait states that need to be
     234                 :            :  * added when accessing memory. The memory size should be larger than the L1
     235                 :            :  * caches as outlined in the documentation and the associated testing.
     236                 :            :  *
     237                 :            :  * The L1 cache has a very high bandwidth, albeit its access rate is  usually
     238                 :            :  * slower than accessing CPU registers. Therefore, L1 accesses only add minimal
     239                 :            :  * variations as the CPU has hardly to wait. Starting with L2, significant
     240                 :            :  * variations are added because L2 typically does not belong to the CPU any more
     241                 :            :  * and therefore a wider range of CPU wait states is necessary for accesses.
     242                 :            :  * L3 and real memory accesses have even a wider range of wait states. However,
     243                 :            :  * to reliably access either L3 or memory, the ec->mem memory must be quite
     244                 :            :  * large which is usually not desirable.
     245                 :            :  *
     246                 :            :  * Input:
     247                 :            :  * @ec Reference to the entropy collector with the memory access data -- if
     248                 :            :  *     the reference to the memory block to be accessed is NULL, this noise
     249                 :            :  *     source is disabled
     250                 :            :  * @loop_cnt if a value not equal to 0 is set, use the given value as number of
     251                 :            :  *           loops to perform the folding
     252                 :            :  *
     253                 :            :  * @return Number of memory access operations
     254                 :            :  */
     255                 :          0 : static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt)
     256                 :            : {
     257                 :          0 :         unsigned int wrap = 0;
     258                 :          0 :         __u64 i = 0;
     259                 :            : #define MAX_ACC_LOOP_BIT 7
     260                 :            : #define MIN_ACC_LOOP_BIT 0
     261                 :            :         __u64 acc_loop_cnt =
     262                 :          0 :                 jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT);
     263                 :            : 
     264   [ #  #  #  # ]:          0 :         if (NULL == ec || NULL == ec->mem)
     265                 :          0 :                 return 0;
     266                 :          0 :         wrap = ec->memblocksize * ec->memblocks;
     267                 :            : 
     268                 :            :         /*
     269                 :            :          * testing purposes -- allow test app to set the counter, not
     270                 :            :          * needed during runtime
     271                 :            :          */
     272         [ #  # ]:          0 :         if (loop_cnt)
     273                 :          0 :                 acc_loop_cnt = loop_cnt;
     274                 :            : 
     275         [ #  # ]:          0 :         for (i = 0; i < (ec->memaccessloops + acc_loop_cnt); i++) {
     276                 :          0 :                 unsigned char *tmpval = ec->mem + ec->memlocation;
     277                 :            :                 /*
     278                 :            :                  * memory access: just add 1 to one byte,
     279                 :            :                  * wrap at 255 -- memory access implies read
     280                 :            :                  * from and write to memory location
     281                 :            :                  */
     282                 :          0 :                 *tmpval = (*tmpval + 1) & 0xff;
     283                 :            :                 /*
     284                 :            :                  * Addition of memblocksize - 1 to pointer
     285                 :            :                  * with wrap around logic to ensure that every
     286                 :            :                  * memory location is hit evenly
     287                 :            :                  */
     288                 :          0 :                 ec->memlocation = ec->memlocation + ec->memblocksize - 1;
     289                 :          0 :                 ec->memlocation = ec->memlocation % wrap;
     290                 :            :         }
     291                 :          0 :         return i;
     292                 :            : }
     293                 :            : 
     294                 :            : /***************************************************************************
     295                 :            :  * Start of entropy processing logic
     296                 :            :  ***************************************************************************/
     297                 :            : 
     298                 :            : /**
     299                 :            :  * Stuck test by checking the:
     300                 :            :  *      1st derivation of the jitter measurement (time delta)
     301                 :            :  *      2nd derivation of the jitter measurement (delta of time deltas)
     302                 :            :  *      3rd derivation of the jitter measurement (delta of delta of time deltas)
     303                 :            :  *
     304                 :            :  * All values must always be non-zero.
     305                 :            :  *
     306                 :            :  * Input:
     307                 :            :  * @ec Reference to entropy collector
     308                 :            :  * @current_delta Jitter time delta
     309                 :            :  *
     310                 :            :  * @return
     311                 :            :  *      0 jitter measurement not stuck (good bit)
     312                 :            :  *      1 jitter measurement stuck (reject bit)
     313                 :            :  */
     314                 :       8400 : static int jent_stuck(struct rand_data *ec, __u64 current_delta)
     315                 :            : {
     316                 :       8400 :         __s64 delta2 = ec->last_delta - current_delta;
     317                 :       8400 :         __s64 delta3 = delta2 - ec->last_delta2;
     318                 :            : 
     319                 :       8400 :         ec->last_delta = current_delta;
     320                 :       8400 :         ec->last_delta2 = delta2;
     321                 :            : 
     322   [ +  -  +  +  :       8400 :         if (!current_delta || !delta2 || !delta3)
                   +  + ]
     323                 :        423 :                 return 1;
     324                 :            : 
     325                 :       7977 :         return 0;
     326                 :            : }
     327                 :            : 
     328                 :            : /**
     329                 :            :  * This is the heart of the entropy generation: calculate time deltas and
     330                 :            :  * use the CPU jitter in the time deltas. The jitter is injected into the
     331                 :            :  * entropy pool.
     332                 :            :  *
     333                 :            :  * WARNING: ensure that ->prev_time is primed before using the output
     334                 :            :  *          of this function! This can be done by calling this function
     335                 :            :  *          and not using its result.
     336                 :            :  *
     337                 :            :  * Input:
     338                 :            :  * @entropy_collector Reference to entropy collector
     339                 :            :  *
     340                 :            :  * @return result of stuck test
     341                 :            :  */
     342                 :          0 : static int jent_measure_jitter(struct rand_data *ec)
     343                 :            : {
     344                 :          0 :         __u64 time = 0;
     345                 :          0 :         __u64 current_delta = 0;
     346                 :            : 
     347                 :            :         /* Invoke one noise source before time measurement to add variations */
     348                 :          0 :         jent_memaccess(ec, 0);
     349                 :            : 
     350                 :            :         /*
     351                 :            :          * Get time stamp and calculate time delta to previous
     352                 :            :          * invocation to measure the timing variations
     353                 :            :          */
     354                 :          0 :         jent_get_nstime(&time);
     355                 :          0 :         current_delta = time - ec->prev_time;
     356                 :          0 :         ec->prev_time = time;
     357                 :            : 
     358                 :            :         /* Now call the next noise sources which also injects the data */
     359                 :          0 :         jent_lfsr_time(ec, current_delta, 0);
     360                 :            : 
     361                 :            :         /* Check whether we have a stuck measurement. */
     362                 :          0 :         return jent_stuck(ec, current_delta);
     363                 :            : }
     364                 :            : 
     365                 :            : /**
     366                 :            :  * Generator of one 64 bit random number
     367                 :            :  * Function fills rand_data->data
     368                 :            :  *
     369                 :            :  * Input:
     370                 :            :  * @ec Reference to entropy collector
     371                 :            :  */
     372                 :          0 : static void jent_gen_entropy(struct rand_data *ec)
     373                 :            : {
     374                 :          0 :         unsigned int k = 0;
     375                 :            : 
     376                 :            :         /* priming of the ->prev_time value */
     377                 :          0 :         jent_measure_jitter(ec);
     378                 :            : 
     379                 :            :         while (1) {
     380                 :            :                 /* If a stuck measurement is received, repeat measurement */
     381         [ #  # ]:          0 :                 if (jent_measure_jitter(ec))
     382                 :          0 :                         continue;
     383                 :            : 
     384                 :            :                 /*
     385                 :            :                  * We multiply the loop value with ->osr to obtain the
     386                 :            :                  * oversampling rate requested by the caller
     387                 :            :                  */
     388         [ #  # ]:          0 :                 if (++k >= (DATA_SIZE_BITS * ec->osr))
     389                 :          0 :                         break;
     390                 :            :         }
     391                 :          0 : }
     392                 :            : 
     393                 :            : /**
     394                 :            :  * The continuous test required by FIPS 140-2 -- the function automatically
     395                 :            :  * primes the test if needed.
     396                 :            :  *
     397                 :            :  * Return:
     398                 :            :  * returns normally if FIPS test passed
     399                 :            :  * panics the kernel if FIPS test failed
     400                 :            :  */
     401                 :          0 : static void jent_fips_test(struct rand_data *ec)
     402                 :            : {
     403         [ #  # ]:          0 :         if (!jent_fips_enabled())
     404                 :          0 :                 return;
     405                 :            : 
     406                 :            :         /* prime the FIPS test */
     407         [ #  # ]:          0 :         if (!ec->old_data) {
     408                 :          0 :                 ec->old_data = ec->data;
     409                 :          0 :                 jent_gen_entropy(ec);
     410                 :            :         }
     411                 :            : 
     412         [ #  # ]:          0 :         if (ec->data == ec->old_data)
     413                 :          0 :                 jent_panic("jitterentropy: Duplicate output detected\n");
     414                 :            : 
     415                 :          0 :         ec->old_data = ec->data;
     416                 :            : }
     417                 :            : 
     418                 :            : /**
     419                 :            :  * Entry function: Obtain entropy for the caller.
     420                 :            :  *
     421                 :            :  * This function invokes the entropy gathering logic as often to generate
     422                 :            :  * as many bytes as requested by the caller. The entropy gathering logic
     423                 :            :  * creates 64 bit per invocation.
     424                 :            :  *
     425                 :            :  * This function truncates the last 64 bit entropy value output to the exact
     426                 :            :  * size specified by the caller.
     427                 :            :  *
     428                 :            :  * Input:
     429                 :            :  * @ec Reference to entropy collector
     430                 :            :  * @data pointer to buffer for storing random data -- buffer must already
     431                 :            :  *       exist
     432                 :            :  * @len size of the buffer, specifying also the requested number of random
     433                 :            :  *      in bytes
     434                 :            :  *
     435                 :            :  * @return 0 when request is fulfilled or an error
     436                 :            :  *
     437                 :            :  * The following error codes can occur:
     438                 :            :  *      -1      entropy_collector is NULL
     439                 :            :  */
     440                 :          0 : int jent_read_entropy(struct rand_data *ec, unsigned char *data,
     441                 :            :                       unsigned int len)
     442                 :            : {
     443                 :          0 :         unsigned char *p = data;
     444                 :            : 
     445         [ #  # ]:          0 :         if (!ec)
     446                 :          0 :                 return -1;
     447                 :            : 
     448         [ #  # ]:          0 :         while (0 < len) {
     449                 :            :                 unsigned int tocopy;
     450                 :            : 
     451                 :          0 :                 jent_gen_entropy(ec);
     452                 :          0 :                 jent_fips_test(ec);
     453         [ #  # ]:          0 :                 if ((DATA_SIZE_BITS / 8) < len)
     454                 :          0 :                         tocopy = (DATA_SIZE_BITS / 8);
     455                 :            :                 else
     456                 :          0 :                         tocopy = len;
     457                 :          0 :                 jent_memcpy(p, &ec->data, tocopy);
     458                 :            : 
     459                 :          0 :                 len -= tocopy;
     460                 :          0 :                 p += tocopy;
     461                 :            :         }
     462                 :            : 
     463                 :          0 :         return 0;
     464                 :            : }
     465                 :            : 
     466                 :            : /***************************************************************************
     467                 :            :  * Initialization logic
     468                 :            :  ***************************************************************************/
     469                 :            : 
     470                 :          0 : struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
     471                 :            :                                                unsigned int flags)
     472                 :            : {
     473                 :            :         struct rand_data *entropy_collector;
     474                 :            : 
     475                 :          0 :         entropy_collector = jent_zalloc(sizeof(struct rand_data));
     476         [ #  # ]:          0 :         if (!entropy_collector)
     477                 :          0 :                 return NULL;
     478                 :            : 
     479         [ #  # ]:          0 :         if (!(flags & JENT_DISABLE_MEMORY_ACCESS)) {
     480                 :            :                 /* Allocate memory for adding variations based on memory
     481                 :            :                  * access
     482                 :            :                  */
     483                 :          0 :                 entropy_collector->mem = jent_zalloc(JENT_MEMORY_SIZE);
     484         [ #  # ]:          0 :                 if (!entropy_collector->mem) {
     485                 :          0 :                         jent_zfree(entropy_collector);
     486                 :          0 :                         return NULL;
     487                 :            :                 }
     488                 :          0 :                 entropy_collector->memblocksize = JENT_MEMORY_BLOCKSIZE;
     489                 :          0 :                 entropy_collector->memblocks = JENT_MEMORY_BLOCKS;
     490                 :          0 :                 entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS;
     491                 :            :         }
     492                 :            : 
     493                 :            :         /* verify and set the oversampling rate */
     494         [ #  # ]:          0 :         if (0 == osr)
     495                 :          0 :                 osr = 1; /* minimum sampling rate is 1 */
     496                 :          0 :         entropy_collector->osr = osr;
     497                 :            : 
     498                 :            :         /* fill the data pad with non-zero values */
     499                 :          0 :         jent_gen_entropy(entropy_collector);
     500                 :            : 
     501                 :          0 :         return entropy_collector;
     502                 :            : }
     503                 :            : 
     504                 :          0 : void jent_entropy_collector_free(struct rand_data *entropy_collector)
     505                 :            : {
     506                 :          0 :         jent_zfree(entropy_collector->mem);
     507                 :          0 :         entropy_collector->mem = NULL;
     508                 :          0 :         jent_zfree(entropy_collector);
     509                 :          0 : }
     510                 :            : 
     511                 :         21 : int jent_entropy_init(void)
     512                 :            : {
     513                 :            :         int i;
     514                 :         21 :         __u64 delta_sum = 0;
     515                 :         21 :         __u64 old_delta = 0;
     516                 :         21 :         int time_backwards = 0;
     517                 :         21 :         int count_mod = 0;
     518                 :         21 :         int count_stuck = 0;
     519                 :         21 :         struct rand_data ec = { 0 };
     520                 :            : 
     521                 :            :         /* We could perform statistical tests here, but the problem is
     522                 :            :          * that we only have a few loop counts to do testing. These
     523                 :            :          * loop counts may show some slight skew and we produce
     524                 :            :          * false positives.
     525                 :            :          *
     526                 :            :          * Moreover, only old systems show potentially problematic
     527                 :            :          * jitter entropy that could potentially be caught here. But
     528                 :            :          * the RNG is intended for hardware that is available or widely
     529                 :            :          * used, but not old systems that are long out of favor. Thus,
     530                 :            :          * no statistical tests.
     531                 :            :          */
     532                 :            : 
     533                 :            :         /*
     534                 :            :          * We could add a check for system capabilities such as clock_getres or
     535                 :            :          * check for CONFIG_X86_TSC, but it does not make much sense as the
     536                 :            :          * following sanity checks verify that we have a high-resolution
     537                 :            :          * timer.
     538                 :            :          */
     539                 :            :         /*
     540                 :            :          * TESTLOOPCOUNT needs some loops to identify edge systems. 100 is
     541                 :            :          * definitely too little.
     542                 :            :          */
     543                 :            : #define TESTLOOPCOUNT 300
     544                 :            : #define CLEARCACHE 100
     545         [ +  + ]:       8421 :         for (i = 0; (TESTLOOPCOUNT + CLEARCACHE) > i; i++) {
     546                 :       8400 :                 __u64 time = 0;
     547                 :       8400 :                 __u64 time2 = 0;
     548                 :       8400 :                 __u64 delta = 0;
     549                 :       8400 :                 unsigned int lowdelta = 0;
     550                 :            :                 int stuck;
     551                 :            : 
     552                 :            :                 /* Invoke core entropy collection logic */
     553                 :       8400 :                 jent_get_nstime(&time);
     554                 :       8400 :                 ec.prev_time = time;
     555                 :       8400 :                 jent_lfsr_time(&ec, time, 0);
     556                 :       8400 :                 jent_get_nstime(&time2);
     557                 :            : 
     558                 :            :                 /* test whether timer works */
     559   [ +  -  -  + ]:       8400 :                 if (!time || !time2)
     560                 :          0 :                         return JENT_ENOTIME;
     561                 :       8400 :                 delta = time2 - time;
     562                 :            :                 /*
     563                 :            :                  * test whether timer is fine grained enough to provide
     564                 :            :                  * delta even when called shortly after each other -- this
     565                 :            :                  * implies that we also have a high resolution timer
     566                 :            :                  */
     567         [ -  + ]:       8400 :                 if (!delta)
     568                 :          0 :                         return JENT_ECOARSETIME;
     569                 :            : 
     570                 :       8400 :                 stuck = jent_stuck(&ec, delta);
     571                 :            : 
     572                 :            :                 /*
     573                 :            :                  * up to here we did not modify any variable that will be
     574                 :            :                  * evaluated later, but we already performed some work. Thus we
     575                 :            :                  * already have had an impact on the caches, branch prediction,
     576                 :            :                  * etc. with the goal to clear it to get the worst case
     577                 :            :                  * measurements.
     578                 :            :                  */
     579         [ +  + ]:       8400 :                 if (CLEARCACHE > i)
     580                 :       2100 :                         continue;
     581                 :            : 
     582         [ +  + ]:       6300 :                 if (stuck)
     583                 :        342 :                         count_stuck++;
     584                 :            : 
     585                 :            :                 /* test whether we have an increasing timer */
     586         [ -  + ]:       6300 :                 if (!(time2 > time))
     587                 :          0 :                         time_backwards++;
     588                 :            : 
     589                 :            :                 /* use 32 bit value to ensure compilation on 32 bit arches */
     590                 :       6300 :                 lowdelta = time2 - time;
     591         [ +  + ]:       6300 :                 if (!(lowdelta % 100))
     592                 :         71 :                         count_mod++;
     593                 :            : 
     594                 :            :                 /*
     595                 :            :                  * ensure that we have a varying delta timer which is necessary
     596                 :            :                  * for the calculation of entropy -- perform this check
     597                 :            :                  * only after the first loop is executed as we need to prime
     598                 :            :                  * the old_data value
     599                 :            :                  */
     600         [ +  + ]:       6300 :                 if (delta > old_delta)
     601                 :       3034 :                         delta_sum += (delta - old_delta);
     602                 :            :                 else
     603                 :       3266 :                         delta_sum += (old_delta - delta);
     604                 :       6300 :                 old_delta = delta;
     605                 :            :         }
     606                 :            : 
     607                 :            :         /*
     608                 :            :          * we allow up to three times the time running backwards.
     609                 :            :          * CLOCK_REALTIME is affected by adjtime and NTP operations. Thus,
     610                 :            :          * if such an operation just happens to interfere with our test, it
     611                 :            :          * should not fail. The value of 3 should cover the NTP case being
     612                 :            :          * performed during our test run.
     613                 :            :          */
     614         [ -  + ]:         21 :         if (3 < time_backwards)
     615                 :          0 :                 return JENT_ENOMONOTONIC;
     616                 :            : 
     617                 :            :         /*
     618                 :            :          * Variations of deltas of time must on average be larger
     619                 :            :          * than 1 to ensure the entropy estimation
     620                 :            :          * implied with 1 is preserved
     621                 :            :          */
     622         [ -  + ]:         21 :         if ((delta_sum) <= 1)
     623                 :          0 :                 return JENT_EVARVAR;
     624                 :            : 
     625                 :            :         /*
     626                 :            :          * Ensure that we have variations in the time stamp below 10 for at
     627                 :            :          * least 10% of all checks -- on some platforms, the counter increments
     628                 :            :          * in multiples of 100, but not always
     629                 :            :          */
     630         [ -  + ]:         21 :         if ((TESTLOOPCOUNT/10 * 9) < count_mod)
     631                 :          0 :                 return JENT_ECOARSETIME;
     632                 :            : 
     633                 :            :         /*
     634                 :            :          * If we have more than 90% stuck results, then this Jitter RNG is
     635                 :            :          * likely to not work well.
     636                 :            :          */
     637         [ -  + ]:         21 :         if ((TESTLOOPCOUNT/10 * 9) < count_stuck)
     638                 :          0 :                 return JENT_ESTUCK;
     639                 :            : 
     640                 :         21 :         return 0;
     641                 :            : }

Generated by: LCOV version 1.14