forked from pool/libgcrypt
162 lines
5.3 KiB
Diff
162 lines
5.3 KiB
Diff
|
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.5.2/random/random-csprng.c
|
||
|
===================================================================
|
||
|
--- libgcrypt-1.5.2.orig/random/random-csprng.c
|
||
|
+++ libgcrypt-1.5.2/random/random-csprng.c
|
||
|
@@ -827,7 +827,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.5.2/random/random-fips.c
|
||
|
===================================================================
|
||
|
--- libgcrypt-1.5.2.orig/random/random-fips.c
|
||
|
+++ libgcrypt-1.5.2/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.5.2/random/rndlinux.c
|
||
|
===================================================================
|
||
|
--- libgcrypt-1.5.2.orig/random/rndlinux.c
|
||
|
+++ libgcrypt-1.5.2/random/rndlinux.c
|
||
|
@@ -36,7 +36,8 @@
|
||
|
#include "g10lib.h"
|
||
|
#include "rand-internal.h"
|
||
|
|
||
|
-static int open_device ( const char *name );
|
||
|
+static int open_device ( const char *name, int fatal );
|
||
|
+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed"
|
||
|
|
||
|
|
||
|
static int
|
||
|
@@ -57,13 +58,17 @@ set_cloexec_flag (int fd)
|
||
|
* 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",
|
||
|
@@ -92,10 +97,12 @@ _gcry_rndlinux_gather_random (void (*add
|
||
|
{
|
||
|
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;
|
||
|
@@ -110,16 +117,42 @@ _gcry_rndlinux_gather_random (void (*add
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
@@ -187,6 +220,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);
|
||
|
|