diff mbox series

VirtIO-RNG: Update default entropy source to `/dev/urandom`

Message ID 20190503154613.4192-1-kchamart@redhat.com
State New
Headers show
Series VirtIO-RNG: Update default entropy source to `/dev/urandom` | expand

Commit Message

Kashyap Chamarthy May 3, 2019, 3:46 p.m. UTC
When QEMU exposes a VirtIO-RNG device to the guest, that device needs a
source of entropy, and that source needs to be "non-blocking", like
`/dev/urandom`.  However, currently QEMU defaults to the problematic
`/dev/random`, which is "blocking" (as in, it waits until sufficient
entropy is available).

So change the entropy source to the recommended `/dev/urandom`.

Related discussion in these[1][2] past threads.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2018-06/msg08335.html
    -- "RNG: Any reason QEMU doesn't default to `/dev/urandom`?"
[2] https://lists.nongnu.org/archive/html/qemu-devel/2018-09/msg02724.html
    -- "[RFC] Virtio RNG: Consider changing the default entropy source to
       /dev/urandom"

Signed-off-by: Kashyap Chamarthy <kchamart@redhat.com>
---
 backends/rng-random.c | 2 +-
 qemu-options.hx       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

Comments

Richard Henderson May 7, 2019, 3:20 p.m. UTC | #1
On 5/3/19 8:46 AM, Kashyap Chamarthy wrote:
> When QEMU exposes a VirtIO-RNG device to the guest, that device needs a
> source of entropy, and that source needs to be "non-blocking", like
> `/dev/urandom`.  However, currently QEMU defaults to the problematic
> `/dev/random`, which is "blocking" (as in, it waits until sufficient
> entropy is available).
> 
> So change the entropy source to the recommended `/dev/urandom`.
> 
> Related discussion in these[1][2] past threads.
> 
> [1] https://lists.nongnu.org/archive/html/qemu-devel/2018-06/msg08335.html
>     -- "RNG: Any reason QEMU doesn't default to `/dev/urandom`?"
> [2] https://lists.nongnu.org/archive/html/qemu-devel/2018-09/msg02724.html
>     -- "[RFC] Virtio RNG: Consider changing the default entropy source to
>        /dev/urandom"
> 
> Signed-off-by: Kashyap Chamarthy <kchamart@redhat.com>
> ---
>  backends/rng-random.c | 2 +-
>  qemu-options.hx       | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)

I would also like to point out

  https://patchwork.ozlabs.org/project/qemu-devel/list/?series=97063
  "[PATCH v4 00/24] Add qemu_getrandom and ARMv8.5-RNG etc"

Which, if used in more rng backends, would remove direct use of either
/dev/urandom or /dev/random and instead be handled by one of the crypto
libraries against which we link.

Which in turn may be implemented by getrandom(2) instead of the legacy /dev/files.

Which would, I suppose, deprecate the file= option entirely.


r~


PS: I'm not sure what the difference between backends/rng* is supposed to be,
and whether that distinction is relevant.
Stefan Hajnoczi May 9, 2019, 1:53 p.m. UTC | #2
On Fri, May 03, 2019 at 05:46:12PM +0200, Kashyap Chamarthy wrote:
> When QEMU exposes a VirtIO-RNG device to the guest, that device needs a
> source of entropy, and that source needs to be "non-blocking", like
> `/dev/urandom`.  However, currently QEMU defaults to the problematic
> `/dev/random`, which is "blocking" (as in, it waits until sufficient
> entropy is available).
> 
> So change the entropy source to the recommended `/dev/urandom`.

Why is /dev/urandom "recommended"?

I understand the requirement for instant random numbers, but what about
the concerns about quality?  Have you decided that the consumers of
these random numbers are safe with /dev/urandom?

