* [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator
@ 2024-03-18 15:54 mhkelley58
2024-03-18 17:21 ` Nuno Das Neves
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: mhkelley58 @ 2024-03-18 15:54 UTC (permalink / raw)
To: haiyangz, wei.liu, decui, catalin.marinas, will, tglx, mingo, bp,
dave.hansen, hpa, arnd, tytso, Jason, x86, linux-kernel,
linux-hyperv, linux-arch
From: Michael Kelley <mhklinux@outlook.com>
A Hyper-V host provides its guest VMs with entropy in a custom ACPI
table named "OEM0". The entropy bits are updated each time Hyper-V
boots the VM, and are suitable for seeding the Linux guest random
number generator (rng). See a brief description of OEM0 in [1].
Generation 2 VMs on Hyper-V use UEFI to boot. Existing EFI code in
Linux seeds the rng with entropy bits from the EFI_RNG_PROTOCOL.
Via this path, the rng is seeded very early during boot with good
entropy. The ACPI OEM0 table provided in such VMs is an additional
source of entropy.
Generation 1 VMs on Hyper-V boot from BIOS. For these VMs, Linux
doesn't currently get any entropy from the Hyper-V host. While this
is not fundamentally broken because Linux can generate its own entropy,
using the Hyper-V host provided entropy would get the rng off to a
better start and would do so earlier in the boot process.
Improve the rng seeding for Generation 1 VMs by having Hyper-V specific
code in Linux take advantage of the OEM0 table to seed the rng. For
Generation 2 VMs, use the OEM0 table to provide additional entropy
beyond the EFI_RNG_PROTOCOL. Because the OEM0 table is custom to
Hyper-V, parse it directly in the Hyper-V code in the Linux kernel
and use add_bootloader_randomness() to add it to the rng. Once the
entropy bits are read from OEM0, zero them out in the table so
they don't appear in /sys/firmware/acpi/tables/OEM0 in the running
VM. The zero'ing is done out of an abundance of caution to avoid
potential security risks to the rng. Also set the OEM0 data length
to zero so a kexec or other subsequent use of the table won't try
to use the zero'ed bits.
[1] https://download.microsoft.com/download/1/c/9/1c9813b8-089c-4fef-b2ad-ad80e79403ba/Whitepaper%20-%20The%20Windows%2010%20random%20number%20generation%20infrastructure.pdf
Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
Changes in v3:
* Removed restriction to just Generation 1 VMs. Generation 2 VMs
now also use the additional entropy even though they also get
initial entropy via EFI_RNG_PROTOCOL [Jason Donenfeld]
* Process the OEM0 table on ARM64 systems in addition to x86/x64,
as a result of no longer excluding Generation 2 VM.
* Enlarge the range of entropy byte counts that are considered valid
in the OEM0 table. New range is 8 to 4K; previously the range was
32 to 256. [Jason Donenfeld]
* After processing the entropy bits in OEM0, also set the OEM0
table length to indicate that the entropy byte count is zero,
to prevent a subsequent kexec or other use of the table from
trying to use the zero'ed bits. [Jason Donenfeld]
Changes in v2:
* Tweaked commit message [Wei Liu]
* Removed message when OEM0 table isn't found. Added debug-level
message when OEM0 is successfully used to add randomness. [Wei Liu]
arch/arm64/hyperv/mshyperv.c | 2 +
arch/x86/kernel/cpu/mshyperv.c | 1 +
drivers/hv/hv_common.c | 69 ++++++++++++++++++++++++++++++++++
include/asm-generic/mshyperv.h | 2 +
4 files changed, 74 insertions(+)
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index f1b8a04ee9f2..c8193cec1b90 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -74,6 +74,8 @@ static int __init hyperv_init(void)
return ret;
}
+ ms_hyperv_late_init();
+
hyperv_initialized = true;
return 0;
}
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 303fef824167..65c9cbdd2282 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -648,6 +648,7 @@ const __initconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
.init.x2apic_available = ms_hyperv_x2apic_available,
.init.msi_ext_dest_id = ms_hyperv_msi_ext_dest_id,
.init.init_platform = ms_hyperv_init_platform,
+ .init.guest_late_init = ms_hyperv_late_init,
#ifdef CONFIG_AMD_MEM_ENCRYPT
.runtime.sev_es_hcall_prepare = hv_sev_es_hcall_prepare,
.runtime.sev_es_hcall_finish = hv_sev_es_hcall_finish,
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 0285a74363b3..724de94d885f 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -20,8 +20,11 @@
#include <linux/sched/task_stack.h>
#include <linux/panic_notifier.h>
#include <linux/ptrace.h>
+#include <linux/random.h>
+#include <linux/efi.h>
#include <linux/kdebug.h>
#include <linux/kmsg_dump.h>
+#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/dma-map-ops.h>
#include <linux/set_memory.h>
@@ -347,6 +350,72 @@ int __init hv_common_init(void)
return 0;
}
+void __init ms_hyperv_late_init(void)
+{
+ struct acpi_table_header *header;
+ acpi_status status;
+ u8 *randomdata;
+ u32 length, i;
+
+ /*
+ * Seed the Linux random number generator with entropy provided by
+ * the Hyper-V host in ACPI table OEM0.
+ */
+ if (!IS_ENABLED(CONFIG_ACPI))
+ return;
+
+ status = acpi_get_table("OEM0", 0, &header);
+ if (ACPI_FAILURE(status) || !header)
+ return;
+
+ /*
+ * Since the "OEM0" table name is for OEM specific usage, verify
+ * that what we're seeing purports to be from Microsoft.
+ */
+ if (strncmp(header->oem_table_id, "MICROSFT", 8))
+ goto error;
+
+ /*
+ * Ensure the length is reasonable. Requiring at least 8 bytes and
+ * no more than 4K bytes is somewhat arbitrary and just protects
+ * against a malformed table. Hyper-V currently provides 64 bytes,
+ * but allow for a change in a later version.
+ */
+ if (header->length < sizeof(*header) + 8 ||
+ header->length > sizeof(*header) + SZ_4K)
+ goto error;
+
+ length = header->length - sizeof(*header);
+ randomdata = (u8 *)(header + 1);
+
+ pr_debug("Hyper-V: Seeding rng with %d random bytes from ACPI table OEM0\n",
+ length);
+
+ add_bootloader_randomness(randomdata, length);
+
+ /*
+ * To prevent the seed data from being visible in /sys/firmware/acpi,
+ * zero out the random data in the ACPI table and fixup the checksum.
+ * The zero'ing is done out of an abundance of caution in avoiding
+ * potential security risks to the rng. Similarly, reset the table
+ * length to just the header size so that a subsequent kexec doesn't
+ * try to use the zero'ed out random data.
+ */
+ for (i = 0; i < length; i++) {
+ header->checksum += randomdata[i];
+ randomdata[i] = 0;
+ }
+
+ for (i = 0; i < sizeof(header->length); i++)
+ header->checksum += ((u8 *)&header->length)[i];
+ header->length = sizeof(*header);
+ for (i = 0; i < sizeof(header->length); i++)
+ header->checksum -= ((u8 *)&header->length)[i];
+
+error:
+ acpi_put_table(header);
+}
+
/*
* Hyper-V specific initialization and die code for
* individual CPUs that is common across all architectures.
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 430f0ae0dde2..e861223093df 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -193,6 +193,7 @@ extern u64 (*hv_read_reference_counter)(void);
int __init hv_common_init(void);
void __init hv_common_free(void);
+void __init ms_hyperv_late_init(void);
int hv_common_cpu_init(unsigned int cpu);
int hv_common_cpu_die(unsigned int cpu);
@@ -290,6 +291,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent);
static inline bool hv_is_hyperv_initialized(void) { return false; }
static inline bool hv_is_hibernation_supported(void) { return false; }
static inline void hyperv_cleanup(void) {}
+static inline void ms_hyperv_late_init(void) {}
static inline bool hv_is_isolation_supported(void) { return false; }
static inline enum hv_isolation_type hv_get_isolation_type(void)
{
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator
2024-03-18 15:54 [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator mhkelley58
@ 2024-03-18 17:21 ` Nuno Das Neves
2024-03-18 21:03 ` Jason A. Donenfeld
2024-03-18 22:04 ` Wei Liu
2 siblings, 0 replies; 5+ messages in thread
From: Nuno Das Neves @ 2024-03-18 17:21 UTC (permalink / raw)
To: mhklinux, haiyangz, wei.liu, decui, catalin.marinas, will, tglx,
mingo, bp, dave.hansen, hpa, arnd, tytso, Jason, x86,
linux-kernel, linux-hyperv, linux-arch
On 3/18/2024 8:54 AM, mhkelley58@gmail.com wrote:
> From: Michael Kelley <mhklinux@outlook.com>
>
> A Hyper-V host provides its guest VMs with entropy in a custom ACPI
> table named "OEM0". The entropy bits are updated each time Hyper-V
> boots the VM, and are suitable for seeding the Linux guest random
> number generator (rng). See a brief description of OEM0 in [1].
>
> Generation 2 VMs on Hyper-V use UEFI to boot. Existing EFI code in
> Linux seeds the rng with entropy bits from the EFI_RNG_PROTOCOL.
> Via this path, the rng is seeded very early during boot with good
> entropy. The ACPI OEM0 table provided in such VMs is an additional
> source of entropy.
>
> Generation 1 VMs on Hyper-V boot from BIOS. For these VMs, Linux
> doesn't currently get any entropy from the Hyper-V host. While this
> is not fundamentally broken because Linux can generate its own entropy,
> using the Hyper-V host provided entropy would get the rng off to a
> better start and would do so earlier in the boot process.
>
> Improve the rng seeding for Generation 1 VMs by having Hyper-V specific
> code in Linux take advantage of the OEM0 table to seed the rng. For
> Generation 2 VMs, use the OEM0 table to provide additional entropy
> beyond the EFI_RNG_PROTOCOL. Because the OEM0 table is custom to
> Hyper-V, parse it directly in the Hyper-V code in the Linux kernel
> and use add_bootloader_randomness() to add it to the rng. Once the
> entropy bits are read from OEM0, zero them out in the table so
> they don't appear in /sys/firmware/acpi/tables/OEM0 in the running
> VM. The zero'ing is done out of an abundance of caution to avoid
> potential security risks to the rng. Also set the OEM0 data length
> to zero so a kexec or other subsequent use of the table won't try
> to use the zero'ed bits.
>
> [1] https://download.microsoft.com/download/1/c/9/1c9813b8-089c-4fef-b2ad-ad80e79403ba/Whitepaper%20-%20The%20Windows%2010%20random%20number%20generation%20infrastructure.pdf
>
> Signed-off-by: Michael Kelley <mhklinux@outlook.com>
> ---
> Changes in v3:
> * Removed restriction to just Generation 1 VMs. Generation 2 VMs
> now also use the additional entropy even though they also get
> initial entropy via EFI_RNG_PROTOCOL [Jason Donenfeld]
> * Process the OEM0 table on ARM64 systems in addition to x86/x64,
> as a result of no longer excluding Generation 2 VM.
> * Enlarge the range of entropy byte counts that are considered valid
> in the OEM0 table. New range is 8 to 4K; previously the range was
> 32 to 256. [Jason Donenfeld]
> * After processing the entropy bits in OEM0, also set the OEM0
> table length to indicate that the entropy byte count is zero,
> to prevent a subsequent kexec or other use of the table from
> trying to use the zero'ed bits. [Jason Donenfeld]
>
> Changes in v2:
> * Tweaked commit message [Wei Liu]
> * Removed message when OEM0 table isn't found. Added debug-level
> message when OEM0 is successfully used to add randomness. [Wei Liu]
>
> arch/arm64/hyperv/mshyperv.c | 2 +
> arch/x86/kernel/cpu/mshyperv.c | 1 +
> drivers/hv/hv_common.c | 69 ++++++++++++++++++++++++++++++++++
> include/asm-generic/mshyperv.h | 2 +
> 4 files changed, 74 insertions(+)
>
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index f1b8a04ee9f2..c8193cec1b90 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -74,6 +74,8 @@ static int __init hyperv_init(void)
> return ret;
> }
>
> + ms_hyperv_late_init();
> +
> hyperv_initialized = true;
> return 0;
> }
> diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> index 303fef824167..65c9cbdd2282 100644
> --- a/arch/x86/kernel/cpu/mshyperv.c
> +++ b/arch/x86/kernel/cpu/mshyperv.c
> @@ -648,6 +648,7 @@ const __initconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
> .init.x2apic_available = ms_hyperv_x2apic_available,
> .init.msi_ext_dest_id = ms_hyperv_msi_ext_dest_id,
> .init.init_platform = ms_hyperv_init_platform,
> + .init.guest_late_init = ms_hyperv_late_init,
> #ifdef CONFIG_AMD_MEM_ENCRYPT
> .runtime.sev_es_hcall_prepare = hv_sev_es_hcall_prepare,
> .runtime.sev_es_hcall_finish = hv_sev_es_hcall_finish,
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 0285a74363b3..724de94d885f 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -20,8 +20,11 @@
> #include <linux/sched/task_stack.h>
> #include <linux/panic_notifier.h>
> #include <linux/ptrace.h>
> +#include <linux/random.h>
> +#include <linux/efi.h>
> #include <linux/kdebug.h>
> #include <linux/kmsg_dump.h>
> +#include <linux/sizes.h>
> #include <linux/slab.h>
> #include <linux/dma-map-ops.h>
> #include <linux/set_memory.h>
> @@ -347,6 +350,72 @@ int __init hv_common_init(void)
> return 0;
> }
>
> +void __init ms_hyperv_late_init(void)
> +{
> + struct acpi_table_header *header;
> + acpi_status status;
> + u8 *randomdata;
> + u32 length, i;
> +
> + /*
> + * Seed the Linux random number generator with entropy provided by
> + * the Hyper-V host in ACPI table OEM0.
> + */
> + if (!IS_ENABLED(CONFIG_ACPI))
> + return;
> +
> + status = acpi_get_table("OEM0", 0, &header);
> + if (ACPI_FAILURE(status) || !header)
> + return;
> +
> + /*
> + * Since the "OEM0" table name is for OEM specific usage, verify
> + * that what we're seeing purports to be from Microsoft.
> + */
> + if (strncmp(header->oem_table_id, "MICROSFT", 8))
> + goto error;
> +
> + /*
> + * Ensure the length is reasonable. Requiring at least 8 bytes and
> + * no more than 4K bytes is somewhat arbitrary and just protects
> + * against a malformed table. Hyper-V currently provides 64 bytes,
> + * but allow for a change in a later version.
> + */
> + if (header->length < sizeof(*header) + 8 ||
> + header->length > sizeof(*header) + SZ_4K> + goto error;
> +
> + length = header->length - sizeof(*header);
> + randomdata = (u8 *)(header + 1);
> +
> + pr_debug("Hyper-V: Seeding rng with %d random bytes from ACPI table OEM0\n",
> + length);
> +
> + add_bootloader_randomness(randomdata, length);
> +
> + /*
> + * To prevent the seed data from being visible in /sys/firmware/acpi,
> + * zero out the random data in the ACPI table and fixup the checksum.
> + * The zero'ing is done out of an abundance of caution in avoiding
> + * potential security risks to the rng. Similarly, reset the table
> + * length to just the header size so that a subsequent kexec doesn't
> + * try to use the zero'ed out random data.
> + */
> + for (i = 0; i < length; i++) {
> + header->checksum += randomdata[i];
> + randomdata[i] = 0;
> + }
> +
> + for (i = 0; i < sizeof(header->length); i++)
> + header->checksum += ((u8 *)&header->length)[i];
> + header->length = sizeof(*header);
> + for (i = 0; i < sizeof(header->length); i++)
> + header->checksum -= ((u8 *)&header->length)[i];
> +
> +error:
> + acpi_put_table(header);
> +}
> +
> /*
> * Hyper-V specific initialization and die code for
> * individual CPUs that is common across all architectures.
> diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> index 430f0ae0dde2..e861223093df 100644
> --- a/include/asm-generic/mshyperv.h
> +++ b/include/asm-generic/mshyperv.h
> @@ -193,6 +193,7 @@ extern u64 (*hv_read_reference_counter)(void);
>
> int __init hv_common_init(void);
> void __init hv_common_free(void);
> +void __init ms_hyperv_late_init(void);
> int hv_common_cpu_init(unsigned int cpu);
> int hv_common_cpu_die(unsigned int cpu);
>
> @@ -290,6 +291,7 @@ void hv_setup_dma_ops(struct device *dev, bool coherent);
> static inline bool hv_is_hyperv_initialized(void) { return false; }
> static inline bool hv_is_hibernation_supported(void) { return false; }
> static inline void hyperv_cleanup(void) {}
> +static inline void ms_hyperv_late_init(void) {}
> static inline bool hv_is_isolation_supported(void) { return false; }
> static inline enum hv_isolation_type hv_get_isolation_type(void)
> {
This patch looks good to me. The code comments were very helpful in explaining
what is going on.
Nuno
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator
2024-03-18 15:54 [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator mhkelley58
2024-03-18 17:21 ` Nuno Das Neves
@ 2024-03-18 21:03 ` Jason A. Donenfeld
2024-03-18 22:49 ` Michael Kelley
2024-03-18 22:04 ` Wei Liu
2 siblings, 1 reply; 5+ messages in thread
From: Jason A. Donenfeld @ 2024-03-18 21:03 UTC (permalink / raw)
To: mhklinux
Cc: haiyangz, wei.liu, decui, catalin.marinas, will, tglx, mingo, bp,
dave.hansen, hpa, arnd, tytso, x86, linux-kernel, linux-hyperv,
linux-arch
Hi Michael,
On Mon, Mar 18, 2024 at 08:54:08AM -0700, mhkelley58@gmail.com wrote:
> From: Michael Kelley <mhklinux@outlook.com>
>
> A Hyper-V host provides its guest VMs with entropy in a custom ACPI
> table named "OEM0". The entropy bits are updated each time Hyper-V
> boots the VM, and are suitable for seeding the Linux guest random
> number generator (rng). See a brief description of OEM0 in [1].
>
> Generation 2 VMs on Hyper-V use UEFI to boot. Existing EFI code in
> Linux seeds the rng with entropy bits from the EFI_RNG_PROTOCOL.
> Via this path, the rng is seeded very early during boot with good
> entropy. The ACPI OEM0 table provided in such VMs is an additional
> source of entropy.
>
> Generation 1 VMs on Hyper-V boot from BIOS. For these VMs, Linux
> doesn't currently get any entropy from the Hyper-V host. While this
> is not fundamentally broken because Linux can generate its own entropy,
> using the Hyper-V host provided entropy would get the rng off to a
> better start and would do so earlier in the boot process.
>
> Improve the rng seeding for Generation 1 VMs by having Hyper-V specific
> code in Linux take advantage of the OEM0 table to seed the rng. For
> Generation 2 VMs, use the OEM0 table to provide additional entropy
> beyond the EFI_RNG_PROTOCOL. Because the OEM0 table is custom to
> Hyper-V, parse it directly in the Hyper-V code in the Linux kernel
> and use add_bootloader_randomness() to add it to the rng. Once the
> entropy bits are read from OEM0, zero them out in the table so
> they don't appear in /sys/firmware/acpi/tables/OEM0 in the running
> VM. The zero'ing is done out of an abundance of caution to avoid
> potential security risks to the rng. Also set the OEM0 data length
> to zero so a kexec or other subsequent use of the table won't try
> to use the zero'ed bits.
>
> [1] https://download.microsoft.com/download/1/c/9/1c9813b8-089c-4fef-b2ad-ad80e79403ba/Whitepaper%20-%20The%20Windows%2010%20random%20number%20generation%20infrastructure.pdf
Looks good to me. Assuming you've tested this and it works,
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Thanks for the v3.
Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator
2024-03-18 21:03 ` Jason A. Donenfeld
@ 2024-03-18 22:49 ` Michael Kelley
0 siblings, 0 replies; 5+ messages in thread
From: Michael Kelley @ 2024-03-18 22:49 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com,
catalin.marinas@arm.com, will@kernel.org, tglx@linutronix.de,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
hpa@zytor.com, arnd@arndb.de, tytso@mit.edu, x86@kernel.org,
linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org,
linux-arch@vger.kernel.org
From: Jason A. Donenfeld <Jason@zx2c4.com> Sent: Monday, March 18, 2024 2:03 PM
>
> On Mon, Mar 18, 2024 at 08:54:08AM -0700, mhkelley58@gmail.com wrote:
> > From: Michael Kelley <mhklinux@outlook.com>
> >
> > A Hyper-V host provides its guest VMs with entropy in a custom ACPI
> > table named "OEM0". The entropy bits are updated each time Hyper-V
> > boots the VM, and are suitable for seeding the Linux guest random
> > number generator (rng). See a brief description of OEM0 in [1].
> >
> > Generation 2 VMs on Hyper-V use UEFI to boot. Existing EFI code in
> > Linux seeds the rng with entropy bits from the EFI_RNG_PROTOCOL.
> > Via this path, the rng is seeded very early during boot with good
> > entropy. The ACPI OEM0 table provided in such VMs is an additional
> > source of entropy.
> >
> > Generation 1 VMs on Hyper-V boot from BIOS. For these VMs, Linux
> > doesn't currently get any entropy from the Hyper-V host. While this
> > is not fundamentally broken because Linux can generate its own entropy,
> > using the Hyper-V host provided entropy would get the rng off to a
> > better start and would do so earlier in the boot process.
> >
> > Improve the rng seeding for Generation 1 VMs by having Hyper-V specific
> > code in Linux take advantage of the OEM0 table to seed the rng. For
> > Generation 2 VMs, use the OEM0 table to provide additional entropy
> > beyond the EFI_RNG_PROTOCOL. Because the OEM0 table is custom to
> > Hyper-V, parse it directly in the Hyper-V code in the Linux kernel
> > and use add_bootloader_randomness() to add it to the rng. Once the
> > entropy bits are read from OEM0, zero them out in the table so
> > they don't appear in /sys/firmware/acpi/tables/OEM0 in the running
> > VM. The zero'ing is done out of an abundance of caution to avoid
> > potential security risks to the rng. Also set the OEM0 data length
> > to zero so a kexec or other subsequent use of the table won't try
> > to use the zero'ed bits.
> >
> > [1] https://download.microsoft.com/download/1/c/9/1c9813b8-089c-4fef-b2ad-ad80e79403ba/Whitepaper%20-%20The%20Windows%2010%20random%20number%20generation%20infrastructure.pdf
>
> Looks good to me. Assuming you've tested this and it works,
Yes, tested on both x86 and arm64. Thanks.
Michael
>
> Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
>
> Thanks for the v3.
>
> Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator
2024-03-18 15:54 [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator mhkelley58
2024-03-18 17:21 ` Nuno Das Neves
2024-03-18 21:03 ` Jason A. Donenfeld
@ 2024-03-18 22:04 ` Wei Liu
2 siblings, 0 replies; 5+ messages in thread
From: Wei Liu @ 2024-03-18 22:04 UTC (permalink / raw)
To: mhklinux
Cc: haiyangz, wei.liu, decui, catalin.marinas, will, tglx, mingo, bp,
dave.hansen, hpa, arnd, tytso, Jason, x86, linux-kernel,
linux-hyperv, linux-arch
On Mon, Mar 18, 2024 at 08:54:08AM -0700, mhkelley58@gmail.com wrote:
> From: Michael Kelley <mhklinux@outlook.com>
>
> A Hyper-V host provides its guest VMs with entropy in a custom ACPI
> table named "OEM0". The entropy bits are updated each time Hyper-V
> boots the VM, and are suitable for seeding the Linux guest random
> number generator (rng). See a brief description of OEM0 in [1].
>
> Generation 2 VMs on Hyper-V use UEFI to boot. Existing EFI code in
> Linux seeds the rng with entropy bits from the EFI_RNG_PROTOCOL.
> Via this path, the rng is seeded very early during boot with good
> entropy. The ACPI OEM0 table provided in such VMs is an additional
> source of entropy.
>
> Generation 1 VMs on Hyper-V boot from BIOS. For these VMs, Linux
> doesn't currently get any entropy from the Hyper-V host. While this
> is not fundamentally broken because Linux can generate its own entropy,
> using the Hyper-V host provided entropy would get the rng off to a
> better start and would do so earlier in the boot process.
>
> Improve the rng seeding for Generation 1 VMs by having Hyper-V specific
> code in Linux take advantage of the OEM0 table to seed the rng. For
> Generation 2 VMs, use the OEM0 table to provide additional entropy
> beyond the EFI_RNG_PROTOCOL. Because the OEM0 table is custom to
> Hyper-V, parse it directly in the Hyper-V code in the Linux kernel
> and use add_bootloader_randomness() to add it to the rng. Once the
> entropy bits are read from OEM0, zero them out in the table so
> they don't appear in /sys/firmware/acpi/tables/OEM0 in the running
> VM. The zero'ing is done out of an abundance of caution to avoid
> potential security risks to the rng. Also set the OEM0 data length
> to zero so a kexec or other subsequent use of the table won't try
> to use the zero'ed bits.
>
> [1] https://download.microsoft.com/download/1/c/9/1c9813b8-089c-4fef-b2ad-ad80e79403ba/Whitepaper%20-%20The%20Windows%2010%20random%20number%20generation%20infrastructure.pdf
>
> Signed-off-by: Michael Kelley <mhklinux@outlook.com>
Applied to hyperv-next. Thanks.
Long gave his review in the last version. I assumed he's at least
onboard with the general idea here. Time is tight, so I applied this
patch without waiting for Long's ack again.
Long, if you have objections, please speak up.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-03-18 22:50 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-18 15:54 [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator mhkelley58
2024-03-18 17:21 ` Nuno Das Neves
2024-03-18 21:03 ` Jason A. Donenfeld
2024-03-18 22:49 ` Michael Kelley
2024-03-18 22:04 ` Wei Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).