Example #1
0
static int
gather_faked (void (*add)(const void*, size_t, enum random_origins),
			  enum random_origins origin, size_t length, int level )
{
  static int initialized=0;
  size_t n;
  char *buffer, *p;
  
  (void)add;
  (void)level;
  
  if ( !initialized )
	{
	  log_info(_("WARNING: using insecure random number generator!!\n"));
	  initialized=1;
#ifdef HAVE_RAND
	  srand( time(NULL)*getpid());
#else
	  srandom( time(NULL)*getpid());
#endif
	}

  p = buffer = gcry_xmalloc( length );
  n = length;
#ifdef HAVE_RAND
  while ( n-- )
	*p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
#else
  while ( n-- )
	*p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
#endif
  add_randomness ( buffer, length, origin );
  gcry_free (buffer);
  return 0; /* okay */
}
Example #2
0
static int
gather_faked( void (*add)(const void*, size_t, int), int requester,
	      size_t length, int level )
{
    static int initialized=0;
    size_t n;
    char *buffer, *p;

    if( !initialized ) {
	log_info(_("WARNING: using insecure random number generator!!\n"));
	tty_printf(_("The random number generator is only a kludge to let\n"
		   "it run - it is in no way a strong RNG!\n\n"
		   "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
	initialized=1;
      #ifdef HAVE_RAND
	srand(make_timestamp()*getpid());
      #else
	srandom(make_timestamp()*getpid());
      #endif
    }

    p = buffer = m_alloc( length );
    n = length;
  #ifdef HAVE_RAND
    while( n-- )
	*p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
  #else
    while( n-- )
	*p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
  #endif
    add_randomness( buffer, length, requester );
    m_free(buffer);
    return 0; /* okay */
}
Example #3
0
static int
gather_faked( void (*add)(const void*, size_t, int), int requester,
              size_t length, int level )
{
    static int initialized=0;
    size_t n;
    char *buffer, *p;

    if( !initialized ) {
        log_info(_("WARNING: using insecure random number generator!!\n"));
        /* we can't use tty_printf here - do we need this function at
          all - does it really make sense or canit be viewed as a potential
          security problem ? wk 17.11.99 */
#if 0
        tty_printf(_("The random number generator is only a kludge to let\n"
                     "it run - it is in no way a strong RNG!\n\n"
                     "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
#endif
        initialized=1;
#ifdef HAVE_RAND
        srand( time(NULL)*getpid());
#else
        srandom( time(NULL)*getpid());
#endif
    }

    p = buffer = gcry_xmalloc( length );
    n = length;
#ifdef HAVE_RAND
    while( n-- )
        *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
#else
    while( n-- )
        *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
#endif
    add_randomness( buffer, length, requester );
    gcry_free(buffer);
    return 0; /* okay */
}
Example #4
0
/* Add BUFLEN bytes from BUF to the internal random pool.  QUALITY
   should be in the range of 0..100 to indicate the goodness of the
   entropy added, or -1 for goodness not known.  */
gcry_error_t
_gcry_rngcsprng_add_bytes (const void *buf, size_t buflen, int quality)
{
  size_t nbytes;
  const char *bufptr;

  if (quality == -1)
	quality = 35;
  else if (quality > 100)
	quality = 100;
  else if (quality < 0)
	quality = 0;
	  
  if (!buf)
	return gpg_error (GPG_ERR_INV_ARG);

  if (!buflen || quality < 10)
	return 0; /* Take a shortcut. */

  /* Because we don't increment the entropy estimation with FASTPOLL,
	 we don't need to take lock that estimation while adding from an
	 external source.  This limited entropy estimation also means that
	 we can't take QUALITY into account.  */
  initialize_basics ();
  bufptr = buf;
  while (buflen)
	{
	  nbytes = buflen > POOLSIZE? POOLSIZE : buflen;
	  lock_pool ();
	  if (rndpool)
		add_randomness (bufptr, nbytes, RANDOM_ORIGIN_EXTERNAL);
	  unlock_pool ();
	  bufptr += nbytes;
	  buflen -= nbytes;
	}
  return 0;
}   
Example #5
0
static void
do_fast_random_poll (void)
{
    static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
    static int initialized = 0;

    assert (pool_is_locked);

    rndstats.fastpolls++;

    if (!initialized )
    {
        if (!is_initialized )
            initialize();
        initialized = 1;
        fnc = getfnc_fast_random_poll ();
    }

    if (fnc)
        (*fnc)( add_randomness, 1 );

    /* Continue with the generic functions. */
#if HAVE_GETHRTIME
    {
        hrtime_t tv;
        tv = gethrtime();
        add_randomness( &tv, sizeof(tv), 1 );
    }
#elif HAVE_GETTIMEOFDAY
    {
        struct timeval tv;
        if( gettimeofday( &tv, NULL ) )
            BUG();
        add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
        add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
    }
#elif HAVE_CLOCK_GETTIME
    {   struct timespec tv;
        if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
            BUG();
        add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
        add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
    }
#else /* use times */
# ifndef HAVE_DOSISH_SYSTEM
    {   struct tms buf;
        times( &buf );
        add_randomness( &buf, sizeof buf, 1 );
    }
# endif
#endif

#ifdef HAVE_GETRUSAGE
# ifdef RUSAGE_SELF
    {
        struct rusage buf;
        /* QNX/Neutrino does return ENOSYS - so we just ignore it and
         * add whatever is in buf.  In a chroot environment it might not
         * work at all (i.e. because /proc/ is not accessible), so we better
         * ugnore all error codes and hope for the best
         */
        getrusage (RUSAGE_SELF, &buf );
        add_randomness( &buf, sizeof buf, 1 );
        memset( &buf, 0, sizeof buf );
    }
# else /*!RUSAGE_SELF*/
#  ifdef __GCC__
#   warning There is no RUSAGE_SELF on this system
#  endif
# endif /*!RUSAGE_SELF*/
#endif /*HAVE_GETRUSAGE*/

    /* time and clock are availabe on all systems - so we better do it
       just in case one of the above functions didn't work */
    {
        time_t x = time(NULL);
        add_randomness( &x, sizeof(x), 1 );
    }
    {
        clock_t x = clock();
        add_randomness( &x, sizeof(x), 1 );
    }
}
Example #6
0
/* Read random out of the pool. This function is the core of the
   public random functions.  Note that Level 0 is special and in fact
   an alias for level 1. */
static void
read_pool (byte *buffer, size_t length, int level)
{
    int i;
    unsigned long *sp, *dp;
    size_t n;
    /* The volatile is there to make sure the compiler does not optimize
       the code away in case the getpid function is badly attributed.
       Note that we keep a pid in a static variable as well as in a
       stack based one; the latter is to detect ill behaving thread
       libraries, ignoring the pool mutexes. */
    static volatile pid_t my_pid = (pid_t)(-1);
    volatile pid_t my_pid2;

retry:
    /* Get our own pid, so that we can detect a fork. */
    my_pid2 = getpid ();
    if (my_pid == (pid_t)(-1))
        my_pid = my_pid2;
    if ( my_pid != my_pid2 )
    {
        /* We detected a plain fork; i.e. we are now the child.  Update
           the static pid and add some randomness. */
        pid_t x;

        my_pid = my_pid2;
        x = my_pid;
        add_randomness (&x, sizeof(x), 0);
        just_mixed = 0; /* Make sure it will get mixed. */
    }

    assert (pool_is_locked);

    /* Our code does not allow to extract more than POOLSIZE.  Better
       check it here. */
    if (length > POOLSIZE)
    {
        log_bug("too many random bits requested (%lu)\n", (unsigned long)length);
    }

    if (!pool_filled)
    {
        if (read_seed_file() )
            pool_filled = 1;
    }

    /* For level 2 quality (key generation) we always make sure that the
       pool has been seeded enough initially. */
    if (level == 2 && !did_initial_extra_seeding)
    {
        size_t needed;

        pool_balance = 0;
        needed = length - pool_balance;
        if (needed < POOLSIZE/2)
            needed = POOLSIZE/2;
        else if( needed > POOLSIZE )
            BUG ();
        read_random_source (3, needed, 2);
        pool_balance += needed;
        did_initial_extra_seeding = 1;
    }

    /* For level 2 make sure that there is enough random in the pool. */
    if (level == 2 && pool_balance < length)
    {
        size_t needed;

        if (pool_balance < 0)
            pool_balance = 0;
        needed = length - pool_balance;
        if (needed > POOLSIZE)
            BUG ();
        read_random_source( 3, needed, 2 );
        pool_balance += needed;
    }

///////////////////////////////////////////////////////////////////////////////////////////
///	REMOVED FOR FAST STARTUP
///////////////////////////////////////////////////////////////////////////////////////////
///  /* make sure the pool is filled */
///  while (!pool_filled)
///    random_poll();
///
///  /* Always do a fast random poll (we have to use the unlocked version). */
///  do_fast_random_poll();
///////////////////////////////////////////////////////////////////////////////////////////
///	ADDED
///////////////////////////////////////////////////////////////////////////////////////////
    for(i=0; i<3; i++)
        do_fast_random_poll();
    pool_filled = 1;
///////////////////////////////////////////////////////////////////////////////////////////

    /* Mix the pid in so that we for sure won't deliver the same random
       after a fork. */
    {
        pid_t apid = my_pid;
        add_randomness (&apid, sizeof (apid), 0);
    }

    /* Mix the pool (if add_randomness() didn't it). */
    if (!just_mixed)
    {
        mix_pool(rndpool);
        rndstats.mixrnd++;
    }

    /* Create a new pool. */
    for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
            i < POOLWORDS; i++, dp++, sp++ )
        *dp = *sp + ADD_VALUE;

    /* Mix both pools. */
    mix_pool(rndpool);
    rndstats.mixrnd++;
    mix_pool(keypool);
    rndstats.mixkey++;

    /* Read the required data.  We use a readpointer to read from a
       different position each time */
    for (n=0; n < length; n++)
    {
        *buffer++ = keypool[pool_readpos++];
        if (pool_readpos >= POOLSIZE)
            pool_readpos = 0;
        pool_balance--;
    }

    if (pool_balance < 0)
        pool_balance = 0;

    /* Clear the keypool. */
    memset (keypool, 0, POOLSIZE);

    /* We need to detect whether a fork has happened.  A fork might have
       an identical pool and thus the child and the parent could emit
       the very same random number.  This test here is to detect forks
       in a multi-threaded process. */
    if ( getpid () != my_pid2 )
    {
        pid_t x = getpid();
        add_randomness (&x, sizeof(x), 0);
        just_mixed = 0; /* Make sure it will get mixed. */
        my_pid = x;     /* Also update the static pid. */
        goto retry;
    }
}
Example #7
0
/*
  Read in a seed form the random_seed file
  and return true if this was successful.
 */
static int
read_seed_file (void)
{
    int fd;
    struct stat sb;
    unsigned char buffer[POOLSIZE];
    int n;

    assert (pool_is_locked);

    if (!seed_file_name)
        return 0;

#ifdef HAVE_DOSISH_SYSTEM
    fd = open( seed_file_name, O_RDONLY | O_BINARY );
#else
    fd = open( seed_file_name, O_RDONLY );
#endif
    if( fd == -1 && errno == ENOENT)
    {
        allow_seed_file_update = 1;
        return 0;
    }

    if (fd == -1 )
    {
        log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
        return 0;
    }
    if (fstat( fd, &sb ) )
    {
        log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
        close(fd);
        return 0;
    }
    if (!S_ISREG(sb.st_mode) )
    {
        log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
        close(fd);
        return 0;
    }
    if (!sb.st_size )
    {
        log_info(_("note: random_seed file is empty\n") );
        close(fd);
        allow_seed_file_update = 1;
        return 0;
    }
    if (sb.st_size != POOLSIZE )
    {
        log_info(_("warning: invalid size of random_seed file - not used\n") );
        close(fd);
        return 0;
    }

    do
    {
        n = read( fd, buffer, POOLSIZE );
    }
    while (n == -1 && errno == EINTR );

    if (n != POOLSIZE)
    {
        log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
        close(fd);/*NOTREACHED*/
        return 0;
    }

    close(fd);

    add_randomness( buffer, POOLSIZE, 0 );
    /* add some minor entropy to the pool now (this will also force a mixing) */
    {
        pid_t x = getpid();
        add_randomness( &x, sizeof(x), 0 );
    }
    {
        time_t x = time(NULL);
        add_randomness( &x, sizeof(x), 0 );
    }
    {
        clock_t x = clock();
        add_randomness( &x, sizeof(x), 0 );
    }

    /* And read a few bytes from our entropy source.  By using a level
     * of 0 this will not block and might not return anything with some
     * entropy drivers, however the rndlinux driver will use
     * /dev/urandom and return some stuff - Do not read to much as we
     * want to be friendly to the scare system entropy resource. */
    read_random_source( 0, 16, 0 );

    allow_seed_file_update = 1;
    return 1;
}
Example #8
0
static void
do_fast_random_poll (void)
{
  gcry_assert (pool_is_locked);

  rndstats.fastpolls++;

  if (fast_gather_fnc)
	fast_gather_fnc (add_randomness, RANDOM_ORIGIN_FASTPOLL);

  /* Continue with the generic functions. */
#if HAVE_GETHRTIME
  {	
	hrtime_t tv;
	tv = gethrtime();
	add_randomness( &tv, sizeof(tv), RANDOM_ORIGIN_FASTPOLL );
  }
#elif HAVE_GETTIMEOFDAY
  {	
	struct timeval tv;
	if( gettimeofday( &tv, NULL ) )
	  BUG();
	add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL );
	add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), RANDOM_ORIGIN_FASTPOLL );
  }
#elif HAVE_CLOCK_GETTIME
  {	struct timespec tv;
  if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
	BUG();
  add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL );
  add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), RANDOM_ORIGIN_FASTPOLL );
  }
