LCOV - code coverage report
Current view: top level - random - random.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 88 165 53.3 %
Date: 2016-12-01 18:32:04 Functions: 11 22 50.0 %

          Line data    Source code
       1             : /* random.c - Random number switch
       2             :  * Copyright (C) 2003, 2006, 2008, 2012  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             :   This module switches between different implementations of random
      22             :   number generators and provides a few help functions.
      23             :  */
      24             : 
      25             : #include <config.h>
      26             : #include <stdio.h>
      27             : #include <stdlib.h>
      28             : #include <errno.h>
      29             : #include <time.h>
      30             : #include <sys/types.h>
      31             : #include <unistd.h>
      32             : 
      33             : #include "g10lib.h"
      34             : #include "random.h"
      35             : #include "rand-internal.h"
      36             : #include "cipher.h"         /* For _gcry_sha1_hash_buffer().  */
      37             : 
      38             : 
      39             : /* If not NULL a progress function called from certain places and the
      40             :    opaque value passed along.  Registered by
      41             :    _gcry_register_random_progress (). */
      42             : static void (*progress_cb) (void *,const char*,int,int, int );
      43             : static void *progress_cb_data;
      44             : 
      45             : /* Flags indicating the requested RNG types.  */
      46             : static struct
      47             : {
      48             :   int standard;
      49             :   int fips;
      50             :   int system;
      51             : } rng_types;
      52             : 
      53             : 
      54             : /* This is the lock we use to protect the buffer used by the nonce
      55             :    generation.  */
      56             : GPGRT_LOCK_DEFINE (nonce_buffer_lock);
      57             : 
      58             : 
      59             : 
      60             : /* ---  Functions  --- */
      61             : 
      62             : 
      63             : /* Used to register a progress callback.  This needs to be called
      64             :    before any threads are created. */
      65             : void
      66           1 : _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
      67             :                                 void *cb_data )
      68             : {
      69           1 :   progress_cb = cb;
      70           1 :   progress_cb_data = cb_data;
      71           1 : }
      72             : 
      73             : 
      74             : /* This progress function is currently used by the random modules to
      75             :    give hints on how much more entropy is required. */
      76             : void
      77           0 : _gcry_random_progress (const char *what, int printchar, int current, int total)
      78             : {
      79           0 :   if (progress_cb)
      80           0 :     progress_cb (progress_cb_data, what, printchar, current, total);
      81           0 : }
      82             : 
      83             : 
      84             : /* Set the preferred RNG type.  This may be called at any time even
      85             :    before gcry_check_version.  Thus we can't assume any thread system
      86             :    initialization.  A type of 0 is used to indicate that any Libgcrypt
      87             :    initialization has been done.*/
      88             : void
      89          85 : _gcry_set_preferred_rng_type (int type)
      90             : {
      91             :   static int any_init;
      92             : 
      93          85 :   if (!type)
      94             :     {
      95          55 :       any_init = 1;
      96             :     }
      97          30 :   else if (type == GCRY_RNG_TYPE_STANDARD)
      98             :     {
      99          10 :       rng_types.standard = 1;
     100             :     }
     101          20 :   else if (any_init)
     102             :     {
     103             :       /* After any initialization has been done we only allow to
     104             :          upgrade to the standard RNG (handled above).  All other
     105             :          requests are ignored.  The idea is that the application needs
     106             :          to declare a preference for a weaker RNG as soon as possible
     107             :          and before any library sets a preference.  We assume that a
     108             :          library which uses Libgcrypt calls an init function very
     109             :          early.  This way --- even if the library gets initialized
     110             :          early by the application --- it is unlikely that it can
     111             :          select a lower priority RNG.
     112             : 
     113             :          This scheme helps to ensure that existing unmodified
     114             :          applications (e.g. gpg2), which don't known about the new RNG
     115             :          selection system, will continue to use the standard RNG and
     116             :          not be tricked by some library to use a lower priority RNG.
     117             :          There are some loopholes here but at least most GnuPG stuff
     118             :          should be save because it calls src_c{gcry_control
     119             :          (GCRYCTL_SUSPEND_SECMEM_WARN);} quite early and thus inhibits
     120             :          switching to a low priority RNG.
     121             :        */
     122             :     }
     123           4 :   else if (type == GCRY_RNG_TYPE_FIPS)
     124             :     {
     125           2 :       rng_types.fips = 1;
     126             :     }
     127           2 :   else if (type == GCRY_RNG_TYPE_SYSTEM)
     128             :     {
     129           2 :       rng_types.system = 1;
     130             :     }
     131          85 : }
     132             : 
     133             : 
     134             : /* Initialize this random subsystem.  If FULL is false, this function
     135             :    merely calls the basic initialization of the module and does not do
     136             :    anything more.  Doing this is not really required but when running
     137             :    in a threaded environment we might get a race condition
     138             :    otherwise. */
     139             : void
     140       16631 : _gcry_random_initialize (int full)
     141             : {
     142       16631 :   if (fips_mode ())
     143           0 :     _gcry_rngdrbg_inititialize (full);
     144       16627 :   else if (rng_types.standard)
     145           2 :     _gcry_rngcsprng_initialize (full);
     146       16625 :   else if (rng_types.fips)
     147           2 :     _gcry_rngdrbg_inititialize (full);
     148       16623 :   else if (rng_types.system)
     149           2 :     _gcry_rngsystem_initialize (full);
     150             :   else
     151       16621 :     _gcry_rngcsprng_initialize (full);
     152       16633 : }
     153             : 
     154             : 
     155             : /* If possible close file descriptors used by the RNG. */
     156             : void
     157           0 : _gcry_random_close_fds (void)
     158             : {
     159             :   /* Note that we can't do that directly because each random system
     160             :      has its own lock functions which need to be used for accessing
     161             :      the entropy gatherer.  */
     162             : 
     163           0 :   if (fips_mode ())
     164           0 :     _gcry_rngdrbg_close_fds ();
     165           0 :   else if (rng_types.standard)
     166           0 :     _gcry_rngcsprng_close_fds ();
     167           0 :   else if (rng_types.fips)
     168           0 :     _gcry_rngdrbg_close_fds ();
     169           0 :   else if (rng_types.system)
     170           0 :     _gcry_rngsystem_close_fds ();
     171             :   else
     172           0 :     _gcry_rngcsprng_close_fds ();
     173           0 : }
     174             : 
     175             : 
     176             : /* Return the current RNG type.  IGNORE_FIPS_MODE is a flag used to
     177             :    skip the test for FIPS.  This is useful, so that we are able to
     178             :    return the type of the RNG even before we have setup FIPS mode
     179             :    (note that FIPS mode is enabled by default until it is switched off
     180             :    by the initialization).  This is mostly useful for the regression
     181             :    test.  */
     182             : int
     183          65 : _gcry_get_rng_type (int ignore_fips_mode)
     184             : {
     185          65 :   if (!ignore_fips_mode && fips_mode ())
     186           0 :     return GCRY_RNG_TYPE_FIPS;
     187          65 :   else if (rng_types.standard)
     188          28 :     return GCRY_RNG_TYPE_STANDARD;
     189          37 :   else if (rng_types.fips)
     190          12 :     return GCRY_RNG_TYPE_FIPS;
     191          25 :   else if (rng_types.system)
     192          12 :     return GCRY_RNG_TYPE_SYSTEM;
     193             :   else
     194          13 :     return GCRY_RNG_TYPE_STANDARD;
     195             : }
     196             : 
     197             : 
     198             : void
     199           0 : _gcry_random_dump_stats (void)
     200             : {
     201           0 :   if (fips_mode ())
     202           0 :     _gcry_rngdrbg_dump_stats ();
     203             :   else
     204           0 :     _gcry_rngcsprng_dump_stats ();
     205           0 : }
     206             : 
     207             : 
     208             : /* This function should be called during initialization and before
     209             :    initialization of this module to place the random pools into secure
     210             :    memory.  */
     211             : void
     212           0 : _gcry_secure_random_alloc (void)
     213             : {
     214           0 :   if (fips_mode ())
     215             :     ;  /* Not used; the FIPS RNG is always in secure mode.  */
     216             :   else
     217           0 :     _gcry_rngcsprng_secure_alloc ();
     218           0 : }
     219             : 
     220             : 
     221             : /* This may be called before full initialization to degrade the
     222             :    quality of the RNG for the sake of a faster running test suite.  */
     223             : void
     224          16 : _gcry_enable_quick_random_gen (void)
     225             : {
     226          16 :   if (fips_mode ())
     227             :     ;  /* Not used.  */
     228             :   else
     229          16 :     _gcry_rngcsprng_enable_quick_gen ();
     230          16 : }
     231             : 
     232             : 
     233             : void
     234           0 : _gcry_set_random_daemon_socket (const char *socketname)
     235             : {
     236           0 :   if (fips_mode ())
     237             :     ;  /* Not used.  */
     238             :   else
     239           0 :     _gcry_rngcsprng_set_daemon_socket (socketname);
     240           0 : }
     241             : 
     242             : /* With ONOFF set to 1, enable the use of the daemon.  With ONOFF set
     243             :    to 0, disable the use of the daemon.  With ONOF set to -1, return
     244             :    whether the daemon has been enabled. */
     245             : int
     246           0 : _gcry_use_random_daemon (int onoff)
     247             : {
     248           0 :   if (fips_mode ())
     249           0 :     return 0; /* Never enabled in fips mode.  */
     250             :   else
     251           0 :     return _gcry_rngcsprng_use_daemon (onoff);
     252             : }
     253             : 
     254             : 
     255             : /* This function returns true if no real RNG is available or the
     256             :    quality of the RNG has been degraded for test purposes.  */
     257             : int
     258           0 : _gcry_random_is_faked (void)
     259             : {
     260           0 :   if (fips_mode ())
     261           0 :     return _gcry_rngdrbg_is_faked ();
     262             :   else
     263           0 :     return _gcry_rngcsprng_is_faked ();
     264             : }
     265             : 
     266             : 
     267             : /* Add BUFLEN bytes from BUF to the internal random pool.  QUALITY
     268             :    should be in the range of 0..100 to indicate the goodness of the
     269             :    entropy added, or -1 for goodness not known.  */
     270             : gcry_err_code_t
     271           0 : _gcry_random_add_bytes (const void *buf, size_t buflen, int quality)
     272             : {
     273           0 :   if (fips_mode ())
     274           0 :     return 0; /* No need for this in fips mode.  */
     275           0 :   else if (rng_types.standard)
     276           0 :     return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality));
     277           0 :   else if (rng_types.fips)
     278           0 :     return 0;
     279           0 :   else if (rng_types.system)
     280           0 :     return 0;
     281             :   else /* default */
     282           0 :     return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality));
     283             : }
     284             : 
     285             : 
     286             : /* Helper function.  */
     287             : static void
     288         713 : do_randomize (void *buffer, size_t length, enum gcry_random_level level)
     289             : {
     290         713 :   if (fips_mode ())
     291           0 :     _gcry_rngdrbg_randomize (buffer, length, level);
     292         713 :   else if (rng_types.standard)
     293          14 :     _gcry_rngcsprng_randomize (buffer, length, level);
     294         699 :   else if (rng_types.fips)
     295           6 :     _gcry_rngdrbg_randomize (buffer, length, level);
     296         693 :   else if (rng_types.system)
     297           6 :     _gcry_rngsystem_randomize (buffer, length, level);
     298             :   else /* default */
     299         687 :     _gcry_rngcsprng_randomize (buffer, length, level);
     300         713 : }
     301             : 
     302             : /* The public function to return random data of the quality LEVEL.
     303             :    Returns a pointer to a newly allocated and randomized buffer of
     304             :    LEVEL and NBYTES length.  Caller must free the buffer.  */
     305             : void *
     306           0 : _gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
     307             : {
     308             :   void *buffer;
     309             : 
     310           0 :   buffer = xmalloc (nbytes);
     311           0 :   do_randomize (buffer, nbytes, level);
     312           0 :   return buffer;
     313             : }
     314             : 
     315             : 
     316             : /* The public function to return random data of the quality LEVEL;
     317             :    this version of the function returns the random in a buffer allocated
     318             :    in secure memory.  Caller must free the buffer. */
     319             : void *
     320         408 : _gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
     321             : {
     322             :   void *buffer;
     323             : 
     324             :   /* Historical note (1.3.0--1.4.1): The buffer was only allocated
     325             :      in secure memory if the pool in random-csprng.c was also set to
     326             :      use secure memory.  */
     327         408 :   buffer = xmalloc_secure (nbytes);
     328         408 :   do_randomize (buffer, nbytes, level);
     329         408 :   return buffer;
     330             : }
     331             : 
     332             : 
     333             : /* Public function to fill the buffer with LENGTH bytes of
     334             :    cryptographically strong random bytes.  Level GCRY_WEAK_RANDOM is
     335             :    not very strong, GCRY_STRONG_RANDOM is strong enough for most
     336             :    usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but
     337             :    may be very slow.  */
     338             : void
     339         305 : _gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
     340             : {
     341         305 :   do_randomize (buffer, length, level);
     342         305 : }
     343             : 
     344             : 
     345             : /* This function may be used to specify the file to be used as a seed
     346             :    file for the PRNG.  This function should be called prior to the
     347             :    initialization of the random module.  NAME may not be NULL.  */
     348             : void
     349           0 : _gcry_set_random_seed_file (const char *name)
     350             : {
     351           0 :   if (fips_mode ())
     352             :     ; /* No need for this in fips mode.  */
     353           0 :   else if (rng_types.standard)
     354           0 :     _gcry_rngcsprng_set_seed_file (name);
     355           0 :   else if (rng_types.fips)
     356             :     ;
     357           0 :   else if (rng_types.system)
     358             :     ;
     359             :   else /* default */
     360           0 :     _gcry_rngcsprng_set_seed_file (name);
     361           0 : }
     362             : 
     363             : 
     364             : /* If a seed file has been setup, this function may be used to write
     365             :    back the random numbers entropy pool.  */
     366             : void
     367           0 : _gcry_update_random_seed_file (void)
     368             : {
     369           0 :   if (fips_mode ())
     370             :     ; /* No need for this in fips mode.  */
     371           0 :   else if (rng_types.standard)
     372           0 :     _gcry_rngcsprng_update_seed_file ();
     373           0 :   else if (rng_types.fips)
     374             :     ;
     375           0 :   else if (rng_types.system)
     376             :     ;
     377             :   else /* default */
     378           0 :     _gcry_rngcsprng_update_seed_file ();
     379           0 : }
     380             : 
     381             : 
     382             : 
     383             : /* The fast random pool function as called at some places in
     384             :    libgcrypt.  This is merely a wrapper to make sure that this module
     385             :    is initialized and to lock the pool.  Note, that this function is a
     386             :    NOP unless a random function has been used or _gcry_initialize (1)
     387             :    has been used.  We use this hack so that the internal use of this
     388             :    function in cipher_open and md_open won't start filling up the
     389             :    random pool, even if no random will be required by the process. */
     390             : void
     391       50526 : _gcry_fast_random_poll (void)
     392             : {
     393       50526 :   if (fips_mode ())
     394             :     ; /* No need for this in fips mode.  */
     395       50526 :   else if (rng_types.standard)
     396           0 :     _gcry_rngcsprng_fast_poll ();
     397       50526 :   else if (rng_types.fips)
     398             :     ;
     399       50500 :   else if (rng_types.system)
     400             :     ;
     401             :   else /* default */
     402       50500 :     _gcry_rngcsprng_fast_poll ();
     403       50526 : }
     404             : 
     405             : 
     406             : 
     407             : /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
     408             : void
     409       16602 : _gcry_create_nonce (void *buffer, size_t length)
     410             : {
     411             :   static unsigned char nonce_buffer[20+8];
     412             :   static int nonce_buffer_initialized = 0;
     413             :   static volatile pid_t my_pid; /* The volatile is there to make sure the
     414             :                                    compiler does not optimize the code away
     415             :                                    in case the getpid function is badly
     416             :                                    attributed. */
     417             :   volatile pid_t apid;
     418             :   unsigned char *p;
     419             :   size_t n;
     420             :   int err;
     421             : 
     422             :   /* First check whether we shall use the FIPS nonce generator.  This
     423             :      is only done in FIPS mode, in all other modes, we use our own
     424             :      nonce generator which is seeded by the RNG actual in use.  */
     425       16602 :   if (fips_mode ())
     426             :     {
     427           0 :       _gcry_rngdrbg_randomize (buffer, length, GCRY_WEAK_RANDOM);
     428           0 :       return;
     429             :     }
     430             : 
     431             :   /* This is the nonce generator, which formerly lived in
     432             :      random-csprng.c.  It is now used by all RNG types except when in
     433             :      FIPS mode (not that this means it is also used if the FIPS RNG
     434             :      has been selected but we are not in fips mode).  */
     435             : 
     436             :   /* Make sure we are initialized. */
     437       16602 :   _gcry_random_initialize (1);
     438             : 
     439             :   /* Acquire the nonce buffer lock. */
     440       16603 :   err = gpgrt_lock_lock (&nonce_buffer_lock);
     441       16604 :   if (err)
     442           0 :     log_fatal ("failed to acquire the nonce buffer lock: %s\n",
     443             :                gpg_strerror (err));
     444             : 
     445       16604 :   apid = getpid ();
     446             :   /* The first time initialize our buffer. */
     447       16604 :   if (!nonce_buffer_initialized)
     448             :     {
     449          10 :       time_t atime = time (NULL);
     450          10 :       pid_t xpid = apid;
     451             : 
     452          10 :       my_pid = apid;
     453             : 
     454             :       if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
     455             :         BUG ();
     456             : 
     457             :       /* Initialize the first 20 bytes with a reasonable value so that
     458             :          a failure of gcry_randomize won't affect us too much.  Don't
     459             :          care about the uninitialized remaining bytes. */
     460          10 :       p = nonce_buffer;
     461          10 :       memcpy (p, &xpid, sizeof xpid);
     462          10 :       p += sizeof xpid;
     463          10 :       memcpy (p, &atime, sizeof atime);
     464             : 
     465             :       /* Initialize the never changing private part of 64 bits. */
     466          10 :       _gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
     467             : 
     468          10 :       nonce_buffer_initialized = 1;
     469             :     }
     470       16594 :   else if ( my_pid != apid )
     471             :     {
     472             :       /* We forked. Need to reseed the buffer - doing this for the
     473             :          private part should be sufficient. */
     474           0 :       do_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
     475             :       /* Update the pid so that we won't run into here again and
     476             :          again. */
     477           0 :       my_pid = apid;
     478             :     }
     479             : 
     480             :   /* Create the nonce by hashing the entire buffer, returning the hash
     481             :      and updating the first 20 bytes of the buffer with this hash. */
     482       55752 :   for (p = buffer; length > 0; length -= n, p += n)
     483             :     {
     484       39148 :       _gcry_sha1_hash_buffer (nonce_buffer,
     485             :                               nonce_buffer, sizeof nonce_buffer);
     486       39148 :       n = length > 20? 20 : length;
     487       39148 :       memcpy (p, nonce_buffer, n);
     488             :     }
     489             : 
     490             :   /* Release the nonce buffer lock. */
     491       16604 :   err = gpgrt_lock_unlock (&nonce_buffer_lock);
     492       16603 :   if (err)
     493           0 :     log_fatal ("failed to release the nonce buffer lock: %s\n",
     494             :                gpg_strerror (err));
     495             : }
     496             : 
     497             : 
     498             : /* Run the self-tests for the RNG.  This is currently only implemented
     499             :    for the FIPS generator.  */
     500             : gpg_error_t
     501           1 : _gcry_random_selftest (selftest_report_func_t report)
     502             : {
     503           1 :   if (fips_mode ())
     504           0 :     return _gcry_rngdrbg_selftest (report);
     505             :   else
     506           1 :     return 0; /* No selftests yet.  */
     507             : }

Generated by: LCOV version 1.11