Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Il 30/10/2012 22:11, H. Peter Anvin ha scritto: What I said that passing /dev/hwrng or rdrand would: - not make /dev/random with virtio-rng-pci worse than without It wouldn't, but it would make virtio-rng-pci a potential noop on a system where it could genuinely do better. True, but it can be fixed later without changing the guest hardware. It will just perform better, transparently. - make migration working - avoiding denial of service for the host's /dev/random However, it means that if there is an rngd-readable source on the host (e.g. TPM, DRNG) then the guest cannot take advantage of it; Right. A DRNG backend for virtio-rng-pci however can easily be implemented in QEMU. In this case you do have a slowish roundtrip to the host, but only if you need to migrate to older hosts (hopefully not a concern in smaller deployments---or in a few years). Related to this, rdrand's entropy content in the worst case will be only 1/255th of the data it produces: Intel documents that one 256-bit seed will result in up to 1022 64-bit random numbers. Yet, it is good enough to drive rngd. Would it make sense for QEMU to implement the same kind of stretching of /dev/random data, to avoid depleting the host's entropy pool too fast? Furthermore, you are in many ways still causing a DoS on the host, since you are eating up entropy that would otherwise be fed into /dev/random. So there are cases where the situation is much worse with /dev/hwrng than with /dev/random. How is it worse, at least from the host point of view? At least the entropy bits collected by the kernel will remain untouched. From the guest point of view it doesn't have to be too good, as long as it's not /dev/urandom. If you know you won't run any task that requires /dev/random on the host, and/or you somehow trust the guests, you certainly can pass it to the guests and disable the test in rngd. However, the same configuration needs to be applied to all hosts, because the test-disabled feature bit must not go from 1 to 0 over migration. Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On 10/31/2012 12:29 AM, Paolo Bonzini wrote: Related to this, rdrand's entropy content in the worst case will be only 1/255th of the data it produces: Intel documents that one 256-bit seed will result in up to 1022 64-bit random numbers. Yet, it is good enough to drive rngd. Would it make sense for QEMU to implement the same kind of stretching of /dev/random data, to avoid depleting the host's entropy pool too fast? Absolutely not; in fact, we have to do data reduction in rngd for exactly this reason (and a Qemu backend would have to do the same). There is a new RDSEED instruction in newer CPUs to correct this. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Il 31/10/2012 15:15, H. Peter Anvin ha scritto: Related to this, rdrand's entropy content in the worst case will be only 1/255th of the data it produces: Intel documents that one 256-bit seed will result in up to 1022 64-bit random numbers. Yet, it is good enough to drive rngd. Would it make sense for QEMU to implement the same kind of stretching of /dev/random data, to avoid depleting the host's entropy pool too fast? Absolutely not; in fact, we have to do data reduction in rngd for exactly this reason (and a Qemu backend would have to do the same). There is a new RDSEED instruction in newer CPUs to correct this. Ok, thanks. At least I asked. :) Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Il 30/10/2012 05:43, H. Peter Anvin ha scritto: Let me be more specific. First of all, feeding /dev/urandom to the guest is dangerous -- you are feeding it PRNG contents but telling it that it is real entropy. This is a security hole. Second of all, you're doing something pointless: you are still exhausting the entropy pool on the host at the same rate, and all you end up with is something that isn't what you want. You still have the same DoS on the host /dev/random that you're worried about. Third, you're doing something inefficient: you're running a PRNG in the host which could be run more efficiently in guest space. Either you're not reading what I wrote, or you're confusing me with someone else. I *never* mentioned passing /dev/urandom, and in fact I explained to Anthony that it is wrong. Please take a look at http://permalink.gmane.org/gmane.comp.emulators.qemu/178123 What I said that passing /dev/hwrng or rdrand would: - not make /dev/random with virtio-rng-pci worse than without - make migration working - avoiding denial of service for the host's /dev/random From an Intel perspective I guess I should be happy, as it functionally would mean that unless you have RDRAND in the host you're insecure, but I'd much rather see the Right Thing done. :) Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On 10/30/2012 02:05 AM, Paolo Bonzini wrote: Either you're not reading what I wrote, or you're confusing me with someone else. My apologies, you are indeed correct. I misinterpreted your emails, probably because I got you confused with someone else. I *never* mentioned passing /dev/urandom, and in fact I explained to Anthony that it is wrong. Please take a look at http://permalink.gmane.org/gmane.comp.emulators.qemu/178123 What I said that passing /dev/hwrng or rdrand would: - not make /dev/random with virtio-rng-pci worse than without It wouldn't, but it would make virtio-rng-pci a potential noop on a system where it could genuinely do better. - make migration working - avoiding denial of service for the host's /dev/random However, it means that if there is an rngd-readable source on the host (e.g. TPM, DRNG) then the guest cannot take advantage of it; if it accesses /dev/random then it would be able to. This is particularly toxic if you turn off DRNG to the host in the name of migration; the DRNG is a very high bandwidth source which is processed directly by rngd since there is no point in doing a detour via /dev/hwrng in the kernel. As such, with your proposed version you would take one of the best possible situations and turn it into the worst possible situation. Furthermore, you are in many ways still causing a DoS on the host, since you are eating up entropy that would otherwise be fed into /dev/random. So there are cases where the situation is much worse with /dev/hwrng than with /dev/random. -hpa
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On (Fri) 26 Oct 2012 [13:24:06], Anthony Liguori wrote: H. Peter Anvin h...@zytor.com writes: On 10/26/2012 08:42 AM, Anthony Liguori wrote: Is /dev/random even appropriate to feed rngd? rngd needs _a lot_ of entropy to even start working. Its randomness test works in groups of 2 bits. On a system without an hardware RNG, /dev/random can hardly produce 4000 bits/minute. This means a guest will not get any entropy boost for 5 minutes after it's started, even if we allow it to exhaust the parent's entropy. I don't know, but rng-random is a non-blocking backend so it can handle /dev/random, /dev/urandom, or /dev/hwrng. /dev/urandom is just plain *wrong*... it is feeding a PRNG into a PRNG which can best be described as masturbation and at worst as a cryptographic usage violation. I don't understand your logic here. From the discussions I've had, the quality of the randomness from a *well seeded* PRNG ought to be good enough to act as an entropy source within the guest. What qualifies as well seeded is a bit difficult to pin down with more specificity than kilobytes of data. I stayed away from /dev/urandom primarily because it's impossible to determine if it's well seeded or not making urandom dangerous to use. But using a PRNG makes sense to me when dealing with multiple guests. If you have a finite source of entropy in the host, using a PRNG to create unique entropy for each guest is certainly better than duplicating entropy. One solution could be to feed host's /dev/urandom to readers of guests' /dev/urandom. We could then pass the rare true entropy bits from host's /dev/hwrng or /dev/random to the guest via virtio-rng-pci's /dev/hwrng interface in the guest. If this is a valid idea (host /dev/urandom goes directly to guest's /dev/urandom), we would need some guest-side surgery, but it shouldn't be huge work, and would remove several bottlenecks. Is this a very crazy idea? Amit
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On (Fri) 26 Oct 2012 [09:43:34], Anthony Liguori wrote: Hi, This series implements the backend and frontend infrastructure for virtio-rng. This is similar to previous series sent out by both Amit and myself although it has been trimmed down considerably. In terms of backends, a file and EGD backend are supported. The file defaults to /dev/random based on the feedback from Peter. It's still possible to support /dev/urandom though as an entropy source by overriding the file name. I think this series is ready to merge. I have a small diff to this series that I had merged in mine. Please apply to your tree as well. (Gets rid of savevm/loadvm complexities by using the new virtqueue_get_avail_bytes(), fixes typos/whitespace in rng.h) diff --git b/hw/virtio-rng.c a/hw/virtio-rng.c index b7fb5e9..290b2b6 100644 --- b/hw/virtio-rng.c +++ a/hw/virtio-rng.c @@ -22,14 +22,9 @@ typedef struct VirtIORNG { /* Only one vq - guest puts buffer(s) on it when it needs entropy */ VirtQueue *vq; -VirtQueueElement elem; -/* Config data for the device -- currently only chardev */ VirtIORNGConf *conf; -/* Whether we've popped a vq element into 'elem' above */ -bool popped; - RngBackend *rng; } VirtIORNG; @@ -42,23 +37,19 @@ static bool is_guest_ready(VirtIORNG *vrng) return false; } -static size_t pop_an_elem(VirtIORNG *vrng) +static size_t get_request_size(VirtQueue *vq) { -size_t size; +unsigned int in, out; -if (!vrng-popped !virtqueue_pop(vrng-vq, vrng-elem)) { -return 0; -} -vrng-popped = true; - -size = iov_size(vrng-elem.in_sg, vrng-elem.in_num); -return size; +virtqueue_get_avail_bytes(vq, in, out); +return in; } /* Send data from a char device over to the guest */ static void chr_read(void *opaque, const void *buf, size_t size) { VirtIORNG *vrng = opaque; +VirtQueueElement elem; size_t len; int offset; @@ -68,27 +59,16 @@ static void chr_read(void *opaque, const void *buf, size_t size) offset = 0; while (offset size) { -if (!pop_an_elem(vrng)) { +if (!virtqueue_pop(vrng-vq, elem)) { break; } -len = iov_from_buf(vrng-elem.in_sg, vrng-elem.in_num, +len = iov_from_buf(elem.in_sg, elem.in_num, 0, buf + offset, size - offset); offset += len; -virtqueue_push(vrng-vq, vrng-elem, len); -vrng-popped = false; +virtqueue_push(vrng-vq, elem, len); } virtio_notify(vrng-vdev, vrng-vq); - -/* - * Lastly, if we had multiple elems queued by the guest, and we - * didn't have enough data to fill them all, indicate we want more - * data. - */ -len = pop_an_elem(vrng); -if (len) { -rng_backend_request_entropy(vrng-rng, size, chr_read, vrng); -} } static void handle_input(VirtIODevice *vdev, VirtQueue *vq) @@ -96,7 +76,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq) VirtIORNG *vrng = DO_UPCAST(VirtIORNG, vdev, vdev); size_t size; -size = pop_an_elem(vrng); +size = get_request_size(vq); if (size) { rng_backend_request_entropy(vrng-rng, size, chr_read, vrng); } @@ -112,23 +92,6 @@ static void virtio_rng_save(QEMUFile *f, void *opaque) VirtIORNG *vrng = opaque; virtio_save(vrng-vdev, f); - -qemu_put_byte(f, vrng-popped); -if (vrng-popped) { -int i; - -qemu_put_be32(f, vrng-elem.index); - -qemu_put_be32(f, vrng-elem.in_num); -for (i = 0; i vrng-elem.in_num; i++) { -qemu_put_be64(f, vrng-elem.in_addr[i]); -} - -qemu_put_be32(f, vrng-elem.out_num); -for (i = 0; i vrng-elem.out_num; i++) { -qemu_put_be64(f, vrng-elem.out_addr[i]); -} -} } static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id) @@ -139,30 +102,6 @@ static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id) return -EINVAL; } virtio_load(vrng-vdev, f); - -vrng-popped = qemu_get_byte(f); -if (vrng-popped) { -int i; - -vrng-elem.index = qemu_get_be32(f); - -vrng-elem.in_num = qemu_get_be32(f); -g_assert(vrng-elem.in_num VIRTQUEUE_MAX_SIZE); -for (i = 0; i vrng-elem.in_num; i++) { -vrng-elem.in_addr[i] = qemu_get_be64(f); -} - -vrng-elem.out_num = qemu_get_be32(f); -g_assert(vrng-elem.out_num VIRTQUEUE_MAX_SIZE); -for (i = 0; i vrng-elem.out_num; i++) { -vrng-elem.out_addr[i] = qemu_get_be64(f); -} - -virtqueue_map_sg(vrng-elem.in_sg, vrng-elem.in_addr, - vrng-elem.in_num, 1); -virtqueue_map_sg(vrng-elem.out_sg, vrng-elem.out_addr, - vrng-elem.out_num, 0); -} return 0; } @@ -195,7 +134,6 @@ VirtIODevice *virtio_rng_init(DeviceState *dev, VirtIORNGConf
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Il 26/10/2012 22:29, H. Peter Anvin ha scritto: This is surreal. Output from /dev/hwrng turns into output for /dev/random... it us guaranteed worse; period, end of story. Isn't that exactly what happens in bare-metal? hwrng - rngd - random. Instead here we'd have, host hwrng - virtio-rng-pci - guest hwrng - guest rngd - guest random. The only difference is that you paravirtualize access to the host hwrng to a) distribute entropy to multiple guests; b) support migration across hosts with different CPUs and hardware. First, hwrng is only one of the sources used by rngd. It can also (currently) use RDRAND or TPM; additional sources are likely to be added in the future. Second, the harvesting of environmental noise -- timings -- is not as good in a VM as on plain hardware, so for the no-hwrng case it is better for this to be done in the host than in the VM. Neither of these make /dev/random with virtio-rng-pci worse than without (as would be the case if you fed /dev/urandom). And migration works. This, and avoiding denial of service for the host's /dev/random, is all I care about at this time. There is always time to change defaults to something better. Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On 10/28/2012 11:23 PM, Amit Shah wrote: One solution could be to feed host's /dev/urandom to readers of guests' /dev/urandom. We could then pass the rare true entropy bits from host's /dev/hwrng or /dev/random to the guest via virtio-rng-pci's /dev/hwrng interface in the guest. If this is a valid idea (host /dev/urandom goes directly to guest's /dev/urandom), we would need some guest-side surgery, but it shouldn't be huge work, and would remove several bottlenecks. Is this a very crazy idea? It's not crazy, it's just pointless. You're doing a completely unnecessary hypercall to run the PRNG in host space. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On 10/29/2012 01:45 AM, Paolo Bonzini wrote: First, hwrng is only one of the sources used by rngd. It can also (currently) use RDRAND or TPM; additional sources are likely to be added in the future. Second, the harvesting of environmental noise -- timings -- is not as good in a VM as on plain hardware, so for the no-hwrng case it is better for this to be done in the host than in the VM. Neither of these make /dev/random with virtio-rng-pci worse than without (as would be the case if you fed /dev/urandom). And migration works. This, and avoiding denial of service for the host's /dev/random, is all I care about at this time. There is always time to change defaults to something better. Your logic are roughly on the level with the people who caused the Debian bug. You are proposing something utterly reckless. Sorry, please stop. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On 10/29/2012 01:45 AM, Paolo Bonzini wrote: Il 26/10/2012 22:29, H. Peter Anvin ha scritto: This is surreal. Output from /dev/hwrng turns into output for /dev/random... it us guaranteed worse; period, end of story. Isn't that exactly what happens in bare-metal? hwrng - rngd - random. Instead here we'd have, host hwrng - virtio-rng-pci - guest hwrng - guest rngd - guest random. The only difference is that you paravirtualize access to the host hwrng to a) distribute entropy to multiple guests; b) support migration across hosts with different CPUs and hardware. First, hwrng is only one of the sources used by rngd. It can also (currently) use RDRAND or TPM; additional sources are likely to be added in the future. Second, the harvesting of environmental noise -- timings -- is not as good in a VM as on plain hardware, so for the no-hwrng case it is better for this to be done in the host than in the VM. Neither of these make /dev/random with virtio-rng-pci worse than without (as would be the case if you fed /dev/urandom). And migration works. This, and avoiding denial of service for the host's /dev/random, is all I care about at this time. There is always time to change defaults to something better. Let me be more specific. First of all, feeding /dev/urandom to the guest is dangerous -- you are feeding it PRNG contents but telling it that it is real entropy. This is a security hole. Second of all, you're doing something pointless: you are still exhausting the entropy pool on the host at the same rate, and all you end up with is something that isn't what you want. You still have the same DoS on the host /dev/random that you're worried about. Third, you're doing something inefficient: you're running a PRNG in the host which could be run more efficiently in guest space. From an Intel perspective I guess I should be happy, as it functionally would mean that unless you have RDRAND in the host you're insecure, but I'd much rather see the Right Thing done. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
This series implements the backend and frontend infrastructure for virtio-rng. This is similar to previous series sent out by both Amit and myself although it has been trimmed down considerably. In terms of backends, a file and EGD backend are supported. The file defaults to /dev/random based on the feedback from Peter. It's still possible to support /dev/urandom though as an entropy source by overriding the file name. I think this series is ready to merge. Is /dev/random even appropriate to feed rngd? rngd needs _a lot_ of entropy to even start working. Its randomness test works in groups of 2 bits. On a system without an hardware RNG, /dev/random can hardly produce 4000 bits/minute. This means a guest will not get any entropy boost for 5 minutes after it's started, even if we allow it to exhaust the parent's entropy. At this point, /dev/hwrng (or rdrand) seems just as good as /dev/random as a source for virtio-rng (and even better, it is not starved as easily). I think RngBackend is over-engineered. What other backends do you plan on adding? Maybe rdrand, but that's just a chardev---so why isn't this enough: -chardev file,source=on,path=/dev/hwrng,id=chr0 -device virtio-rng-pci,file=chr0 -chardev rdrand,id=chr0 -device virtio-rng-pci,file=chr0 -chardev socket,host=localhost,port=1024,id=chr0 -device virtio-rng-pci,rng=chr0,egd=on (which I suggested in my reply to Amit)? Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Paolo Bonzini pbonz...@redhat.com writes: This series implements the backend and frontend infrastructure for virtio-rng. This is similar to previous series sent out by both Amit and myself although it has been trimmed down considerably. In terms of backends, a file and EGD backend are supported. The file defaults to /dev/random based on the feedback from Peter. It's still possible to support /dev/urandom though as an entropy source by overriding the file name. I think this series is ready to merge. Is /dev/random even appropriate to feed rngd? rngd needs _a lot_ of entropy to even start working. Its randomness test works in groups of 2 bits. On a system without an hardware RNG, /dev/random can hardly produce 4000 bits/minute. This means a guest will not get any entropy boost for 5 minutes after it's started, even if we allow it to exhaust the parent's entropy. I don't know, but rng-random is a non-blocking backend so it can handle /dev/random, /dev/urandom, or /dev/hwrng. It's just a matter of what the default is and I feel comfortable that if someone can provide a *concrete* demonstration of what the best default is, we can change it later on. At this point, /dev/hwrng (or rdrand) seems just as good as /dev/random as a source for virtio-rng (and even better, it is not starved as easily). I've been told that hwrng sources need to be passed through a whitening function in order to be suitable for PRNG generators. Since we expose a /dev/hwrng in the guest, perhaps this doesn't matter... I think RngBackend is over-engineered. What other backends do you plan on adding? Stefan Berger suggested a backend that uses a PRNG in FreeBL. That's probably the best default since it punts to a userspace library to deal with ensuring there's adequate whitening/entropy to start with. Maybe rdrand, but that's just a chardev---so why isn't this enough: -chardev file,source=on,path=/dev/hwrng,id=chr0 -device virtio-rng-pci,file=chr0 -chardev rdrand,id=chr0 -device virtio-rng-pci,file=chr0 -chardev socket,host=localhost,port=1024,id=chr0 -device virtio-rng-pci,rng=chr0,egd=on (which I suggested in my reply to Amit)? I don't like overloading chardev to representate any !block device backend which is what I fear we're doing here. EGD is more than just a dumb pipe of data too. It's got a way to query available entropy. I have a strong suspicion that over time, we'll add methods to virtio-rng to query available entropy. That would mean adding a backend specific ioctl to the chardev layer which is pretty ugly. The overhead of creating a separate backend to begin with is extremely small. We're talking about dozens of lines of code. So I don't see what the problem is. Regards, Anthony Liguori Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On 10/26/2012 08:42 AM, Anthony Liguori wrote: Is /dev/random even appropriate to feed rngd? rngd needs _a lot_ of entropy to even start working. Its randomness test works in groups of 2 bits. On a system without an hardware RNG, /dev/random can hardly produce 4000 bits/minute. This means a guest will not get any entropy boost for 5 minutes after it's started, even if we allow it to exhaust the parent's entropy. I don't know, but rng-random is a non-blocking backend so it can handle /dev/random, /dev/urandom, or /dev/hwrng. /dev/urandom is just plain *wrong*... it is feeding a PRNG into a PRNG which can best be described as masturbation and at worst as a cryptographic usage violation. /dev/hwrng is reasonable, in some ways; after all, the guest itself is expected to use rngd. There are, however, at least two problems: a) it means that the guest *has* to run rngd or a similar engine; if you have control over the guests it might be more efficient to run rngd in skip-test mode (I don't think that is currently implemented but it could/should be) and centralize all testing to the host. A skip-test mode would also allow rngd to forward-feed shorter blocks than 2500 bytes. b) if the host has no physical hwrng, /dev/hwrng will output nothing at all, which is worse than /dev/random in that situation. Stefan Berger suggested a backend that uses a PRNG in FreeBL. That's probably the best default since it punts to a userspace library to deal with ensuring there's adequate whitening/entropy to start with. We SHOULD NOT expose a PRNG here! It is the same fail as using /dev/urandom (but worse) The whole point is to inject actual entropy... a PRNG can (and typically will) just run in guest space. Maybe rdrand, but that's just a chardev---so why isn't this enough: -chardev file,source=on,path=/dev/hwrng,id=chr0 -device virtio-rng-pci,file=chr0 -chardev rdrand,id=chr0 -device virtio-rng-pci,file=chr0 -chardev socket,host=localhost,port=1024,id=chr0 -device virtio-rng-pci,rng=chr0,egd=on (which I suggested in my reply to Amit)? If you have rdrand you might just use it in the guest directly, unless you have a strong reason (migration?) not to do that. Either way, for rdrand you need whitening similar to what rngd is doing (for *rdseed* you do not, but rdseed is not shipping yet.) The startup issue is an interesting problem. If you have full control over the guest it might be best to simply inject some entropy into the guest on startup via the initramfs or a disk image; that has its own awkwardness too, of course. The one bit that could potentially be solved in Qemu would be an option to don't start the guest until X bytes of entropy have been gathered. Overall, I want to emphasize that we don't want to try solve generic problems in virtualization space... resource constraints on /dev/random is a generic host OS issue for example. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
H. Peter Anvin h...@zytor.com writes: On 10/26/2012 08:42 AM, Anthony Liguori wrote: Is /dev/random even appropriate to feed rngd? rngd needs _a lot_ of entropy to even start working. Its randomness test works in groups of 2 bits. On a system without an hardware RNG, /dev/random can hardly produce 4000 bits/minute. This means a guest will not get any entropy boost for 5 minutes after it's started, even if we allow it to exhaust the parent's entropy. I don't know, but rng-random is a non-blocking backend so it can handle /dev/random, /dev/urandom, or /dev/hwrng. /dev/urandom is just plain *wrong*... it is feeding a PRNG into a PRNG which can best be described as masturbation and at worst as a cryptographic usage violation. I don't understand your logic here. From the discussions I've had, the quality of the randomness from a *well seeded* PRNG ought to be good enough to act as an entropy source within the guest. What qualifies as well seeded is a bit difficult to pin down with more specificity than kilobytes of data. I stayed away from /dev/urandom primarily because it's impossible to determine if it's well seeded or not making urandom dangerous to use. But using a PRNG makes sense to me when dealing with multiple guests. If you have a finite source of entropy in the host, using a PRNG to create unique entropy for each guest is certainly better than duplicating entropy. Adding Ted T'so and a few others to CC in hopes that they can chime in here too. FWIW, none of this should affect this series being merged as it can use a variety of different inputs. But I would like to have a strong recommendation for what people should use (and make that default) so I'd really like to get a clear answer here. Regards, Anthony Liguori /dev/hwrng is reasonable, in some ways; after all, the guest itself is expected to use rngd. There are, however, at least two problems: a) it means that the guest *has* to run rngd or a similar engine; if you have control over the guests it might be more efficient to run rngd in skip-test mode (I don't think that is currently implemented but it could/should be) and centralize all testing to the host. A skip-test mode would also allow rngd to forward-feed shorter blocks than 2500 bytes. b) if the host has no physical hwrng, /dev/hwrng will output nothing at all, which is worse than /dev/random in that situation. Stefan Berger suggested a backend that uses a PRNG in FreeBL. That's probably the best default since it punts to a userspace library to deal with ensuring there's adequate whitening/entropy to start with. We SHOULD NOT expose a PRNG here! It is the same fail as using /dev/urandom (but worse) The whole point is to inject actual entropy... a PRNG can (and typically will) just run in guest space. Maybe rdrand, but that's just a chardev---so why isn't this enough: -chardev file,source=on,path=/dev/hwrng,id=chr0 -device virtio-rng-pci,file=chr0 -chardev rdrand,id=chr0 -device virtio-rng-pci,file=chr0 -chardev socket,host=localhost,port=1024,id=chr0 -device virtio-rng-pci,rng=chr0,egd=on (which I suggested in my reply to Amit)? If you have rdrand you might just use it in the guest directly, unless you have a strong reason (migration?) not to do that. Either way, for rdrand you need whitening similar to what rngd is doing (for *rdseed* you do not, but rdseed is not shipping yet.) The startup issue is an interesting problem. If you have full control over the guest it might be best to simply inject some entropy into the guest on startup via the initramfs or a disk image; that has its own awkwardness too, of course. The one bit that could potentially be solved in Qemu would be an option to don't start the guest until X bytes of entropy have been gathered. Overall, I want to emphasize that we don't want to try solve generic problems in virtualization space... resource constraints on /dev/random is a generic host OS issue for example. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
PRNGs don't create entropy. Period. The guest will run its own PRNG. Anthony Liguori aligu...@us.ibm.com wrote: H. Peter Anvin h...@zytor.com writes: On 10/26/2012 08:42 AM, Anthony Liguori wrote: Is /dev/random even appropriate to feed rngd? rngd needs _a lot_ of entropy to even start working. Its randomness test works in groups of 2 bits. On a system without an hardware RNG, /dev/random can hardly produce 4000 bits/minute. This means a guest will not get any entropy boost for 5 minutes after it's started, even if we allow it to exhaust the parent's entropy. I don't know, but rng-random is a non-blocking backend so it can handle /dev/random, /dev/urandom, or /dev/hwrng. /dev/urandom is just plain *wrong*... it is feeding a PRNG into a PRNG which can best be described as masturbation and at worst as a cryptographic usage violation. I don't understand your logic here. From the discussions I've had, the quality of the randomness from a *well seeded* PRNG ought to be good enough to act as an entropy source within the guest. What qualifies as well seeded is a bit difficult to pin down with more specificity than kilobytes of data. I stayed away from /dev/urandom primarily because it's impossible to determine if it's well seeded or not making urandom dangerous to use. But using a PRNG makes sense to me when dealing with multiple guests. If you have a finite source of entropy in the host, using a PRNG to create unique entropy for each guest is certainly better than duplicating entropy. Adding Ted T'so and a few others to CC in hopes that they can chime in here too. FWIW, none of this should affect this series being merged as it can use a variety of different inputs. But I would like to have a strong recommendation for what people should use (and make that default) so I'd really like to get a clear answer here. Regards, Anthony Liguori /dev/hwrng is reasonable, in some ways; after all, the guest itself is expected to use rngd. There are, however, at least two problems: a) it means that the guest *has* to run rngd or a similar engine; if you have control over the guests it might be more efficient to run rngd in skip-test mode (I don't think that is currently implemented but it could/should be) and centralize all testing to the host. A skip-test mode would also allow rngd to forward-feed shorter blocks than 2500 bytes. b) if the host has no physical hwrng, /dev/hwrng will output nothing at all, which is worse than /dev/random in that situation. Stefan Berger suggested a backend that uses a PRNG in FreeBL. That's probably the best default since it punts to a userspace library to deal with ensuring there's adequate whitening/entropy to start with. We SHOULD NOT expose a PRNG here! It is the same fail as using /dev/urandom (but worse) The whole point is to inject actual entropy... a PRNG can (and typically will) just run in guest space. Maybe rdrand, but that's just a chardev---so why isn't this enough: -chardev file,source=on,path=/dev/hwrng,id=chr0 -device virtio-rng-pci,file=chr0 -chardev rdrand,id=chr0 -device virtio-rng-pci,file=chr0 -chardev socket,host=localhost,port=1024,id=chr0 -device virtio-rng-pci,rng=chr0,egd=on (which I suggested in my reply to Amit)? If you have rdrand you might just use it in the guest directly, unless you have a strong reason (migration?) not to do that. Either way, for rdrand you need whitening similar to what rngd is doing (for *rdseed* you do not, but rdseed is not shipping yet.) The startup issue is an interesting problem. If you have full control over the guest it might be best to simply inject some entropy into the guest on startup via the initramfs or a disk image; that has its own awkwardness too, of course. The one bit that could potentially be solved in Qemu would be an option to don't start the guest until X bytes of entropy have been gathered. Overall, I want to emphasize that we don't want to try solve generic problems in virtualization space... resource constraints on /dev/random is a generic host OS issue for example. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. -- Sent from my mobile phone. Please excuse brevity and lack of formatting.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Il 26/10/2012 17:42, Anthony Liguori ha scritto: Maybe rdrand, but that's just a chardev---so why isn't this enough: -chardev file,source=on,path=/dev/hwrng,id=chr0 -device virtio-rng-pci,file=chr0 -chardev rdrand,id=chr0 -device virtio-rng-pci,file=chr0 -chardev socket,host=localhost,port=1024,id=chr0 -device virtio-rng-pci,rng=chr0,egd=on (which I suggested in my reply to Amit)? I don't like overloading chardev to representate any !block device backend which is what I fear we're doing here. Like -chardev msmouse you mean? ;) EGD is more than just a dumb pipe of data too. It's got a way to query available entropy. I have a strong suspicion that over time, we'll add methods to virtio-rng to query available entropy. That would mean adding a backend specific ioctl to the chardev layer which is pretty ugly. The overhead of creating a separate backend to begin with is extremely small. We're talking about dozens of lines of code. So I don't see what the problem is. If you just make rng-random take a chardev, I have no problem with the series. Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Il 26/10/2012 18:09, H. Peter Anvin ha scritto: a) it means that the guest *has* to run rngd or a similar engine; if you have control over the guests it might be more efficient to run rngd in skip-test mode (I don't think that is currently implemented but it could/should be) and centralize all testing to the host. A skip-test mode would also allow rngd to forward-feed shorter blocks than 2500 bytes. That would be something we can communicate via virtio-rng-pci feature bits. Perhaps /dev/hwrng could also expose a need-whitening property in sysfs. b) if the host has no physical hwrng, /dev/hwrng will output nothing at all, which is worse than /dev/random in that situation. Not really, it would just mean that the guest takes more time to gather entropy, just like if you had no virtio-rng-pci at all. If you have rdrand you might just use it in the guest directly, unless you have a strong reason (migration?) not to do that. Either way, for rdrand you need whitening similar to what rngd is doing (for *rdseed* you do not, but rdseed is not shipping yet.) Yes, migration is a good reason. The startup issue is an interesting problem. If you have full control over the guest it might be best to simply inject some entropy into the guest on startup via the initramfs or a disk image; that has its own awkwardness too, of course. The one bit that could potentially be solved in Qemu would be an option to don't start the guest until X bytes of entropy have been gathered. Overall, I want to emphasize that we don't want to try solve generic problems in virtualization space... resource constraints on /dev/random is a generic host OS issue for example. Yes, but the agreed solution right now is that programs should not ask for more than 32 bytes or so from /dev/random. Which means /dev/random is not a suitable backend for virtio-rng-pci as things stand now. Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
This is surreal. Output from /dev/hwrng turns into output for /dev/random... it us guaranteed worse; period, end of story. I don't know who the agreement is with, but it is ridiculous in this case. As far as the need whitening issue, I discussed that with Ted at Kernel Summit and we came up with an outline for what we can do to improve the current situation. It is challenging to deal with the patanoia crowd at the same time. Paolo Bonzini pbonz...@redhat.com wrote: Il 26/10/2012 18:09, H. Peter Anvin ha scritto: a) it means that the guest *has* to run rngd or a similar engine; if you have control over the guests it might be more efficient to run rngd in skip-test mode (I don't think that is currently implemented but it could/should be) and centralize all testing to the host. A skip-test mode would also allow rngd to forward-feed shorter blocks than 2500 bytes. That would be something we can communicate via virtio-rng-pci feature bits. Perhaps /dev/hwrng could also expose a need-whitening property in sysfs. b) if the host has no physical hwrng, /dev/hwrng will output nothing at all, which is worse than /dev/random in that situation. Not really, it would just mean that the guest takes more time to gather entropy, just like if you had no virtio-rng-pci at all. If you have rdrand you might just use it in the guest directly, unless you have a strong reason (migration?) not to do that. Either way, for rdrand you need whitening similar to what rngd is doing (for *rdseed* you do not, but rdseed is not shipping yet.) Yes, migration is a good reason. The startup issue is an interesting problem. If you have full control over the guest it might be best to simply inject some entropy into the guest on startup via the initramfs or a disk image; that has its own awkwardness too, of course. The one bit that could potentially be solved in Qemu would be an option to don't start the guest until X bytes of entropy have been gathered. Overall, I want to emphasize that we don't want to try solve generic problems in virtualization space... resource constraints on /dev/random is a generic host OS issue for example. Yes, but the agreed solution right now is that programs should not ask for more than 32 bytes or so from /dev/random. Which means /dev/random is not a suitable backend for virtio-rng-pci as things stand now. Paolo -- Sent from my mobile phone. Please excuse brevity and lack of formatting.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
Il 26/10/2012 21:07, H. Peter Anvin ha scritto: This is surreal. Output from /dev/hwrng turns into output for /dev/random... it us guaranteed worse; period, end of story. Isn't that exactly what happens in bare-metal? hwrng - rngd - random. Instead here we'd have, host hwrng - virtio-rng-pci - guest hwrng - guest rngd - guest random. The only difference is that you paravirtualize access to the host hwrng to a) distribute entropy to multiple guests; b) support migration across hosts with different CPUs and hardware. I don't know who the agreement is with, but it is ridiculous in this case. man 4 random: While some safety margin above that minimum is reasonable, as a guard against flaws in the CPRNG algorithm, no cryptographic primitive available today can hope to promise more than 256 bits of security, so if any program reads more than 256 bits (32 bytes) from the kernel random pool per invocation, or per reasonable reseed interval (not less than one minute), that should be taken as a sign that its cryptography is not skilfully implemented. Paolo
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
That statement is pretty toxic... I wonder where it came from. It is at best horribly misleading and actively encourages dangerous behaviours even for the cases where it isn't actively wrong. Paolo Bonzini pbonz...@redhat.com wrote: Il 26/10/2012 21:07, H. Peter Anvin ha scritto: This is surreal. Output from /dev/hwrng turns into output for /dev/random... it us guaranteed worse; period, end of story. Isn't that exactly what happens in bare-metal? hwrng - rngd - random. Instead here we'd have, host hwrng - virtio-rng-pci - guest hwrng - guest rngd - guest random. The only difference is that you paravirtualize access to the host hwrng to a) distribute entropy to multiple guests; b) support migration across hosts with different CPUs and hardware. I don't know who the agreement is with, but it is ridiculous in this case. man 4 random: While some safety margin above that minimum is reasonable, as a guard against flaws in the CPRNG algorithm, no cryptographic primitive available today can hope to promise more than 256 bits of security, so if any program reads more than 256 bits (32 bytes) from the kernel random pool per invocation, or per reasonable reseed interval (not less than one minute), that should be taken as a sign that its cryptography is not skilfully implemented. Paolo -- Sent from my mobile phone. Please excuse brevity and lack of formatting.
Re: [Qemu-devel] [PATCH 0/6] add paravirtualization hwrng support
On 10/26/2012 12:51 PM, Paolo Bonzini wrote: Il 26/10/2012 21:07, H. Peter Anvin ha scritto: This is surreal. Output from /dev/hwrng turns into output for /dev/random... it us guaranteed worse; period, end of story. Isn't that exactly what happens in bare-metal? hwrng - rngd - random. Instead here we'd have, host hwrng - virtio-rng-pci - guest hwrng - guest rngd - guest random. The only difference is that you paravirtualize access to the host hwrng to a) distribute entropy to multiple guests; b) support migration across hosts with different CPUs and hardware. First, hwrng is only one of the sources used by rngd. It can also (currently) use RDRAND or TPM; additional sources are likely to be added in the future. Second, the harvesting of environmental noise -- timings -- is not as good in a VM as on plain hardware, so for the no-hwrng case it is better for this to be done in the host than in the VM. -hpa