Skip to content

Support Rdrand/rdseed instruction in hyperlight_guest #202

Open
@simongdavies

Description

@simongdavies

The use of rdrand in hyperlight_guest for random number generation has been removed due to issues where the Host OS has prevented its use causing a KVM exit with a Internal Error.

Some hosts can choose to not support the user of RDRAND and RDSEED instructions in guests. Intel VMX provides the capability to turn usage of these instructions to VM Exits by setting bits in the MSR IA32_VMX_PROCBASED_CTLS2 (see here for details).

Linux/KVM will process these exits as invalid operations (see here).

The use of rdrand in WSL with Ubuntu/KVM (18.04/20.04/22.04) causes invalid operation errors as does a local non virtualised install of Ubuntu 22.04. It is not clear what causes Linux to disable support for rdrand in these scenarios, there is code in the kernel which checks to see if rdrand produces sufficiently random results and disables it in the host if not, this is not happening as if we check for support in the host it is enabled.

Regardless there are a couple of things that we can do:

In hyperlight_host we can ensure that rdrand is supported in the host and that it is allowed in the guest (by clearing the bit in IA32_VMX_PROCBASED_CTLS2 and ensuring that CPUID checks for RDRAND are successful). Brief attempts at setting this up in the KVM hypervisor module were not successful (failed to get/set the CPUID property and failed to get/set the MSR), but with more investigation this should be possible. It would need to be done in all hypervisor modules.

It may be that the issue seen with KVM was due to the way we were creating threads and using the KVM API in the past, we should re-test and see if this is still an issue

Alongside this the guest should be updated to test for rdrand support something like this:

let mut _eax: u32 = 1;
let _ebx: u32;
let mut ecx: u32;
let _edx: u32;

asm!(
  "mov {0:r}, rbx",
  "cpuid",
  "xchg {0:r}, rbx",
   out(reg) _ebx,
   inout("eax") _eax,
   out("ecx") ecx,
   out("edx") _edx,
   options(nostack, preserves_flags),
   );

if ecx & (1 << 30) != 0 {
   has_rdrand = true;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/securityInvolves security-related changes or fixeslifecycle/confirmedBug is verified or proposal seems reasonable

    Type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions