[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 <[email protected]> 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,id=@var{id},filename=@var{/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
