3
0
forked from pool/libgcrypt
libgcrypt/libgcrypt-1.5.0-etc_gcrypt_rngseed-symlink.diff

170 lines
5.8 KiB
Diff
Raw Normal View History

From: draht@suse.com
Subject: /etc/gcrypt/rngseed symlink
logic error in evaluation of routine to open /dev/{u,}random or
/etc/gcrypt/rngseed (open_device()) causes abort() in cases where
do_randomize(nbytes, level) is called with level == 1
(GCRY_STRONG_RANDOM).
References: bnc#724841
https://bugzilla.novell.com/show_bug.cgi?id=724841
---
random/random-csprng.c | 2 +-
random/random-fips.c | 10 +++++-----
random/rndlinux.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
3 files changed, 48 insertions(+), 12 deletions(-)
Index: libgcrypt-1.6.0/random/random-csprng.c
===================================================================
--- libgcrypt-1.6.0.orig/random/random-csprng.c
+++ libgcrypt-1.6.0/random/random-csprng.c
@@ -832,7 +832,7 @@ read_seed_file (void)
* 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;
Index: libgcrypt-1.6.0/random/random-fips.c
===================================================================
--- libgcrypt-1.6.0.orig/random/random-fips.c
+++ libgcrypt-1.6.0/random/random-fips.c
@@ -27,10 +27,10 @@
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
@@ -562,7 +562,7 @@ get_entropy (size_t nbytes)
#if USE_RNDLINUX
rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0,
X931_AES_KEYLEN,
- GCRY_VERY_STRONG_RANDOM);
+ -1);
#elif USE_RNDW32
do
{
Index: libgcrypt-1.6.0/random/rndlinux.c
===================================================================
--- libgcrypt-1.6.0.orig/random/rndlinux.c
+++ libgcrypt-1.6.0/random/rndlinux.c
@@ -36,7 +36,8 @@
#include "g10lib.h"
#include "rand-internal.h"
-static int open_device (const char *name, int retry);
+static int open_device (const char *name, int retry, int fatal);
+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed"
static int
@@ -59,7 +60,7 @@ set_cloexec_flag (int fd)
* a fatal error but retries until it is able to reopen the device.
*/
static int
-open_device (const char *name, int retry)
+open_device (const char *name, int retry, int fatal)
{
int fd;
@@ -77,8 +78,11 @@ open_device (const char *name, int retry
select (0, NULL, NULL, NULL, &tv);
goto again;
}
- 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",
@@ -111,11 +115,13 @@ _gcry_rndlinux_gather_random (void (*add
{
static int fd_urandom = -1;
static int fd_random = -1;
+ static int fd_configured = -1;
static unsigned char ever_opened;
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;
@@ -153,20 +159,46 @@ _gcry_rndlinux_gather_random (void (*add
that we always require the device to be existent but want a more
graceful behaviour if the rarely needed close operation has been
used and the device needs to be re-opened later. */
+
+ /* 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, 0);
+ fd = fd_configured;
+ if (fd == -1)
+ level = 1;
+ }
+
+
if (level >= 2)
{
if (fd_random == -1)
{
- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1));
+ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1);
ever_opened |= 1;
}
fd = fd_random;
}
- else
+ else if (level != -1)
{
if (fd_urandom == -1)
{
- fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2));
+ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1);
ever_opened |= 2;
}
fd = fd_urandom;
@@ -242,6 +274,9 @@ _gcry_rndlinux_gather_random (void (*add
}
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);