Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src-draft/trunk]: src/sys/stand/efiboot Pass EFI RNG output via /chosen/netb...
details: https://anonhg.NetBSD.org/src-all/rev/996ce8f9ccff
branches: trunk
changeset: 932723:996ce8f9ccff
user: Taylor R Campbell <riastradh%NetBSD.org@localhost>
date: Mon May 11 02:11:09 2020 +0000
description:
Pass EFI RNG output via /chosen/netbsd,efirng-{start,end}.
This is separate from /chosen/netbsd,rndseed-{start,end}, which
specifies NetBSD's persistent on-disk seed; efirng is the firmware's
RNG device.
diffstat:
sys/stand/efiboot/efiboot.c | 2 +
sys/stand/efiboot/efifdt.c | 24 ++++++++++++++++++++++
sys/stand/efiboot/efifdt.h | 1 +
sys/stand/efiboot/exec.c | 48 +++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 73 insertions(+), 2 deletions(-)
diffs (153 lines):
diff -r e6085e29ece7 -r 996ce8f9ccff sys/stand/efiboot/efiboot.c
--- a/sys/stand/efiboot/efiboot.c Mon May 11 02:10:19 2020 +0000
+++ b/sys/stand/efiboot/efiboot.c Mon May 11 02:11:09 2020 +0000
@@ -31,6 +31,7 @@
#include "efiblock.h"
#include "efifdt.h"
#include "efiacpi.h"
+#include "efirng.h"
#include <sys/reboot.h>
@@ -99,6 +100,7 @@
efi_net_probe();
efi_file_system_probe();
efi_block_probe();
+ efi_rng_probe();
boot();
diff -r e6085e29ece7 -r 996ce8f9ccff sys/stand/efiboot/efifdt.c
--- a/sys/stand/efiboot/efifdt.c Mon May 11 02:10:19 2020 +0000
+++ b/sys/stand/efiboot/efifdt.c Mon May 11 02:11:09 2020 +0000
@@ -391,6 +391,7 @@
fdt_setprop_u64(fdt_data, chosen, "linux,initrd-end", initrd_addr + initrd_size);
}
+/* pass in the NetBSD on-disk random seed */
void
efi_fdt_rndseed(u_long rndseed_addr, u_long rndseed_size)
{
@@ -412,3 +413,26 @@
fdt_setprop_u64(fdt_data, chosen, "netbsd,rndseed-end",
rndseed_addr + rndseed_size);
}
+
+/* pass in output from the EFI firmware's RNG from some unknown source */
+void
+efi_fdt_efirng(u_long efirng_addr, u_long efirng_size)
+{
+ int chosen;
+
+ if (efirng_size == 0)
+ return;
+
+ chosen = fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH);
+ if (chosen < 0)
+ chosen = fdt_add_subnode(fdt_data,
+ fdt_path_offset(fdt_data, "/"),
+ FDT_CHOSEN_NODE_NAME);
+ if (chosen < 0)
+ panic("FDT: Failed to create " FDT_CHOSEN_NODE_PATH " node");
+
+ fdt_setprop_u64(fdt_data, chosen, "netbsd,efirng-start",
+ efirng_addr);
+ fdt_setprop_u64(fdt_data, chosen, "netbsd,efirng-end",
+ efirng_addr + efirng_size);
+}
diff -r e6085e29ece7 -r 996ce8f9ccff sys/stand/efiboot/efifdt.h
--- a/sys/stand/efiboot/efifdt.h Mon May 11 02:10:19 2020 +0000
+++ b/sys/stand/efiboot/efifdt.h Mon May 11 02:11:09 2020 +0000
@@ -38,5 +38,6 @@
void efi_fdt_bootargs(const char *);
void efi_fdt_initrd(u_long, u_long);
void efi_fdt_rndseed(u_long, u_long);
+void efi_fdt_efirng(u_long, u_long);
void efi_fdt_init(u_long, u_long);
void efi_fdt_fini(void);
diff -r e6085e29ece7 -r 996ce8f9ccff sys/stand/efiboot/exec.c
--- a/sys/stand/efiboot/exec.c Mon May 11 02:10:19 2020 +0000
+++ b/sys/stand/efiboot/exec.c Mon May 11 02:11:09 2020 +0000
@@ -31,6 +31,7 @@
#include "efienv.h"
#include "efifdt.h"
#include "efiacpi.h"
+#include "efirng.h"
#include <sys/reboot.h>
@@ -41,8 +42,8 @@
#define FDT_SPACE (4 * 1024 * 1024)
#define FDT_ALIGN ((2 * 1024 * 1024) - 1)
-static EFI_PHYSICAL_ADDRESS initrd_addr, dtb_addr, rndseed_addr;
-static u_long initrd_size = 0, dtb_size = 0, rndseed_size = 0;
+static EFI_PHYSICAL_ADDRESS initrd_addr, dtb_addr, rndseed_addr, efirng_addr;
+static u_long initrd_size = 0, dtb_size = 0, rndseed_size = 0, efirng_size = 0;
static int
load_file(const char *path, u_long extra, bool quiet_errors,
@@ -273,6 +274,47 @@
prop_object_iterator_release(iter);
}
+static void
+generate_efirng(void)
+{
+ EFI_PHYSICAL_ADDRESS addr;
+ u_long size = EFI_PAGE_SIZE;
+ EFI_STATUS status;
+
+ /* Check whether the RNG is available before bothering. */
+ if (!efi_rng_available())
+ return;
+
+ /*
+ * Allocate a page. This is the smallest unit we can pass into
+ * the kernel conveniently.
+ */
+#ifdef EFIBOOT_ALLOCATE_MAX_ADDRESS
+ addr = EFIBOOT_ALLOCATE_MAX_ADDRESS;
+ status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress,
+ EfiLoaderData, EFI_SIZE_TO_PAGES(size), &addr);
+#else
+ addr = 0;
+ status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages,
+ EfiLoaderData, EFI_SIZE_TO_PAGES(size), &addr);
+#endif
+ if (EFI_ERROR(status)) {
+ Print(L"Failed to allocate page for EFI RNG output: %r\n",
+ status);
+ return;
+ }
+
+ /* Fill the page with whatever the EFI RNG will do. */
+ if (efi_rng((void *)(uintptr_t)addr, size)) {
+ uefi_call_wrapper(BS->FreePages, 2, addr, size);
+ return;
+ }
+
+ /* Success! */
+ efirng_addr = addr;
+ efirng_size = size;
+}
+
int
exec_netbsd(const char *fname, const char *args)
{
@@ -283,6 +325,7 @@
load_file(get_initrd_path(), 0, false, &initrd_addr, &initrd_size);
load_file(get_dtb_path(), 0, false, &dtb_addr, &dtb_size);
+ generate_efirng();
memset(marks, 0, sizeof(marks));
ohowto = howto;
@@ -346,6 +389,7 @@
load_fdt_overlays();
efi_fdt_initrd(initrd_addr, initrd_size);
efi_fdt_rndseed(rndseed_addr, rndseed_size);
+ efi_fdt_efirng(efirng_addr, efirng_size);
efi_fdt_bootargs(args);
#ifdef EFIBOOT_ACPI
if (efi_acpi_available())
Home |
Main Index |
Thread Index |
Old Index