[Help-gnutls] Re: gnutls 1.2.6 and Mozilla Firefox compatibility problem

Simon Josefsson jas at extundo.com
Mon Sep 12 02:35:34 CEST 2005


Nikos Mavrogiannopoulos <nmav at gnutls.org> writes:

> On Saturday 10 September 2005 18:18, Simon Josefsson wrote:
>
>> > The problem seems to be libgcrypt's random generator. As far as I
>> > understand when you fork() the random generator is on the same state for
>> > every children. That's why the server produces the same session ID in the
>> > second process.
>> > I am not really sure about it, and I don't know how to overcome this,
>> > that's why I crosspost to gcrypt-devel as well.
>> One solution is that we switch to the random number handling that is
>> implemented when --enable-nettle is given to a GnuTLS build.  Then
>> GnuTLS will read (on GNU/Linux) from /dev/urandom for pseudo-random
>> data and nonces, and from /dev/random for random data.
>
> The problem with this is that a gnutls server will depleat /dev/random (we 
> need to generate a master secret for each session), thus the server will be 
> most of the time blocked waiting for input for /dev/random.

I see.  But isn't it worse to use master secrets based on poor random
data?  The kernel block the read for a reason, after all.

I don't see how libgcrypt is in a better position to always give out
randomness than the kernel is.  Also, I think the current use of
libgcrypt's randomness functions by GnuTLS for TLS master secret is
equivalent to /dev/urandom, not /dev/random.  And /dev/urandom never
block, as far as I know.

I think we should change the GnuTLS default to read from /dev/urandom
for pseudo-random data like TLS master secrets.  Unless there is a
simple way to make libgcrypt work after fork.

I'm talking about GNU/Linux here, but hopefully other systems has
similar devices.  m4/gc_random contain the following:

  # Devices with randomness.
  # FIXME: Are these the best defaults?
  case "${target}" in
    *-openbsd*)
	NAME_OF_RANDOM_DEVICE="/dev/srandom"
	NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/prandom"
	NAME_OF_NONCE_DEVICE="/dev/urandom"
        ;;

    *-netbsd*)
	NAME_OF_RANDOM_DEVICE="/dev/srandom"
	NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom"
	NAME_OF_NONCE_DEVICE="/dev/urandom"
        ;;

    *-solaris* | *-irix* | *-dec-osf* )
	NAME_OF_RANDOM_DEVICE="/dev/random"
	NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/random"
	NAME_OF_NONCE_DEVICE="/dev/random"
        ;;

    *)
	NAME_OF_RANDOM_DEVICE="/dev/random"
	NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom"
	NAME_OF_NONCE_DEVICE="/dev/urandom"
        ;;
  esac

Again, if there is a system that doesn't have these devices, it is
possible to build with --enable-random-device=/var/run/my.random.fifo
to make GnuTLS read randomness from somewhere else.  Perhaps we could
even ship with a small tool that create a fifo and uses libgcrypt to
feed it with randomness.  That tool should be simple to write.

Of course, the libgcrypt approach should be available too, through
build flags.  But unless someone explains how we should fix the fork
problem, I think we should make the default /dev/*random and document
the libgcrypt/fork issue.

What do you think?

>> Alternatively, GnuTLS could use an internal PRNG, and we could add an
>> API to seed it.
> The problem with internal PRNGs is that they are not thread safe (see 
> libgcrypt's PRNG). 

The code could check the PID and re-seed the PRNG if it changes, every
time random data is needed.  I don't think this is a robust solution
though.

Thanks,
Simon





More information about the Gnutls-help mailing list