> 
> Related discussion in these[1][2] past threads.
> 
> [1] https://lists.nongnu.org/archive/html/qemu-devel/2018-06/msg08335.html
>     -- "RNG: Any reason QEMU doesn't default to `/dev/urandom`?"
> [2] https://lists.nongnu.org/archive/html/qemu-devel/2018-09/msg02724.html
>     -- "[RFC] Virtio RNG: Consider changing the default entropy source to
>        /dev/urandom"

Please include actual justification in the commit description instead of
linking to email threads that need to be read and interpreted.

Stefan
Daniel P. Berrangé May 9, 2019, 2:54 p.m. UTC | #3
On Thu, May 09, 2019 at 02:53:20PM +0100, Stefan Hajnoczi wrote:
> On Fri, May 03, 2019 at 05:46:12PM +0200, Kashyap Chamarthy wrote:
> > When QEMU exposes a VirtIO-RNG device to the guest, that device needs a
> > source of entropy, and that source needs to be "non-blocking", like
> > `/dev/urandom`.  However, currently QEMU defaults to the problematic
> > `/dev/random`, which is "blocking" (as in, it waits until sufficient
> > entropy is available).
> > 
> > So change the entropy source to the recommended `/dev/urandom`.
> 
> Why is /dev/urandom "recommended"?
> 
> I understand the requirement for instant random numbers, but what about
> the concerns about quality?  Have you decided that the consumers of
> these random numbers are safe with /dev/urandom?

The current random(4) man page says:

       The /dev/random interface is considered a legacy inter‐
       face, and /dev/urandom is preferred and  sufficient  in
       all use cases, with the exception of applications which
       require randomness during early boot  time;  for  these
       applications,   getrandom(2)   must  be  used  instead,
       because it will block until the entropy  pool  is  ini‐
       tialized.

"early boot" is a bit of an ill-defined term here, but I think in
general QEMU can reasonably be said to not be running in early boot.

In any case the newly proposed RNG backend should ultimately become
the preferred choice for mgmt apps:

  https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg02062.html

This new rng-builtin delegates to our crypto random APIs, which are
backed by GNUTLS, libgcrypt, getrandom (or Windows equiv), and
finally /dev/urandom as last ditch effort.

Regards,
Daniel
Kashyap Chamarthy May 9, 2019, 3:59 p.m. UTC | #4
On Thu, May 09, 2019 at 02:53:20PM +0100, Stefan Hajnoczi wrote:
> On Fri, May 03, 2019 at 05:46:12PM +0200, Kashyap Chamarthy wrote:
> > When QEMU exposes a VirtIO-RNG device to the guest, that device needs a
> > source of entropy, and that source needs to be "non-blocking", like
> > `/dev/urandom`.  However, currently QEMU defaults to the problematic
> > `/dev/random`, which is "blocking" (as in, it waits until sufficient
> > entropy is available).
> > 
> > So change the entropy source to the recommended `/dev/urandom`.
> 
> Why is /dev/urandom "recommended"?

Allow me to quote three expert sources.

(1) Let's start with Ted Ts'o, who is the author of the /dev/random.
    So it's as authoritative as it gets.  Ted Ts'o writes[*]:

    [quote]
      My recommendation is to just seed virtio-rng from /dev/urandom.
      Here's why.  /dev/urandom provides a cryptographic random number
      generator, and assuming it is adequately initialized, that should be
      *fine* for pretty much all practical purposes.  And on the sort of
      systems you would be using as a Host, there are enough hardware
      devices that /dev/urandom will be initialized very quickly --- in
      practice, well before any VM's will be started.
      
      Furthermore, all modern x86 systems have RDRAND by now, and on those
      systems, the host kernel will mix RDRAND output with CRNG before
      sending the random numbers out via getrandom(2) or /dev/urandom.
      
      From a guest perspective, you have to trust the Host system anyway.
      The host as the ability to read or modify arbitrary guest memory,
      including that used by the kernel.  The host can mess with the guest
      kernel before it's booted, or change the contents of the emulated hard
      drive.  So trusting that the host CPU has implemented RDRAND correctly
      isn't a stretch.  So even if the customer running the VM is a
      tin-foil-hatter who believes the NSA may have backdoored RDRAND and
      not have it be discovered or leaked out, in most cases, they aren't
      the sort of people who would want to use a cloud infrastructure.
      They're much more likely to want to use hardware which always stays
      under their personal control.
      
      And even if you *do* believe the NSA has somehow managed to sneak a
      backdoor into Intel CPU designs without it become public, that still
      means that you have to break the CRNG.  And practically speaking,
      assuming it's been initialized correctly, if you can break the CRNG,
      we've got much bigger problems, since that implies you can't trust the
      basic crypto primitives we use to secure our entire internet. 
    [/quote]

