Browse files

kvm tools: use /dev/random in virtio-rng

hpa explained it way better than I ever could:

  On 11/15/2012 04:13 PM, H. Peter Anvin wrote:
  >> In tools/kvm, you are currently using /dev/urandom as a source for
  >> virtio-rng.  virtio-rng is expected to provide entropic content, as
  >> the PRNG side of the force can be run in the guest itself.

  On 11/15/2012 01:49 PM, Sasha Levin wrote:
  > I was under the impression that by supplying /dev/urandom from the
  > host, which is *outside* the guest, this is equivalent to completely
  > random data for the guest since the guest cannot possibly calculate
  > the random data by observing it's own actions.
  > I guess I was wrong on that? If so I'll fix it as you've suggested.

  It is unpredictable, but not entropic.  Those are different things.
  Consider a PRNG built by AES-encrypting a counter with a random key
  (the seed).  If it is properly randomly seeded, the first 16 bytes
  would be entropic.  However, the second 16 bytes would be completely
  determined by the first ones and thus add no entropy, even though to
  be able to predict them you would have to invert AES via a
  known-plaintext attack.

  That is why they are different metrics.

  We already have a PRNG in guest space, so there is no reason to burn
  more CPU time running one in host space to fake-seed the one in guest

Suggested-by: H. Peter Anvin <>
Signed-off-by: Sasha Levin <>
Signed-off-by: Pekka Enberg <>
  • Loading branch information...
1 parent a6d404d commit 10ed0ae7373128917f704804f861d4c4cec25f25 @sashalevin sashalevin committed with Nov 16, 2012
Showing with 4 additions and 2 deletions.
  1. +4 −2 tools/kvm/virtio/rng.c
6 tools/kvm/virtio/rng.c
@@ -61,11 +61,13 @@ static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
static bool virtio_rng_do_io_request(struct kvm *kvm, struct rng_dev *rdev, struct virt_queue *queue)
struct iovec iov[VIRTIO_RNG_QUEUE_SIZE];
- unsigned int len = 0;
+ ssize_t len = 0;
u16 out, in, head;
head = virt_queue__get_iov(queue, iov, &out, &in, kvm);
len = readv(rdev->fd, iov, in);
+ if (len < 0 && errno == EAGAIN)
+ len = 0;
virt_queue__set_used_elem(queue, head, len);
@@ -161,7 +163,7 @@ int virtio_rng__init(struct kvm *kvm)
if (rdev == NULL)
return -ENOMEM;
- rdev->fd = open("/dev/urandom", O_RDONLY);
+ rdev->fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
if (rdev->fd < 0) {
r = rdev->fd;
goto cleanup;

0 comments on commit 10ed0ae

Please sign in to comment.