Exemple #1
0
/* The fast random pool function as called at some places in
   libgcrypt.  This is merely a wrapper to make sure that this module
   is initalized and to look the pool.  Note, that this function is a
   NOP unless a random function has been used or _gcry_initialize (1)
   has been used.  We use this hack so that the internal use of this
   function in cipher_open and md_open won't start filling up the
   random pool, even if no random will be required by the process. */
void
_gcry_rngcsprng_fast_poll (void)
{
  initialize_basics ();

  lock_pool ();
  if (rndpool)
	{
	  /* Yes, we are fully initialized. */
	  do_fast_random_poll ();
	}
  unlock_pool ();
}
Exemple #2
0
/* The fast random pool function as called at some places in
   libgcrypt.  This is merely a wrapper to make sure that this module
   is initalized and to look the pool.  Note, that this function is a
   NOP unless a random function has been used or _gcry_initialize (1)
   has been used.  We use this hack so that the internal use of this
   function in cipher_open and md_open won't start filling up the
   radnom pool, even if no random will be required by the process. */
void
_gcry_fast_random_poll (void)
{
    int err;

    if (!is_initialized)
        return;

    err = ath_mutex_lock (&pool_lock);
    if (err)
        log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
    pool_is_locked = 1;

    do_fast_random_poll ();

    pool_is_locked = 0;
    err = ath_mutex_unlock (&pool_lock);
    if (err)
        log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));

}
Exemple #3
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;
    }
}