Example #1
0
int
quick_random_gen( int onoff )
{
    int last;

    read_random_source(0,0,0); /* init */
    last = quick_test;
    if( onoff != -1 )
	quick_test = onoff;
    return faked_rng? 1 : last;
}
Example #2
0
int
_gcry_quick_random_gen( int onoff )
{
    int last;

    /* No need to lock it here because we are only initializing.  A
       prerequisite of the entire code is that it has already been
       initialized before any possible concurrent access */
    read_random_source(0,0,0); /* init */
    last = quick_test;
    if( onoff != -1 )
        quick_test = onoff;
    return faked_rng? 1 : last;
}
Example #3
0
static void
random_poll()
{
    rndstats.slowpolls++;
    read_random_source (2, POOLSIZE/5, 1);
}
Example #4
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 #5
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 #6
0
static void
random_poll()
{
  rndstats.slowpolls++;
  read_random_source (RANDOM_ORIGIN_SLOWPOLL, POOLSIZE/5, GCRY_STRONG_RANDOM);
}
Example #7
0
static void
read_pool( byte *buffer, size_t length, int level )
{
    int i;
    ulong *sp, *dp;

    if( length > POOLSIZE ) {
	log_bug("too many random bits requested\n");
    }

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

    /* For level 2 quality (key generation) we alwas 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;
    }

    /* make sure the pool is filled */
    while( !pool_filled )
	random_poll();

    /* do always a fast random poll */
    fast_random_poll();

    if( !level ) { /* no need for cryptographic strong random */
	/* create a new pool */
	for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
				    i < POOLWORDS; i++, dp++, sp++ )
	    *dp = *sp + ADD_VALUE;
	/* must mix both pools */
	mix_pool(rndpool); rndstats.mixrnd++;
	mix_pool(keypool); rndstats.mixkey++;
	memcpy( buffer, keypool, length );
    }
    else {
	/* 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;
	/* and mix both pools */
	mix_pool(rndpool); rndstats.mixrnd++;
	mix_pool(keypool); rndstats.mixkey++;
	/* read the required data
	 * we use a readpoiter to read from a different postion each
	 * time */
	while( length-- ) {
	    *buffer++ = keypool[pool_readpos++];
	    if( pool_readpos >= POOLSIZE )
		pool_readpos = 0;
	    pool_balance--;
	}
	if( pool_balance < 0 )
	    pool_balance = 0;
	/* and clear the keypool */
	memset( keypool, 0, POOLSIZE );
    }
}