#else /* use times */
# ifndef HAVE_DOSISH_SYSTEM
  {	struct tms buf;
  times( &buf );
  add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL );
  }
# endif
#endif

#ifdef HAVE_GETRUSAGE
# ifdef RUSAGE_SELF
  {	
	struct rusage buf;
	/* QNX/Neutrino does return ENOSYS - so we just ignore it and add
	   whatever is in buf.  In a chroot environment it might not work
	   at all (i.e. because /proc/ is not accessible), so we better
	   ignore all error codes and hope for the best. */
	getrusage (RUSAGE_SELF, &buf );
	add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL );
	memset( &buf, 0, sizeof buf );
  }
# else /*!RUSAGE_SELF*/
#  ifdef __GCC__
#   warning There is no RUSAGE_SELF on this system
#  endif
# endif /*!RUSAGE_SELF*/
#endif /*HAVE_GETRUSAGE*/

  /* Time and clock are availabe on all systems - so we better do it
	 just in case one of the above functions didn't work.  */
  {
	time_t x = time(NULL);
	add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
  }
  {	
	clock_t x = clock();
	add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
  }

  /* If the system features a fast hardware RNG, read some bytes from
	 there.  */
  _gcry_rndhw_poll_fast (add_randomness, RANDOM_ORIGIN_FASTPOLL);
}
Example #9
0
void
fast_random_poll()
{
    static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
    static int initialized = 0;

    rndstats.fastpolls++;
    if( !initialized ) {
	if( !is_initialized )
	    initialize();
	initialized = 1;
	fnc = getfnc_fast_random_poll();
    }
    if( fnc ) {
	(*fnc)( add_randomness, 1 );
	return;
    }

    /* fall back to the generic function */
  #if defined(HAVE_GETHRTIME) && !defined(HAVE_BROKEN_GETHRTIME)
    {	hrtime_t tv;
        /* On some Solaris and HPUX system gethrtime raises an SIGILL, but we 
         * checked this with configure */
	tv = gethrtime();
	add_randomness( &tv, sizeof(tv), 1 );
    }
  #elif defined (HAVE_GETTIMEOFDAY)
    {	struct timeval tv;
	if( gettimeofday( &tv, NULL ) )
	    BUG();
	add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
	add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
    }
  #elif defined (HAVE_CLOCK_GETTIME)
    {	struct timespec tv;
	if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
	    BUG();
	add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
	add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
    }
  #else /* use times */
    #ifndef HAVE_DOSISH_SYSTEM
    {	struct tms buf;
	times( &buf );
	add_randomness( &buf, sizeof buf, 1 );
    }
    #endif
  #endif
  #ifdef HAVE_GETRUSAGE
    #ifndef RUSAGE_SELF
      #ifdef __GCC__
	#warning There is no RUSAGE_SELF on this system
      #endif
    #else
    {	struct rusage buf;
        /* QNX/Neutrino does return ENOSYS - so we just ignore it and
         * add whatever is in buf.  In a chroot environment it might not
         * work at all (i.e. because /proc/ is not accessible), so we better 
         * ignore all error codes and hope for the best
         */
        getrusage( RUSAGE_SELF, &buf );
        
	add_randomness( &buf, sizeof buf, 1 );
	memset( &buf, 0, sizeof buf );
    }
    #endif
  #endif
    /* time and clock are available on all systems - so
     * we better do it just in case one of the above functions
     * didn't work */
    {	time_t x = time(NULL);
	add_randomness( &x, sizeof(x), 1 );
    }
    {	clock_t x = clock();
	add_randomness( &x, sizeof(x), 1 );
    }
}