File libgcrypt-1.5.0-etc_gcrypt_rngseed-symlink.diff of Package compat-libgcrypt11.5136
diff -rNU 20 ../libgcrypt-1.5.0-o/random/random-csprng.c ./random/random-csprng.c
--- ../libgcrypt-1.5.0-o/random/random-csprng.c 2011-10-18 13:39:24.000000000 +0200
+++ ./random/random-csprng.c 2011-10-18 13:39:41.000000000 +0200
@@ -810,41 +810,41 @@
add_randomness( buffer, POOLSIZE, RANDOM_ORIGIN_INIT );
/* add some minor entropy to the pool now (this will also force a mixing) */
{
pid_t x = getpid();
add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
}
{
time_t x = time(NULL);
add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
}
{
clock_t x = clock();
add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
}
/* 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 too much as we
* want to be friendly to the scare system entropy resource. */
- read_random_source ( RANDOM_ORIGIN_INIT, 16, GCRY_WEAK_RANDOM );
+ read_random_source ( RANDOM_ORIGIN_INIT, 16, -1 );
allow_seed_file_update = 1;
return 1;
}
void
_gcry_rngcsprng_update_seed_file (void)
{
unsigned long *sp, *dp;
int fd, i;
/* We do only a basic initialization so that we can lock the pool.
This is required to cope with the case that this function is
called by some cleanup code at a point where the RNG has never
been initialized. */
initialize_basics ();
lock_pool ();
if ( !seed_file_name || !rndpool || !pool_filled )
diff -rNU 20 ../libgcrypt-1.5.0-o/random/random-fips.c ./random/random-fips.c
--- ../libgcrypt-1.5.0-o/random/random-fips.c 2011-10-18 13:39:24.000000000 +0200
+++ ./random/random-fips.c 2011-10-18 13:39:41.000000000 +0200
@@ -10,44 +10,44 @@
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
The core of this deterministic random number generator is
implemented according to the document "NIST-Recommended Random
Number Generator Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key
Triple DES and AES Algorithms" (2005-01-31). This implementation
uses the AES variant.
There are 3 random context which map to the different levels of
random quality:
- Generator Seed and Key Kernel entropy (init/reseed)
- ------------------------------------------------------------
- GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits
- GCRY_STRONG_RANDOM /dev/random 256/128 bits
+ Generator Seed and Key Kernel entropy (init/reseed)
+ ---------------------------------------------------------------------------------------
+ GCRY_VERY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits
+ GCRY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits
gcry_create_nonce GCRY_STRONG_RANDOM n/a
All random generators return their data in 128 bit blocks. If the
caller requested less bits, the extra bits are not used. The key
for each generator is only set once at the first time a generator
is used. The seed value is set with the key and again after 1000
(SEED_TTL) output blocks; the re-seeding is disabled in test mode.
The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are
keyed and seeded from the /dev/random device. Thus these
generators may block until the kernel has collected enough entropy.
The gcry_create_nonce generator is keyed and seeded from the
GCRY_STRONG_RANDOM generator. It may also block if the
GCRY_STRONG_RANDOM generator has not yet been used before and thus
gets initialized on the first use by gcry_create_nonce. This
special treatment is justified by the weaker requirements for a
nonce generator and to save precious kernel entropy for use by the
real random generators.
@@ -545,41 +545,41 @@
}
/* Get NBYTES of entropy from the kernel device. The callers needs to
free the returned buffer. The function either succeeds or
terminates the process in case of a fatal error. */
static void *
get_entropy (size_t nbytes)
{
void *result;
int rc;
gcry_assert (!entropy_collect_buffer);
entropy_collect_buffer = gcry_xmalloc_secure (nbytes);
entropy_collect_buffer_size = nbytes;
entropy_collect_buffer_len = 0;
#if USE_RNDLINUX
rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0,
X931_AES_KEYLEN,
- GCRY_VERY_STRONG_RANDOM);
+ -1);
#elif USE_RNDW32
do
{
rc = _gcry_rndw32_gather_random (entropy_collect_cb, 0,
X931_AES_KEYLEN,
GCRY_VERY_STRONG_RANDOM);
}
while (rc >= 0 && entropy_collect_buffer_len < entropy_collect_buffer_size);
#else
rc = -1;
#endif
if (rc < 0 || entropy_collect_buffer_len != entropy_collect_buffer_size)
{
gcry_free (entropy_collect_buffer);
entropy_collect_buffer = NULL;
log_fatal ("error getting entropy data\n");
}
result = entropy_collect_buffer;
entropy_collect_buffer = NULL;
diff -rNU 20 ../libgcrypt-1.5.0-o/random/rndlinux.c ./random/rndlinux.c
--- ../libgcrypt-1.5.0-o/random/rndlinux.c 2011-10-18 13:39:24.000000000 +0200
+++ ./random/rndlinux.c 2011-10-18 15:53:34.000000000 +0200
@@ -19,124 +19,157 @@
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_GETTIMEOFDAY
# include <sys/times.h>
#endif
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "types.h"
#include "g10lib.h"
#include "rand-internal.h"
-static int open_device ( const char *name );
+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed"
+static int open_device ( const char *name, int fatal );
static int
set_cloexec_flag (int fd)
{
int oldflags;
oldflags= fcntl (fd, F_GETFD, 0);
if (oldflags < 0)
return oldflags;
oldflags |= FD_CLOEXEC;
return fcntl (fd, F_SETFD, oldflags);
}
/*
* Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists)).
*/
static int
-open_device ( const char *name )
+open_device ( const char *name, int fatal )
{
int fd;
fd = open ( name, O_RDONLY );
if ( fd == -1 )
- log_fatal ("can't open %s: %s\n", name, strerror(errno) );
+ {
+ if (fatal)
+ log_fatal ("can't open %s: %s\n", name, strerror(errno) );
+ return fd;
+ }
if (set_cloexec_flag (fd))
log_error ("error setting FD_CLOEXEC on fd %d: %s\n",
fd, strerror (errno));
/* We used to do the following check, however it turned out that this
is not portable since more OSes provide a random device which is
sometimes implemented as another device type.
struct stat sb;
if( fstat( fd, &sb ) )
log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
if( (!S_ISCHR(sb.st_mode)) && (!S_ISFIFO(sb.st_mode)) )
log_fatal("invalid random device!\n" );
*/
return fd;
}
int
_gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
enum random_origins),
enum random_origins origin,
size_t length, int level )
{
static int fd_urandom = -1;
static int fd_random = -1;
+ static int fd_configured = -1;
int fd;
int n;
byte buffer[768];
size_t n_hw;
+ size_t orig_length = length;
size_t want = length;
size_t last_so_far = 0;
int any_need_entropy = 0;
int delay;
/* First read from a hardware source. However let it account only
for up to 50% of the requested bytes. */
n_hw = _gcry_rndhw_poll_slow (add, origin);
if (n_hw > length/2)
n_hw = length/2;
if (length > 1)
length -= n_hw;
/* Open the requested device. */
+
+ /* Clarification: path how "level == -1" comes about:
+ gcry_random_bytes( ... , GCRY_STRONG_RANDOM) (public) ->
+ do_randomize(buffer, nbytes, level) ->
+ _gcry_rngcsprng_randomize(buffer, length, level) ->
+ read_pool (p, n, level) ->
+ read_seed_file(),
+ random_poll() ->
+ read_random_source(..., ..., GCRY_STRONG_RANDOM),
+ read_random_source(... , ..., , -1 ) (note: -1) ->
+ slow_gather_fnc(..., ..., ..., level)
+ function pointer set by getfnc_gather_random() to
+ _gcry_rndlinux_gather_random() , which is here.
+ */
+
+
+ if (level == -1)
+ {
+ if (fd_configured == -1)
+ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0 );
+ fd = fd_configured;
+ if (fd == -1)
+ level = 1;
+ }
+
+
if (level >= 2)
{
if( fd_random == -1 )
- fd_random = open_device ( NAME_OF_DEV_RANDOM );
+ fd_random = open_device ( NAME_OF_DEV_RANDOM, 1 );
fd = fd_random;
}
- else
+ else if (level != -1)
{
if( fd_urandom == -1 )
- fd_urandom = open_device ( NAME_OF_DEV_URANDOM );
+ fd_urandom = open_device ( NAME_OF_DEV_URANDOM, 1 );
fd = fd_urandom;
}
/* Enter the read loop. */
delay = 0; /* Start with 0 seconds so that we do no block on the
first iteration and in turn call the progress function
before blocking. To give the OS a better chance to
return with something we will actually use 100ms. */
while (length)
{
fd_set rfds;
struct timeval tv;
int rc;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = delay;
tv.tv_usec = delay? 0 : 100000;
if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
{
@@ -160,25 +193,28 @@
}
do
{
int nbytes = length < sizeof(buffer)? length : sizeof(buffer);
n = read(fd, buffer, nbytes );
if( n >= 0 && n > nbytes )
{
log_error("bogus read from random device (n=%d)\n", n );
n = nbytes;
}
}
while( n == -1 && errno == EINTR );
if ( n == -1 )
log_fatal("read error on random device: %s\n", strerror(errno));
(*add)( buffer, n, origin );
length -= n;
}
memset(buffer, 0, sizeof(buffer) );
+ if (level == -1)
+ _gcry_rndlinux_gather_random(add, origin, orig_length, 1);
+
if (any_need_entropy)
_gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
return 0; /* success */
}