qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] RNG: Any reason QEMU doesn't default to `/dev/urandom`?


From: Kashyap Chamarthy
Subject: Re: [Qemu-devel] RNG: Any reason QEMU doesn't default to `/dev/urandom`?
Date: Fri, 21 Sep 2018 15:28:20 +0200
User-agent: Mutt/1.10.1 (2018-07-13)

[Reviving this thread; and Ccing Nikos Mavrogiannopoulos of GnuTLS, a
retaining the full context.]

A clarification inline about the source of entropy for GnuTLS vs.
libgcrypt.

On Thu, Jun 28, 2018 at 01:22:24PM +0100, Daniel P. Berrangé wrote:
> On Thu, Jun 28, 2018 at 02:15:14PM +0200, Markus Armbruster wrote:
> > Kashyap Chamarthy <address@hidden> writes:
> > 
> > > QEMU still defaults to /dev/random as entropy source.  Any reason why
> > > not default to /dev/urandom?
> > >
> > > The other day Dan Berrangé explained elsewhere that /dev/urandom is
> > > recommended -- as it is non-blocking; and doesn't have the same
> > > limitations of /dev/random, which is a legacy interface.  (And other
> > > applications[*] are any way overriding the QEMU default to
> > > /dev/urandom.)
> > >
> > > `random(4)` says the following about the blocking nature of /dev/random:
> > >
> > >        The /dev/random device is a legacy interface which dates back to
> > >        a time where the cryptographic primitives used in the
> > >        implementation of /dev/urandom were not widely trusted.  It will
> > >        return random bytes only within the estimated number of bits of
> > >        fresh noise in the entropy pool, blocking if necessary.
> > >        /dev/random is suitable for applications  that  need high quality
> > >        randomness, and can afford indeterminate delays.
> > >
> > > And its "Usage" section says:
> > >
> > >        The  /dev/random  interface is considered a legacy interface, and
> > >        /dev/urandom is preferred and sufficient in all use cases, with
> > >        the exception of applications which require ran‐ domness during
> > >        early boot time; for these applications, getrandom(2) must be
> > >        used instead, because it will block until the entropy pool is
> > >        initialized.
> > >
> > >        If a seed file is saved across reboots as recommended below (all
> > >        major Linux distributions have done this since 2000 at least),
> > >        the output  is  cryptographically  secure  against attackers
> > >        without local root access as soon as it is reloaded in the boot
> > >        sequence, and perfectly adequate for network encryption session
> > >        keys.  Since reads from /dev/random may block, users will usually
> > >        want to open it in nonblocking mode (or perform a read with
> > >        timeout), and provide some sort of user notification if the
> > >        desired entropy is  not  immedi‐ ately available.
> > >
> > > [*] E.g. libguestfs:
> > >     
> > > https://github.com/libguestfs/libguestfs/blob/master/lib/launch-direct.c#L592
> > 
> > There's also getrandom(2).
> > 
> > See random(7) for a comparison between getrandom(), /dev/urandom,
> > /dev/random.
> > 
> > As you wrote, Linux's /dev/random blocks when the kernel entropy pool
> > has been depleted, while /dev/urandom doesn't.  There are systems where
> > both devices behave exactly the same, or only /dev/random exists.
> > Trying /dev/urandom first, and /dev/random as fallback is simple and
> > works okay across a wide range of hosts.  That said, getrandom(2) or
> > getentropy(3) are even nicer when available.
> > 
> > I can see two uses of /dev/random in QEMU outside tests:
> > 
> > * crypto/random-platform.c
> > 
> >     int qcrypto_random_init(Error **errp)
> >     {
> >     #ifndef _WIN32
> >         /* TBD perhaps also add support for BSD getentropy / Linux
> >          * getrandom syscalls directly */
> >         fd = open("/dev/urandom", O_RDONLY);
> >         if (fd == -1 && errno == ENOENT) {
> >             fd = open("/dev/random", O_RDONLY);
> >         }
> > 
> >         if (fd < 0) {
> >             error_setg(errp, "No /dev/urandom or /dev/random found");
> >             return -1;
> >         }
> >     #else
> >     [...]
> >     #endif
> > 
> >         return 0;
> >     }
> > 
> >   Looks good to me.  Resolving the TBD would be nice.
> 
> FYI, crypto/random-platform.c will only ever get used if neither GNUTLS
> or GCrypt are available. So while I agree it would be nice to have a
> getrandom() impl, in practice it wouldn't be used, as we'll prefer the
> gcrypt/gnutls RNGs (which in turn usually use /dev/random or getrandom(),
> long with a crypto routine on top).

That last sentence seems incorrect.  Nikos clarified on IRC:

  - GnuTLS uses /dev/*urandom*/ (and not /dev/random), if getrandom(2) —
    which itself by default "draws entropy from the urandom source" — is
    not available.

  - However, libgcrypt (from GnuPG) uses '/dev/random' by default.

> > * backends/rng-random.c
> > 
> >     static void rng_random_init(Object *obj)
> >     {
> >         RngRandom *s = RNG_RANDOM(obj);
> > 
> >         object_property_add_str(obj, "filename",
> >                                 rng_random_get_filename,
> >                                 rng_random_set_filename,
> >                                 NULL);
> > 
> >         s->filename = g_strdup("/dev/random");
> >         s->fd = -1;
> >     }
> > 
> >    This is TYPE_RNG_RANDOM's instance_init() method.  Doesn't look so
> >    good, but it's "only" a default.
> > 
> >    What TYPE_RNG_RANDOM's intended use?  The manual suggests "backend
> >    for virtio-rng":
> > 
> >     @item -object rng-random,address@hidden,address@hidden/dev/random}
> > 
> >     Creates a random number generator backend which obtains entropy from
> >     a device on the host. The @option{id} parameter is a unique ID that
> >     will be used to reference this entropy backend from the 
> > @option{virtio-rng}
> >     device. The @option{filename} parameter specifies which file to obtain
> >     entropy from and if omitted defaults to @option{/dev/random}.
> > 
> > Regardless of other considerations, duplicating something as hairy as
> > getting high-quality random numbers from the host in a portable manner
> > is a Bad Idea.
> 
> We could change semantics so that when 'filename' is not given, we default
> to using the qcrypto_random_bytes API. It would, however, mean we would
> be pulling random bytes via gnutls in most deployments. This is still
> secure of course, since gnults provides cryptographically strong bytes.
> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
> 

-- 
/kashyap



reply via email to

[Prev in Thread] Current Thread [Next in Thread]