[Xen-devel] [RFC] Hypervisor RNG and enumeration

Andy Lutomirski
Wed, 29 Oct 2014 16:13:15 -0000

On Oct 29, 2014 8:17 AM, "Ian Jackson" <Ian.Jackson at
eu.citrix.com> wrote:
>
> Andy Lutomirski writes ("[Xen-devel] [RFC] Hypervisor RNG and
enumeration"):
> > Here's a draft CommonHV spec.  It's also on github:
> > https://github.com/amluto/CommonHV
>
> This a worthwhile direction to investigate, and an interesting
> proposal.  From a Xen point of view I have some concerns, though.
>
> I think in Xen we would want to implement the bulk of the provision of
> random numbers to guests outside the hypervisor.  That is, the
> hypervisor itself should not have random number pool code, associated
> policy, and so on.  We would like to avoid adding too much code to the
> hypervisor.
>
> That functionality should live in the lower toolstack layers.  For the
> benefit of people who want to do radical disaggregation (for security
> reasons), it should be capable of being provided by a different domain
> to dom0.
>
> I think a fully general interface based purely on MSRs makes that
> difficult in a number of ways:
>
>  * Currently I don't think there is any way in Xen to cause MSR
>    accesses to be passed to toolstack support programs.
>
>  * In some configurations, Xen PV domains do not have a suitable
>    longrunning service process to handle requests of this kind.
>
>  * MSR reads of this kind might be expected to be fast but if they
>    involve trapping to a service domain they might be very slow.

I have no objection to specifying that these reads may be quite slow.
Guests should only use them at boot and if they have some reason to
distrust their RNG pool.

The latter can legitimately happen after various types of suspend or
after migration (detected by VM Generation ID, for example).

>
>  * This interface is very x86-specific.
>

Agreed.

Part of the motivation is to allow guests to use this mechanism very
early in boot for stack canaries, ASLR, etc.  I don't know a good way
to do that without something very platform specific.

>
> It seems to me that the real need for this facility is to provide a
> good seed for the guest's own cryptographic PRNG.  If we restrict
> ourselves to that use case, we can sidestep the difficulties.
>
> In particular, the parts of this proposal that are most difficult are:
>
>  * The facility for the guest to provide random numbers back to the
>    host.  I think this can be dealt with easily by hypervisor-specific
>    mechanisms, if it is desirable.

Xen can implement this is a no-op.  If we use feature bits, wrmsr
support could be separately enumerated.

>
>  * The implication that a hypervisor ought to be providing a unbounded
>    stream of random numbers, rather than a fixed amount of seed.
>

I don't expect hypervisors to estimate the entropy available through
this mechanism.  Given that, the length of the stream is largely
irrelevant, except that an unbounded stream allowed reseeding after
boot.

>
> I think the most obvious approach would be to provide the VM, at
> startup, with a page containing a fixed amount of random number seed,
> along with some metatdata.
>
> Some platform-specific way of discovering the location of the page
> would have to be defined.  (That might an MSR but more likely it would
> be Device Tree or ACPI.)
>
> After the guest has read the page, it would be free to treat it as
> normal memory.
>
> The metadata need do little more than specify the length and the
> amount of provided entropy.  There should be some room for expansion.

ACPI is not useful early in boot.  DT might be, but that could be a
separate spec.

>
> The specification should say that the provided seed MUST be
> cryptographically secure, MUST have as much entropy as stated and that
> that amount of entropy MUST be at least (say) 64 bits and SHOULD be at
> least (say) 256 bits.

I don't think this is practical.  It will require hypervisors to
throttle guest startup to ensure that they have that much entropy.

I'm not fundamentally opposed to allowing hypervisors to provide more
than 64 bits of data per invocation, which would help when the trap is
very slow, but I don't know of a suitably simple way to do that.

--Andy