LCOV - code coverage report
Current view: top level - random - random-fips.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 190 353 53.8 %
Date: 2015-11-05 17:08:00 Functions: 18 28 64.3 %

          Line data    Source code
       1             : /* random-fips.c - FIPS style random number generator
       2             :  * Copyright (C) 2008  Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser General Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /*
      21             :    The core of this deterministic random number generator is
      22             :    implemented according to the document "NIST-Recommended Random
      23             :    Number Generator Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key
      24             :    Triple DES and AES Algorithms" (2005-01-31).  This implementation
      25             :    uses the AES variant.
      26             : 
      27             :    There are 3 random context which map to the different levels of
      28             :    random quality:
      29             : 
      30             :    Generator                Seed and Key        Kernel entropy (init/reseed)
      31             :    ------------------------------------------------------------
      32             :    GCRY_VERY_STRONG_RANDOM  /dev/random         256/128 bits
      33             :    GCRY_STRONG_RANDOM       /dev/random         256/128 bits
      34             :    gcry_create_nonce        GCRY_STRONG_RANDOM  n/a
      35             : 
      36             :    All random generators return their data in 128 bit blocks.  If the
      37             :    caller requested less bits, the extra bits are not used.  The key
      38             :    for each generator is only set once at the first time a generator
      39             :    is used.  The seed value is set with the key and again after 1000
      40             :    (SEED_TTL) output blocks; the re-seeding is disabled in test mode.
      41             : 
      42             :    The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are
      43             :    keyed and seeded from the /dev/random device.  Thus these
      44             :    generators may block until the kernel has collected enough entropy.
      45             : 
      46             :    The gcry_create_nonce generator is keyed and seeded from the
      47             :    GCRY_STRONG_RANDOM generator.  It may also block if the
      48             :    GCRY_STRONG_RANDOM generator has not yet been used before and thus
      49             :    gets initialized on the first use by gcry_create_nonce.  This
      50             :    special treatment is justified by the weaker requirements for a
      51             :    nonce generator and to save precious kernel entropy for use by the
      52             :    real random generators.
      53             : 
      54             :  */
      55             : 
      56             : #include <config.h>
      57             : #include <stdio.h>
      58             : #include <stdlib.h>
      59             : #include <errno.h>
      60             : #include <sys/types.h>
      61             : #include <unistd.h>
      62             : #ifdef HAVE_GETTIMEOFDAY
      63             : #include <sys/time.h>
      64             : #endif
      65             : 
      66             : #include "g10lib.h"
      67             : #include "random.h"
      68             : #include "rand-internal.h"
      69             : 
      70             : /* This is the lock we use to serialize access to this RNG.  The extra
      71             :    integer variable is only used to check the locking state; that is,
      72             :    it is not meant to be thread-safe but merely as a failsafe feature
      73             :    to assert proper locking.  */
      74             : GPGRT_LOCK_DEFINE (fips_rng_lock);
      75             : static int fips_rng_is_locked;
      76             : 
      77             : 
      78             : /* The required size for the temporary buffer of the x931_aes_driver
      79             :    function and the buffer itself which will be allocated in secure
      80             :    memory.  This needs to be global variable for proper initialization
      81             :    and to allow shutting down the RNG without leaking memory.  May
      82             :    only be used while holding the FIPS_RNG_LOCK.
      83             : 
      84             :    This variable is also used to avoid duplicate initialization.  */
      85             : #define TEMPVALUE_FOR_X931_AES_DRIVER_SIZE 48
      86             : static unsigned char *tempvalue_for_x931_aes_driver;
      87             : 
      88             : 
      89             : /* After having retrieved this number of blocks from the RNG, we want
      90             :    to do a reseeding.  */
      91             : #define SEED_TTL 1000
      92             : 
      93             : 
      94             : /* The length of the key we use:  16 bytes (128 bit) for AES128.  */
      95             : #define X931_AES_KEYLEN  16
      96             : /* A global buffer used to communicate between the x931_generate_key
      97             :    and x931_generate_seed functions and the entropy_collect_cb
      98             :    function.  It may only be used by these functions. */
      99             : static unsigned char *entropy_collect_buffer;  /* Buffer.  */
     100             : static size_t entropy_collect_buffer_len;      /* Used length.  */
     101             : static size_t entropy_collect_buffer_size;     /* Allocated length.  */
     102             : 
     103             : 
     104             : /* This random context type is used to track properties of one random
     105             :    generator. Thee context are usually allocated in secure memory so
     106             :    that the seed value is well protected.  There are a couble of guard
     107             :    fields to help detecting applications accidently overwriting parts
     108             :    of the memory. */
     109             : struct rng_context
     110             : {
     111             :   unsigned char guard_0[1];
     112             : 
     113             :   /* The handle of the cipher used by the RNG.  If this one is not
     114             :      NULL a cipher handle along with a random key has been
     115             :      established.  */
     116             :   gcry_cipher_hd_t cipher_hd;
     117             : 
     118             :   /* If this flag is true, the SEED_V buffer below carries a valid
     119             :      seed.  */
     120             :   int is_seeded:1;
     121             : 
     122             :   /* The very first block generated is used to compare the result
     123             :      against the last result.  This flag indicates that such a block
     124             :      is available.  */
     125             :   int compare_value_valid:1;
     126             : 
     127             :   /* A counter used to trigger re-seeding.  */
     128             :   unsigned int use_counter;
     129             : 
     130             :   unsigned char guard_1[1];
     131             : 
     132             :   /* The buffer containing the seed value V.  */
     133             :   unsigned char seed_V[16];
     134             : 
     135             :   unsigned char guard_2[1];
     136             : 
     137             :   /* The last result from the x931_aes function.  Only valid if
     138             :      compare_value_valid is set.  */
     139             :   unsigned char compare_value[16];
     140             : 
     141             :   unsigned char guard_3[1];
     142             : 
     143             :   /* The external test may want to suppress the duplicate bock check.
     144             :      This is done if the this flag is set.  */
     145             :   unsigned char test_no_dup_check;
     146             :   /* To implement a KAT we need to provide a know DT value.  To
     147             :      accomplish this the x931_get_dt function checks whether this
     148             :      field is not NULL and then uses the 16 bytes at this address for
     149             :      the DT value.  However the last 4 bytes are replaced by the
     150             :      value of field TEST_DT_COUNTER which will be incremented after
     151             :      each invocation of x931_get_dt. We use a pointer and not a buffer
     152             :      because there is no need to put this value into secure memory.  */
     153             :   const unsigned char *test_dt_ptr;
     154             :   u32 test_dt_counter;
     155             : 
     156             :   /* We need to keep track of the process which did the initialization
     157             :      so that we can detect a fork.  The volatile modifier is required
     158             :      so that the compiler does not optimize it away in case the getpid
     159             :      function is badly attributed.  */
     160             :   pid_t key_init_pid;
     161             :   pid_t seed_init_pid;
     162             : };
     163             : typedef struct rng_context *rng_context_t;
     164             : 
     165             : 
     166             : /* The random context used for the nonce generator.  May only be used
     167             :    while holding the FIPS_RNG_LOCK.  */
     168             : static rng_context_t nonce_context;
     169             : /* The random context used for the standard random generator.  May
     170             :    only be used while holding the FIPS_RNG_LOCK.  */
     171             : static rng_context_t std_rng_context;
     172             : /* The random context used for the very strong random generator.  May
     173             :    only be used while holding the FIPS_RNG_LOCK.  */
     174             : static rng_context_t strong_rng_context;
     175             : 
     176             : 
     177             : /* --- Local prototypes ---  */
     178             : static void x931_reseed (rng_context_t rng_ctx);
     179             : static void get_random (void *buffer, size_t length, rng_context_t rng_ctx);
     180             : 
     181             : 
     182             : 
     183             : 
     184             : /* --- Functions  --- */
     185             : 
     186             : /* Basic initialization is required to initialize mutexes and
     187             :    do a few checks on the implementation.  */
     188             : static void
     189           4 : basic_initialization (void)
     190             : {
     191             :   static int initialized;
     192             : 
     193           4 :   if (initialized)
     194           7 :     return;
     195           1 :   initialized = 1;
     196             : 
     197           1 :   fips_rng_is_locked = 0;
     198             : 
     199             :   /* Make sure that we are still using the values we have
     200             :      traditionally used for the random levels.  */
     201             :   gcry_assert (GCRY_WEAK_RANDOM == 0
     202             :                && GCRY_STRONG_RANDOM == 1
     203             :                && GCRY_VERY_STRONG_RANDOM == 2);
     204             : 
     205             : }
     206             : 
     207             : 
     208             : /* Acquire the fips_rng_lock.  */
     209             : static void
     210           6 : lock_rng (void)
     211             : {
     212             :   gpg_err_code_t rc;
     213             : 
     214           6 :   rc = gpgrt_lock_lock (&fips_rng_lock);
     215           6 :   if (rc)
     216           0 :     log_fatal ("failed to acquire the RNG lock: %s\n", gpg_strerror (rc));
     217           6 :   fips_rng_is_locked = 1;
     218           6 : }
     219             : 
     220             : 
     221             : /* Release the fips_rng_lock.  */
     222             : static void
     223           6 : unlock_rng (void)
     224             : {
     225             :   gpg_err_code_t rc;
     226             : 
     227           6 :   fips_rng_is_locked = 0;
     228           6 :   rc = gpgrt_lock_unlock (&fips_rng_lock);
     229           6 :   if (rc)
     230           0 :     log_fatal ("failed to release the RNG lock: %s\n", gpg_strerror (rc));
     231           6 : }
     232             : 
     233             : static void
     234           3 : setup_guards (rng_context_t rng_ctx)
     235             : {
     236             :   /* Set the guards to some arbitrary values.  */
     237           3 :   rng_ctx->guard_0[0] = 17;
     238           3 :   rng_ctx->guard_1[0] = 42;
     239           3 :   rng_ctx->guard_2[0] = 137;
     240           3 :   rng_ctx->guard_3[0] = 252;
     241           3 : }
     242             : 
     243             : static void
     244          12 : check_guards (rng_context_t rng_ctx)
     245             : {
     246          12 :   if ( rng_ctx->guard_0[0] != 17
     247          12 :        || rng_ctx->guard_1[0] != 42
     248          12 :        || rng_ctx->guard_2[0] != 137
     249          12 :        || rng_ctx->guard_3[0] != 252 )
     250           0 :     log_fatal ("memory corruption detected in RNG context %p\n", rng_ctx);
     251          12 : }
     252             : 
     253             : 
     254             : /* Get the DT vector for use with the core PRNG function.  Buffer
     255             :    needs to be provided by the caller with a size of at least LENGTH
     256             :    bytes. RNG_CTX needs to be passed to allow for a KAT.  The 16 byte
     257             :    timestamp we construct is made up the real time and three counters:
     258             : 
     259             :    Buffer:       00112233445566778899AABBCCDDEEFF
     260             :                  !--+---!!-+-!!+!!--+---!!--+---!
     261             :    seconds ---------/      |   |    |       |
     262             :    microseconds -----------/   |    |       |
     263             :    counter2 -------------------/    |       |
     264             :    counter1 ------------------------/       |
     265             :    counter0 --------------------------------/
     266             : 
     267             :    Counter 2 is just 12 bits wide and used to track fractions of
     268             :    milliseconds whereas counters 1 and 0 are combined to a free
     269             :    running 64 bit counter.  */
     270             : static void
     271           4 : x931_get_dt (unsigned char *buffer, size_t length, rng_context_t rng_ctx)
     272             : {
     273           4 :   gcry_assert (length == 16); /* This length is required for use with AES.  */
     274           4 :   gcry_assert (fips_rng_is_locked);
     275             : 
     276             :   /* If the random context indicates that a test DT should be used,
     277             :      take the DT value from the context.  For safety reasons we do
     278             :      this only if the context is not one of the regular contexts.  */
     279           4 :   if (rng_ctx->test_dt_ptr
     280           0 :       && rng_ctx != nonce_context
     281           0 :       && rng_ctx != std_rng_context
     282           0 :       && rng_ctx != strong_rng_context)
     283             :     {
     284           0 :       memcpy (buffer, rng_ctx->test_dt_ptr, 16);
     285           0 :       buffer[12] = (rng_ctx->test_dt_counter >> 24);
     286           0 :       buffer[13] = (rng_ctx->test_dt_counter >> 16);
     287           0 :       buffer[14] = (rng_ctx->test_dt_counter >> 8);
     288           0 :       buffer[15] = rng_ctx->test_dt_counter;
     289           0 :       rng_ctx->test_dt_counter++;
     290           4 :       return;
     291             :     }
     292             : 
     293             : 
     294             : #if HAVE_GETTIMEOFDAY
     295             :   {
     296             :     static u32 last_sec, last_usec;
     297             :     static u32 counter1, counter0;
     298             :     static u16 counter2;
     299             : 
     300             :     unsigned int usec;
     301             :     struct timeval tv;
     302             : 
     303           4 :     if (!last_sec)
     304             :       {
     305             :         /* This is the very first time we are called: Set the counters
     306             :            to an not so easy predictable value to avoid always
     307             :            starting at 0.  Not really needed but it doesn't harm.  */
     308           1 :         counter1 = (u32)getpid ();
     309             : #ifndef HAVE_W32_SYSTEM
     310           1 :         counter0 = (u32)getppid ();
     311             : #endif
     312             :       }
     313             : 
     314             : 
     315           4 :     if (gettimeofday (&tv, NULL))
     316           0 :       log_fatal ("gettimeofday() failed: %s\n", strerror (errno));
     317             : 
     318             :     /* The microseconds part is always less than 1 millon (0x0f4240).
     319             :        Thus we don't care about the MSB and in addition shift it to
     320             :        the left by 4 bits.  */
     321           4 :     usec = tv.tv_usec;
     322           4 :     usec <<= 4;
     323             :     /* If we got the same time as by the last invocation, bump up
     324             :        counter2 and save the time for the next invocation.  */
     325           4 :     if (tv.tv_sec == last_sec && usec == last_usec)
     326             :       {
     327           0 :         counter2++;
     328           0 :         counter2 &= 0x0fff;
     329             :       }
     330             :     else
     331             :       {
     332           4 :         counter2 = 0;
     333           4 :         last_sec = tv.tv_sec;
     334           4 :         last_usec = usec;
     335             :       }
     336             :     /* Fill the buffer with the timestamp.  */
     337           4 :     buffer[0] = ((tv.tv_sec >> 24) & 0xff);
     338           4 :     buffer[1] = ((tv.tv_sec >> 16) & 0xff);
     339           4 :     buffer[2] = ((tv.tv_sec >> 8) & 0xff);
     340           4 :     buffer[3] = (tv.tv_sec & 0xff);
     341           4 :     buffer[4] = ((usec >> 16) & 0xff);
     342           4 :     buffer[5] = ((usec >> 8) & 0xff);
     343           4 :     buffer[6] = ((usec & 0xf0) | ((counter2 >> 8) & 0x0f));
     344           4 :     buffer[7] = (counter2 & 0xff);
     345             :     /* Add the free running counter.  */
     346           4 :     buffer[8]  = ((counter1 >> 24) & 0xff);
     347           4 :     buffer[9]  = ((counter1 >> 16) & 0xff);
     348           4 :     buffer[10] = ((counter1 >> 8) & 0xff);
     349           4 :     buffer[11] = ((counter1) & 0xff);
     350           4 :     buffer[12] = ((counter0 >> 24) & 0xff);
     351           4 :     buffer[13] = ((counter0 >> 16) & 0xff);
     352           4 :     buffer[14] = ((counter0 >> 8) & 0xff);
     353           4 :     buffer[15] = ((counter0) & 0xff);
     354             :     /* Bump up that counter.  */
     355           4 :     if (!++counter0)
     356           0 :       ++counter1;
     357             :   }
     358             : #else
     359             :   log_fatal ("gettimeofday() not available on this system\n");
     360             : #endif
     361             : 
     362             :   /* log_printhex ("x931_get_dt: ", buffer, 16); */
     363             : }
     364             : 
     365             : 
     366             : /* XOR the buffers A and B which are each of LENGTH bytes and store
     367             :    the result at R.  R needs to be provided by the caller with a size
     368             :    of at least LENGTH bytes.  */
     369             : static void
     370           8 : xor_buffer (unsigned char *r,
     371             :             const unsigned char *a, const unsigned char *b, size_t length)
     372             : {
     373         136 :   for ( ; length; length--, a++, b++, r++)
     374         128 :     *r = (*a ^ *b);
     375           8 : }
     376             : 
     377             : 
     378             : /* Encrypt LENGTH bytes of INPUT to OUTPUT using KEY.  LENGTH
     379             :    needs to be 16. */
     380             : static void
     381          12 : encrypt_aes (gcry_cipher_hd_t key,
     382             :              unsigned char *output, const unsigned char *input, size_t length)
     383             : {
     384             :   gpg_error_t err;
     385             : 
     386          12 :   gcry_assert (length == 16);
     387             : 
     388          12 :   err = _gcry_cipher_encrypt (key, output, length, input, length);
     389          12 :   if (err)
     390           0 :     log_fatal ("AES encryption in RNG failed: %s\n", _gcry_strerror (err));
     391          12 : }
     392             : 
     393             : 
     394             : /* The core ANSI X9.31, Appendix A.2.4 function using AES.  The caller
     395             :    needs to pass a 16 byte buffer for the result, the 16 byte
     396             :    datetime_DT value and the 16 byte seed value V.  The caller also
     397             :    needs to pass an appropriate KEY and make sure to pass a valid
     398             :    seed_V.  The caller also needs to provide two 16 bytes buffer for
     399             :    intermediate results, they may be reused by the caller later.
     400             : 
     401             :    On return the result is stored at RESULT_R and the SEED_V is
     402             :    updated.  May only be used while holding the lock.  */
     403             : static void
     404           4 : x931_aes (unsigned char result_R[16],
     405             :           unsigned char datetime_DT[16], unsigned char seed_V[16],
     406             :           gcry_cipher_hd_t key,
     407             :           unsigned char intermediate_I[16], unsigned char temp_xor[16])
     408             : {
     409             :   /* Let ede*X(Y) represent the AES encryption of Y under the key *X.
     410             : 
     411             :      Let V be a 128-bit seed value which is also kept secret, and XOR
     412             :      be the exclusive-or operator. Let DT be a date/time vector which
     413             :      is updated on each iteration. I is a intermediate value.
     414             : 
     415             :      I = ede*K(DT)  */
     416           4 :   encrypt_aes (key, intermediate_I, datetime_DT, 16);
     417             : 
     418             :   /* R = ede*K(I XOR V) */
     419           4 :   xor_buffer (temp_xor, intermediate_I, seed_V, 16);
     420           4 :   encrypt_aes (key, result_R, temp_xor, 16);
     421             : 
     422             :   /* V = ede*K(R XOR I).  */
     423           4 :   xor_buffer (temp_xor, result_R, intermediate_I, 16);
     424           4 :   encrypt_aes (key, seed_V, temp_xor, 16);
     425             : 
     426             :   /* Zero out temporary values.  */
     427           4 :   wipememory (intermediate_I, 16);
     428           4 :   wipememory (temp_xor, 16);
     429           4 : }
     430             : 
     431             : 
     432             : /* The high level driver to x931_aes.  This one does the required
     433             :    tests and calls the core function until the entire buffer has been
     434             :    filled.  OUTPUT is a caller provided buffer of LENGTH bytes to
     435             :    receive the random, RNG_CTX is the context of the RNG.  The context
     436             :    must be properly initialized.  Returns 0 on success. */
     437             : static int
     438           3 : x931_aes_driver (unsigned char *output, size_t length, rng_context_t rng_ctx)
     439             : {
     440             :   unsigned char datetime_DT[16];
     441             :   unsigned char *intermediate_I, *temp_buffer, *result_buffer;
     442             :   size_t nbytes;
     443             : 
     444           3 :   gcry_assert (fips_rng_is_locked);
     445           3 :   gcry_assert (rng_ctx->cipher_hd);
     446           3 :   gcry_assert (rng_ctx->is_seeded);
     447             : 
     448           3 :   gcry_assert (tempvalue_for_x931_aes_driver);
     449             :   gcry_assert (TEMPVALUE_FOR_X931_AES_DRIVER_SIZE == 48);
     450           3 :   intermediate_I = tempvalue_for_x931_aes_driver;
     451           3 :   temp_buffer    = tempvalue_for_x931_aes_driver + 16;
     452           3 :   result_buffer  = tempvalue_for_x931_aes_driver + 32;
     453             : 
     454          10 :   while (length)
     455             :     {
     456             :       /* Unless we are running with a test context, we require a new
     457             :          seed after some time.  */
     458           4 :       if (!rng_ctx->test_dt_ptr && rng_ctx->use_counter > SEED_TTL)
     459             :         {
     460           0 :           x931_reseed (rng_ctx);
     461           0 :           rng_ctx->use_counter = 0;
     462             :         }
     463             : 
     464             :       /* Due to the design of the RNG, we always receive 16 bytes (128
     465             :          bit) of random even if we require less.  The extra bytes
     466             :          returned are not used.  Intheory we could save them for the
     467             :          next invocation, but that would make the control flow harder
     468             :          to read.  */
     469           4 :       nbytes = length < 16? length : 16;
     470             : 
     471           4 :       x931_get_dt (datetime_DT, 16, rng_ctx);
     472           8 :       x931_aes (result_buffer,
     473           4 :                 datetime_DT, rng_ctx->seed_V, rng_ctx->cipher_hd,
     474             :                 intermediate_I, temp_buffer);
     475           4 :       rng_ctx->use_counter++;
     476             : 
     477           4 :       if (rng_ctx->test_no_dup_check
     478           0 :           && rng_ctx->test_dt_ptr
     479           0 :           && rng_ctx != nonce_context
     480           0 :           && rng_ctx != std_rng_context
     481           0 :           && rng_ctx != strong_rng_context)
     482             :         {
     483             :           /* This is a test context which does not want the duplicate
     484             :              block check. */
     485             :         }
     486             :       else
     487             :         {
     488             :           /* Do a basic check on the output to avoid a stuck generator.  */
     489           4 :           if (!rng_ctx->compare_value_valid)
     490             :             {
     491             :               /* First time used, only save the result.  */
     492           1 :               memcpy (rng_ctx->compare_value, result_buffer, 16);
     493           1 :               rng_ctx->compare_value_valid = 1;
     494           1 :               continue;
     495             :             }
     496           3 :           if (!memcmp (rng_ctx->compare_value, result_buffer, 16))
     497             :             {
     498             :               /* Ooops, we received the same 128 bit block - that should
     499             :                  in theory never happen.  The FIPS requirement says that
     500             :                  we need to put ourself into the error state in such
     501             :                  case.  */
     502           0 :               fips_signal_error ("duplicate 128 bit block returned by RNG");
     503           0 :               return -1;
     504             :             }
     505           3 :           memcpy (rng_ctx->compare_value, result_buffer, 16);
     506             :         }
     507             : 
     508             :       /* Append to outbut.  */
     509           3 :       memcpy (output, result_buffer, nbytes);
     510           3 :       wipememory (result_buffer, 16);
     511           3 :       output += nbytes;
     512           3 :       length -= nbytes;
     513             :     }
     514             : 
     515           3 :   return 0;
     516             : }
     517             : 
     518             : 
     519             : /* Callback for x931_generate_key. Note that this callback uses the
     520             :    global ENTROPY_COLLECT_BUFFER which has been setup by get_entropy.
     521             :    ORIGIN is not used but required due to the design of entropy
     522             :    gathering module. */
     523             : static void
     524           2 : entropy_collect_cb (const void *buffer, size_t length,
     525             :                     enum random_origins origin)
     526             : {
     527           2 :   const unsigned char *p = buffer;
     528             : 
     529             :   (void)origin;
     530             : 
     531           2 :   gcry_assert (fips_rng_is_locked);
     532           2 :   gcry_assert (entropy_collect_buffer);
     533             : 
     534             :   /* Note that we need to protect against gatherers returning more
     535             :      than the requested bytes (e.g. rndw32).  */
     536          36 :   while (length-- && entropy_collect_buffer_len < entropy_collect_buffer_size)
     537             :     {
     538          32 :       entropy_collect_buffer[entropy_collect_buffer_len++] ^= *p++;
     539             :     }
     540           2 : }
     541             : 
     542             : 
     543             : /* Get NBYTES of entropy from the kernel device.  The callers needs to
     544             :    free the returned buffer.  The function either succeeds or
     545             :    terminates the process in case of a fatal error. */
     546             : static void *
     547           2 : get_entropy (size_t nbytes)
     548             : {
     549             :   void *result;
     550             :   int rc;
     551             : 
     552           2 :   gcry_assert (!entropy_collect_buffer);
     553           2 :   entropy_collect_buffer = xmalloc_secure (nbytes);
     554           2 :   entropy_collect_buffer_size = nbytes;
     555           2 :   entropy_collect_buffer_len = 0;
     556             : 
     557             : #if USE_RNDLINUX
     558           2 :   rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0,
     559             :                                      X931_AES_KEYLEN,
     560             :                                      GCRY_VERY_STRONG_RANDOM);
     561             : #elif USE_RNDW32
     562             :   do
     563             :     {
     564             :       rc = _gcry_rndw32_gather_random (entropy_collect_cb, 0,
     565             :                                        X931_AES_KEYLEN,
     566             :                                        GCRY_VERY_STRONG_RANDOM);
     567             :     }
     568             :   while (rc >= 0 && entropy_collect_buffer_len < entropy_collect_buffer_size);
     569             : #else
     570             :   rc = -1;
     571             : #endif
     572             : 
     573           2 :   if (rc < 0 || entropy_collect_buffer_len != entropy_collect_buffer_size)
     574             :     {
     575           0 :       xfree (entropy_collect_buffer);
     576           0 :       entropy_collect_buffer = NULL;
     577           0 :       log_fatal ("error getting entropy data\n");
     578             :     }
     579           2 :   result = entropy_collect_buffer;
     580           2 :   entropy_collect_buffer = NULL;
     581           2 :   return result;
     582             : }
     583             : 
     584             : 
     585             : /* Generate a key for use with x931_aes.  The function returns a
     586             :    handle to the cipher context readily prepared for ECB encryption.
     587             :    If FOR_NONCE is true, the key is retrieved by readong random from
     588             :    the standard generator.  On error NULL is returned.  */
     589             : static gcry_cipher_hd_t
     590           1 : x931_generate_key (int for_nonce)
     591             : {
     592             :   gcry_cipher_hd_t hd;
     593             :   gpg_err_code_t rc;
     594             :   void *buffer;
     595             : 
     596           1 :   gcry_assert (fips_rng_is_locked);
     597             : 
     598             :   /* Allocate a cipher context.  */
     599           1 :   rc = _gcry_cipher_open (&hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
     600             :                           GCRY_CIPHER_SECURE);
     601           1 :   if (rc)
     602             :     {
     603           0 :       log_error ("error creating cipher context for RNG: %s\n",
     604             :                  _gcry_strerror (rc));
     605           0 :       return NULL;
     606             :     }
     607             : 
     608             :   /* Get a key from the standard RNG or from the entropy source.  */
     609           1 :   if (for_nonce)
     610             :     {
     611           0 :       buffer = xmalloc (X931_AES_KEYLEN);
     612           0 :       get_random (buffer, X931_AES_KEYLEN, std_rng_context);
     613             :     }
     614             :   else
     615             :     {
     616           1 :       buffer = get_entropy (X931_AES_KEYLEN);
     617             :     }
     618             : 
     619             :   /* Set the key and delete the buffer because the key is now part of
     620             :      the cipher context.  */
     621           1 :   rc = _gcry_cipher_setkey (hd, buffer, X931_AES_KEYLEN);
     622           1 :   wipememory (buffer, X931_AES_KEYLEN);
     623           1 :   xfree (buffer);
     624           1 :   if (rc)
     625             :     {
     626           0 :       log_error ("error creating key for RNG: %s\n", _gcry_strerror (rc));
     627           0 :       _gcry_cipher_close (hd);
     628           0 :       return NULL;
     629             :     }
     630             : 
     631           1 :   return hd;
     632             : }
     633             : 
     634             : 
     635             : /* Generate a key for use with x931_aes.  The function copies a seed
     636             :    of LENGTH bytes into SEED_BUFFER. LENGTH needs to by given as 16.  */
     637             : static void
     638           1 : x931_generate_seed (unsigned char *seed_buffer, size_t length)
     639             : {
     640             :   void *buffer;
     641             : 
     642           1 :   gcry_assert (fips_rng_is_locked);
     643           1 :   gcry_assert (length == 16);
     644             : 
     645           1 :   buffer = get_entropy (X931_AES_KEYLEN);
     646             : 
     647           1 :   memcpy (seed_buffer, buffer, X931_AES_KEYLEN);
     648           1 :   wipememory (buffer, X931_AES_KEYLEN);
     649           1 :   xfree (buffer);
     650           1 : }
     651             : 
     652             : 
     653             : 
     654             : /* Reseed a generator.  This is also used for the initial seeding. */
     655             : static void
     656           1 : x931_reseed (rng_context_t rng_ctx)
     657             : {
     658           1 :   gcry_assert (fips_rng_is_locked);
     659             : 
     660           1 :   if (rng_ctx == nonce_context)
     661             :     {
     662             :       /* The nonce context is special.  It will be seeded using the
     663             :          standard random generator.  */
     664           0 :       get_random (rng_ctx->seed_V, 16, std_rng_context);
     665           0 :       rng_ctx->is_seeded = 1;
     666           0 :       rng_ctx->seed_init_pid = getpid ();
     667             :     }
     668             :   else
     669             :     {
     670             :       /* The other two generators are seeded from /dev/random.  */
     671           1 :       x931_generate_seed (rng_ctx->seed_V, 16);
     672           1 :       rng_ctx->is_seeded = 1;
     673           1 :       rng_ctx->seed_init_pid = getpid ();
     674             :     }
     675           1 : }
     676             : 
     677             : 
     678             : /* Core random function.  This is used for both nonce and random
     679             :    generator.  The actual RNG to be used depends on the random context
     680             :    RNG_CTX passed.  Note that this function is called with the RNG not
     681             :    yet locked.  */
     682             : static void
     683           3 : get_random (void *buffer, size_t length, rng_context_t rng_ctx)
     684             : {
     685           3 :   gcry_assert (buffer);
     686           3 :   gcry_assert (rng_ctx);
     687             : 
     688           3 :   check_guards (rng_ctx);
     689             : 
     690             :   /* Initialize the cipher handle and thus setup the key if needed.  */
     691           3 :   if (!rng_ctx->cipher_hd)
     692             :     {
     693           1 :       if (rng_ctx == nonce_context)
     694           0 :         rng_ctx->cipher_hd = x931_generate_key (1);
     695             :       else
     696           1 :         rng_ctx->cipher_hd = x931_generate_key (0);
     697           1 :       if (!rng_ctx->cipher_hd)
     698           0 :         goto bailout;
     699           1 :       rng_ctx->key_init_pid = getpid ();
     700             :     }
     701             : 
     702             :   /* Initialize the seed value if needed.  */
     703           3 :   if (!rng_ctx->is_seeded)
     704           1 :     x931_reseed (rng_ctx);
     705             : 
     706           3 :   if (rng_ctx->key_init_pid != getpid ()
     707           3 :       || rng_ctx->seed_init_pid != getpid ())
     708             :     {
     709             :       /* We are in a child of us.  Because we have no way yet to do
     710             :          proper re-initialization (including self-checks etc), the
     711             :          only chance we have is to bail out.  Obviusly a fork/exec
     712             :          won't harm because the exec overwrites the old image. */
     713           0 :       fips_signal_error ("fork without proper re-initialization "
     714             :                          "detected in RNG");
     715           0 :       goto bailout;
     716             :     }
     717             : 
     718           3 :   if (x931_aes_driver (buffer, length, rng_ctx))
     719           0 :     goto bailout;
     720             : 
     721           3 :   check_guards (rng_ctx);
     722           3 :   return;
     723             : 
     724             :  bailout:
     725           0 :   log_fatal ("severe error getting random\n");
     726             :   /*NOTREACHED*/
     727             : }
     728             : 
     729             : 
     730             : 
     731             : /* --- Public Functions --- */
     732             : 
     733             : /* Initialize this random subsystem.  If FULL is false, this function
     734             :    merely calls the basic initialization of the module and does not do
     735             :    anything more.  Doing this is not really required but when running
     736             :    in a threaded environment we might get a race condition
     737             :    otherwise. */
     738             : void
     739           4 : _gcry_rngfips_initialize (int full)
     740             : {
     741           4 :   basic_initialization ();
     742           4 :   if (!full)
     743           5 :     return;
     744             : 
     745             :   /* Allocate temporary buffers.  If that buffer already exists we
     746             :      know that we are already initialized.  */
     747           3 :   lock_rng ();
     748           3 :   if (!tempvalue_for_x931_aes_driver)
     749             :     {
     750             :       tempvalue_for_x931_aes_driver
     751           1 :         = xmalloc_secure (TEMPVALUE_FOR_X931_AES_DRIVER_SIZE);
     752             : 
     753             :       /* Allocate the random contexts.  Note that we do not need to use
     754             :          secure memory for the nonce context.  */
     755           1 :       nonce_context = xcalloc (1, sizeof *nonce_context);
     756           1 :       setup_guards (nonce_context);
     757             : 
     758           1 :       std_rng_context = xcalloc_secure (1, sizeof *std_rng_context);
     759           1 :       setup_guards (std_rng_context);
     760             : 
     761           1 :       strong_rng_context = xcalloc_secure (1, sizeof *strong_rng_context);
     762           1 :       setup_guards (strong_rng_context);
     763             :     }
     764             :   else
     765             :     {
     766             :       /* Already initialized. Do some sanity checks.  */
     767           2 :       gcry_assert (!nonce_context->test_dt_ptr);
     768           2 :       gcry_assert (!std_rng_context->test_dt_ptr);
     769           2 :       gcry_assert (!strong_rng_context->test_dt_ptr);
     770           2 :       check_guards (nonce_context);
     771           2 :       check_guards (std_rng_context);
     772           2 :       check_guards (strong_rng_context);
     773             :     }
     774           3 :   unlock_rng ();
     775             : }
     776             : 
     777             : 
     778             : /* Try to close the FDs of the random gather module.  This is
     779             :    currently only implemented for rndlinux. */
     780             : void
     781           0 : _gcry_rngfips_close_fds (void)
     782             : {
     783           0 :   lock_rng ();
     784             : #if USE_RNDLINUX
     785           0 :   _gcry_rndlinux_gather_random (NULL, 0, 0, 0);
     786             : #endif
     787           0 :   unlock_rng ();
     788           0 : }
     789             : 
     790             : 
     791             : /* Print some statistics about the RNG.  */
     792             : void
     793           0 : _gcry_rngfips_dump_stats (void)
     794             : {
     795             :   /* Not yet implemented.  */
     796           0 : }
     797             : 
     798             : 
     799             : /* This function returns true if no real RNG is available or the
     800             :    quality of the RNG has been degraded for test purposes.  */
     801             : int
     802           0 : _gcry_rngfips_is_faked (void)
     803             : {
     804           0 :   return 0;  /* Faked random is not allowed.  */
     805             : }
     806             : 
     807             : 
     808             : /* Add BUFLEN bytes from BUF to the internal random pool.  QUALITY
     809             :    should be in the range of 0..100 to indicate the goodness of the
     810             :    entropy added, or -1 for goodness not known. */
     811             : gcry_error_t
     812           0 : _gcry_rngfips_add_bytes (const void *buf, size_t buflen, int quality)
     813             : {
     814             :   (void)buf;
     815             :   (void)buflen;
     816             :   (void)quality;
     817           0 :   return 0;  /* Not implemented. */
     818             : }
     819             : 
     820             : 
     821             : /* Public function to fill the buffer with LENGTH bytes of
     822             :    cryptographically strong random bytes.  Level GCRY_WEAK_RANDOM is
     823             :    here mapped to GCRY_STRONG_RANDOM, GCRY_STRONG_RANDOM is strong
     824             :    enough for most usage, GCRY_VERY_STRONG_RANDOM is good for key
     825             :    generation stuff but may be very slow.  */
     826             : void
     827           3 : _gcry_rngfips_randomize (void *buffer, size_t length,
     828             :                          enum gcry_random_level level)
     829             : {
     830           3 :   _gcry_rngfips_initialize (1);  /* Auto-initialize if needed.  */
     831             : 
     832           3 :   lock_rng ();
     833           3 :   if (level == GCRY_VERY_STRONG_RANDOM)
     834           0 :     get_random (buffer, length, strong_rng_context);
     835             :   else
     836           3 :     get_random (buffer, length, std_rng_context);
     837           3 :   unlock_rng ();
     838           3 : }
     839             : 
     840             : 
     841             : /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
     842             : void
     843           0 : _gcry_rngfips_create_nonce (void *buffer, size_t length)
     844             : {
     845           0 :   _gcry_rngfips_initialize (1);  /* Auto-initialize if needed.  */
     846             : 
     847           0 :   lock_rng ();
     848           0 :   get_random (buffer, length, nonce_context);
     849           0 :   unlock_rng ();
     850           0 : }
     851             : 
     852             : 
     853             : /* Run a Know-Answer-Test using a dedicated test context.  Note that
     854             :    we can't use the samples from the NISR RNGVS document because they
     855             :    don't take the requirement to throw away the first block and use
     856             :    that for duplicate check in account.  Thus we made up our own test
     857             :    vectors. */
     858             : static gcry_err_code_t
     859           0 : selftest_kat (selftest_report_func_t report)
     860             : {
     861             :   static struct
     862             :   {
     863             :     const unsigned char key[16];
     864             :     const unsigned char dt[16];
     865             :     const unsigned char v[16];
     866             :     const unsigned char r[3][16];
     867             :   } tv[] =
     868             :     {
     869             :       { { 0xb9, 0xca, 0x7f, 0xd6, 0xa0, 0xf5, 0xd3, 0x42,
     870             :           0x19, 0x6d, 0x84, 0x91, 0x76, 0x1c, 0x3b, 0xbe },
     871             :         { 0x48, 0xb2, 0x82, 0x98, 0x68, 0xc2, 0x80, 0x00,
     872             :           0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x25, 0x00 },
     873             :         { 0x52, 0x17, 0x8d, 0x29, 0xa2, 0xd5, 0x84, 0x12,
     874             :           0x9d, 0x89, 0x9a, 0x45, 0x82, 0x02, 0xf7, 0x77 },
     875             :         { { 0x42, 0x9c, 0x08, 0x3d, 0x82, 0xf4, 0x8a, 0x40,
     876             :             0x66, 0xb5, 0x49, 0x27, 0xab, 0x42, 0xc7, 0xc3 },
     877             :           { 0x0e, 0xb7, 0x61, 0x3c, 0xfe, 0xb0, 0xbe, 0x73,
     878             :             0xf7, 0x6e, 0x6d, 0x6f, 0x1d, 0xa3, 0x14, 0xfa },
     879             :           { 0xbb, 0x4b, 0xc1, 0x0e, 0xc5, 0xfb, 0xcd, 0x46,
     880             :             0xbe, 0x28, 0x61, 0xe7, 0x03, 0x2b, 0x37, 0x7d } } },
     881             :       { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     882             :           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
     883             :         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     884             :           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
     885             :         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     886             :           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
     887             :         { { 0xf7, 0x95, 0xbd, 0x4a, 0x52, 0xe2, 0x9e, 0xd7,
     888             :             0x13, 0xd3, 0x13, 0xfa, 0x20, 0xe9, 0x8d, 0xbc },
     889             :           { 0xc8, 0xd1, 0xe5, 0x11, 0x59, 0x52, 0xf7, 0xfa,
     890             :             0x37, 0x38, 0xb4, 0xc5, 0xce, 0xb2, 0xb0, 0x9a },
     891             :           { 0x0d, 0x9c, 0xc5, 0x0d, 0x16, 0xe1, 0xbc, 0xed,
     892             :             0xcf, 0x60, 0x62, 0x09, 0x9d, 0x20, 0x83, 0x7e } } },
     893             :       { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     894             :           0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
     895             :         { 0x80, 0x00, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03,
     896             :           0xa0, 0x20, 0xa1, 0x21, 0xa2, 0x22, 0xa3, 0x23 },
     897             :         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     898             :           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
     899             :         { { 0x96, 0xed, 0xcc, 0xc3, 0xdd, 0x04, 0x7f, 0x75,
     900             :             0x63, 0x19, 0x37, 0x6f, 0x15, 0x22, 0x57, 0x56 },
     901             :           { 0x7a, 0x14, 0x76, 0x77, 0x95, 0x17, 0x7e, 0xc8,
     902             :             0x92, 0xe8, 0xdd, 0x15, 0xcb, 0x1f, 0xbc, 0xb1 },
     903             :           { 0x25, 0x3e, 0x2e, 0xa2, 0x41, 0x1b, 0xdd, 0xf5,
     904             :             0x21, 0x48, 0x41, 0x71, 0xb3, 0x8d, 0x2f, 0x4c } } }
     905             :     };
     906             :   int tvidx, ridx;
     907             :   rng_context_t test_ctx;
     908             :   gpg_err_code_t rc;
     909           0 :   const char *errtxt = NULL;
     910             :   unsigned char result[16];
     911             : 
     912           0 :   gcry_assert (tempvalue_for_x931_aes_driver);
     913             : 
     914           0 :   test_ctx = xcalloc (1, sizeof *test_ctx);
     915           0 :   setup_guards (test_ctx);
     916             : 
     917           0 :   lock_rng ();
     918             : 
     919           0 :   for (tvidx=0; tvidx < DIM (tv); tvidx++)
     920             :     {
     921             :       /* Setup the key.  */
     922           0 :       rc = _gcry_cipher_open (&test_ctx->cipher_hd,
     923             :                               GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
     924             :                               GCRY_CIPHER_SECURE);
     925           0 :       if (rc)
     926             :         {
     927           0 :           errtxt = "error creating cipher context for RNG";
     928           0 :           goto leave;
     929             :         }
     930             : 
     931           0 :       rc = _gcry_cipher_setkey (test_ctx->cipher_hd, tv[tvidx].key, 16);
     932           0 :       if (rc)
     933             :         {
     934           0 :           errtxt = "error setting key for RNG";
     935           0 :           goto leave;
     936             :         }
     937           0 :       test_ctx->key_init_pid = getpid ();
     938             : 
     939             :       /* Setup the seed.  */
     940           0 :       memcpy (test_ctx->seed_V, tv[tvidx].v, 16);
     941           0 :       test_ctx->is_seeded = 1;
     942           0 :       test_ctx->seed_init_pid = getpid ();
     943             : 
     944             :       /* Setup a DT value.  */
     945           0 :       test_ctx->test_dt_ptr = tv[tvidx].dt;
     946           0 :       test_ctx->test_dt_counter = ( (tv[tvidx].dt[12] << 24)
     947           0 :                                    |(tv[tvidx].dt[13] << 16)
     948           0 :                                    |(tv[tvidx].dt[14] << 8)
     949           0 :                                    |(tv[tvidx].dt[15]) );
     950             : 
     951             :       /* Get and compare the first three results.  */
     952           0 :       for (ridx=0; ridx < 3; ridx++)
     953             :         {
     954             :           /* Compute the next value.  */
     955           0 :           if (x931_aes_driver (result, 16, test_ctx))
     956             :             {
     957           0 :               errtxt = "X9.31 RNG core function failed";
     958           0 :               goto leave;
     959             :             }
     960             : 
     961             :           /* Compare it to the known value.  */
     962           0 :           if (memcmp (result, tv[tvidx].r[ridx], 16))
     963             :             {
     964             :               /* log_printhex ("x931_aes got: ", result, 16); */
     965             :               /* log_printhex ("x931_aes exp: ", tv[tvidx].r[ridx], 16); */
     966           0 :               errtxt = "RNG output does not match known value";
     967           0 :               goto leave;
     968             :             }
     969             :         }
     970             : 
     971             :       /* This test is actual pretty pointless because we use a local test
     972             :          context.  */
     973           0 :       if (test_ctx->key_init_pid != getpid ()
     974           0 :           || test_ctx->seed_init_pid != getpid ())
     975             :         {
     976           0 :           errtxt = "fork detection failed";
     977           0 :           goto leave;
     978             :         }
     979             : 
     980           0 :       _gcry_cipher_close (test_ctx->cipher_hd);
     981           0 :       test_ctx->cipher_hd = NULL;
     982           0 :       test_ctx->is_seeded = 0;
     983           0 :       check_guards (test_ctx);
     984             :     }
     985             : 
     986             :  leave:
     987           0 :   unlock_rng ();
     988           0 :   _gcry_cipher_close (test_ctx->cipher_hd);
     989           0 :   check_guards (test_ctx);
     990           0 :   xfree (test_ctx);
     991           0 :   if (report && errtxt)
     992           0 :     report ("random", 0, "KAT", errtxt);
     993           0 :   return errtxt? GPG_ERR_SELFTEST_FAILED : 0;
     994             : }
     995             : 
     996             : 
     997             : /* Run the self-tests.  */
     998             : gcry_error_t
     999           0 : _gcry_rngfips_selftest (selftest_report_func_t report)
    1000             : {
    1001             :   gcry_err_code_t ec;
    1002             : 
    1003             : #if defined(USE_RNDLINUX) || defined(USE_RNDW32)
    1004             :   {
    1005             :     char buffer[8];
    1006             : 
    1007             :     /* Do a simple test using the public interface.  This will also
    1008             :        enforce full initialization of the RNG.  We need to be fully
    1009             :        initialized due to the global requirement of the
    1010             :        tempvalue_for_x931_aes_driver stuff. */
    1011           0 :     _gcry_randomize (buffer, sizeof buffer, GCRY_STRONG_RANDOM);
    1012             :   }
    1013             : 
    1014           0 :   ec = selftest_kat (report);
    1015             : 
    1016             : #else /*!(USE_RNDLINUX||USE_RNDW32)*/
    1017             :   report ("random", 0, "setup", "no entropy gathering module");
    1018             :   ec = GPG_ERR_SELFTEST_FAILED;
    1019             : #endif
    1020           0 :   return gpg_error (ec);
    1021             : }
    1022             : 
    1023             : 
    1024             : /* Create a new test context for an external RNG test driver.  On
    1025             :    success the test context is stored at R_CONTEXT; on failure NULL is
    1026             :    stored at R_CONTEXT and an error code is returned.  */
    1027             : gcry_err_code_t
    1028           0 : _gcry_rngfips_init_external_test (void **r_context, unsigned int flags,
    1029             :                                   const void *key, size_t keylen,
    1030             :                                   const void *seed, size_t seedlen,
    1031             :                                   const void *dt, size_t dtlen)
    1032             : {
    1033             :   gpg_err_code_t rc;
    1034             :   rng_context_t test_ctx;
    1035             : 
    1036           0 :   _gcry_rngfips_initialize (1);  /* Auto-initialize if needed.  */
    1037             : 
    1038           0 :   if (!r_context
    1039           0 :       || !key  || keylen  != 16
    1040           0 :       || !seed || seedlen != 16
    1041           0 :       || !dt   || dtlen   != 16 )
    1042           0 :     return GPG_ERR_INV_ARG;
    1043             : 
    1044           0 :   test_ctx = xtrycalloc (1, sizeof *test_ctx + dtlen);
    1045           0 :   if (!test_ctx)
    1046           0 :     return gpg_err_code_from_syserror ();
    1047           0 :   setup_guards (test_ctx);
    1048             : 
    1049             :   /* Setup the key.  */
    1050           0 :   rc = _gcry_cipher_open (&test_ctx->cipher_hd,
    1051             :                           GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
    1052             :                           GCRY_CIPHER_SECURE);
    1053           0 :   if (rc)
    1054           0 :     goto leave;
    1055             : 
    1056           0 :   rc = _gcry_cipher_setkey (test_ctx->cipher_hd, key, keylen);
    1057           0 :   if (rc)
    1058           0 :     goto leave;
    1059             : 
    1060           0 :   test_ctx->key_init_pid = getpid ();
    1061             : 
    1062             :   /* Setup the seed.  */
    1063           0 :   memcpy (test_ctx->seed_V, seed, seedlen);
    1064           0 :   test_ctx->is_seeded = 1;
    1065           0 :   test_ctx->seed_init_pid = getpid ();
    1066             : 
    1067             :   /* Setup a DT value.  Because our context structure only stores a
    1068             :      pointer we copy the DT value to the extra space we allocated in
    1069             :      the test_ctx and set the pointer to that address.  */
    1070           0 :   memcpy ((unsigned char*)test_ctx + sizeof *test_ctx, dt, dtlen);
    1071           0 :   test_ctx->test_dt_ptr = (unsigned char*)test_ctx + sizeof *test_ctx;
    1072           0 :   test_ctx->test_dt_counter = ( (test_ctx->test_dt_ptr[12] << 24)
    1073           0 :                                |(test_ctx->test_dt_ptr[13] << 16)
    1074           0 :                                |(test_ctx->test_dt_ptr[14] << 8)
    1075           0 :                                |(test_ctx->test_dt_ptr[15]) );
    1076             : 
    1077           0 :   if ( (flags & 1) )
    1078           0 :     test_ctx->test_no_dup_check = 1;
    1079             : 
    1080           0 :   check_guards (test_ctx);
    1081             :   /* All fine.  */
    1082           0 :   rc = 0;
    1083             : 
    1084             :  leave:
    1085           0 :   if (rc)
    1086             :     {
    1087           0 :       _gcry_cipher_close (test_ctx->cipher_hd);
    1088           0 :       xfree (test_ctx);
    1089           0 :       *r_context = NULL;
    1090             :     }
    1091             :   else
    1092           0 :     *r_context = test_ctx;
    1093           0 :   return rc;
    1094             : }
    1095             : 
    1096             : 
    1097             : /* Get BUFLEN bytes from the RNG using the test CONTEXT and store them
    1098             :    at BUFFER.  Return 0 on success or an error code.  */
    1099             : gcry_err_code_t
    1100           0 : _gcry_rngfips_run_external_test (void *context, char *buffer, size_t buflen)
    1101             : {
    1102           0 :   rng_context_t test_ctx = context;
    1103             : 
    1104           0 :   if (!test_ctx || !buffer || buflen != 16)
    1105           0 :     return GPG_ERR_INV_ARG;
    1106             : 
    1107           0 :   lock_rng ();
    1108           0 :   get_random (buffer, buflen, test_ctx);
    1109           0 :   unlock_rng ();
    1110           0 :   return 0;
    1111             : }
    1112             : 
    1113             : /* Release the test CONTEXT.  */
    1114             : void
    1115           0 : _gcry_rngfips_deinit_external_test (void *context)
    1116             : {
    1117           0 :   rng_context_t test_ctx = context;
    1118             : 
    1119           0 :   if (test_ctx)
    1120             :     {
    1121           0 :       _gcry_cipher_close (test_ctx->cipher_hd);
    1122           0 :       xfree (test_ctx);
    1123             :     }
    1124           0 : }

Generated by: LCOV version 1.11