Kashyap Chamarthy <kcham...@redhat.com> 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. * 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.