(2) The man pages of `random(4) and `urandom(4)`:

    Both the man pages say 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 their the "Usage" section:

       "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 randomness 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."

(3) And this widely-referred document (by Thomas Hühn, who describes
    himself as "interested in ... Cryptography, standing on the
    sidelines"):

      "Myths about /dev/urandom"
      https://www.2uo.de/myths-about-urandom/

    I'm not going to quote the relevant parts, but the document is
    competently written, and is well worth reading.

> I understand the requirement for instant random numbers, but what
> about the concerns about quality?  

I'm not a Crypto or RNG expert, but what precise "concerns" are these?
From my reading on this topic over the past several months, there are
some "sticky myths" in this area that Crypto / RNG experts have been
trying to debunk.  Refer to the earlier mentioned sources.

> Have you decided that the consumers of these random numbers are safe
> with /dev/urandom?

I didn't unilaterally decide it, but am relying on the expert sources
that I mentioned earlier.

In all likelihood you know this, but just as a refresher, there are
_two_ cases to distinguish w.r.t random numbers in QEMU:

  (a) When QEMU needs a random number, the entropy source it chooses.
      IIUC, here QEMU defers to GnuTLS, which uses getrandom(2), which
      in turn uses '/dev/urandom' as its entropy source; if getrandom(2)
      isn't available, GnuTLS uses `/dev/urandom` anyway.
  
  (b) When QEMU exposes a VirtIO-RNG device to the guest, the entropy
  source of that device.

This patch is changing the default of case (b).

> > Related discussion in these[1][2] past threads.
> > 
> > [1] https://lists.nongnu.org/archive/html/qemu-devel/2018-06/msg08335.html
> >     -- "RNG: Any reason QEMU doesn't default to `/dev/urandom`?"
> > [2] https://lists.nongnu.org/archive/html/qemu-devel/2018-09/msg02724.html
> >     -- "[RFC] Virtio RNG: Consider changing the default entropy source to
> >        /dev/urandom"
> 
> Please include actual justification in the commit description instead of
> linking to email threads that need to be read and interpreted.

Sure, will do.  I normally bear that in mind, but missed to do it here.
I'll send a v2 by quoting the relevant parts from the
random(4)|urandom(4) man pages.

[*] http://lists.katacontainers.io/pipermail/kata-dev/2018-September/000459.html
    [kata-dev] /dev/urandom or /dev/random
diff mbox series

Patch

diff --git a/backends/rng-random.c b/backends/rng-random.c
index e2a49b0571d79eab335d5a74841d92c50a727b6a..eff36ef14084bccaad1eabe952e2cf6ffa9a2529 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -112,7 +112,7 @@  static void rng_random_init(Object *obj)
                             rng_random_set_filename,
                             NULL);
 
-    s->filename = g_strdup("/dev/random");
+    s->filename = g_strdup("/dev/urandom");
     s->fd = -1;
 }
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 51802cbb266a208d70989c4f0ab3317a76edc1ea..a525609149e4d0e4bb60959f029a1a16eb36900d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4276,7 +4276,7 @@  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}.
+entropy from and if omitted defaults to @option{/dev/urandom}.
 
 @item -object rng-egd,id=@var{id},chardev=@var{chardevid}