Module Name: src
Committed By: riastradh
Date: Thu May 14 19:20:08 UTC 2020
Modified Files:
src/sys/stand/efiboot: efiboot.c efifdt.c efifdt.h exec.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/sys/stand/efiboot/efiboot.c
cvs rdiff -u -r1.21 -r1.22 src/sys/stand/efiboot/efifdt.c
cvs rdiff -u -r1.7 -r1.8 src/sys/stand/efiboot/efifdt.h
cvs rdiff -u -r1.13 -r1.14 src/sys/stand/efiboot/exec.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/stand/efiboot/efiboot.c
diff -u src/sys/stand/efiboot/efiboot.c:1.17 src/sys/stand/efiboot/efiboot.c:1.18
--- src/sys/stand/efiboot/efiboot.c:1.17 Thu Sep 26 14:28:14 2019
+++ src/sys/stand/efiboot/efiboot.c Thu May 14 19:20:08 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: efiboot.c,v 1.17 2019/09/26 14:28:14 jmcneill Exp $ */
+/* $NetBSD: efiboot.c,v 1.18 2020/05/14 19:20:08 riastradh Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -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_main(EFI_HANDLE imageHandle, EFI_SYS
efi_net_probe();
efi_file_system_probe();
efi_block_probe();
+ efi_rng_probe();
boot();
Index: src/sys/stand/efiboot/efifdt.c
diff -u src/sys/stand/efiboot/efifdt.c:1.21 src/sys/stand/efiboot/efifdt.c:1.22
--- src/sys/stand/efiboot/efifdt.c:1.21 Fri Jan 3 14:14:56 2020
+++ src/sys/stand/efiboot/efifdt.c Thu May 14 19:20:08 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.c,v 1.21 2020/01/03 14:14:56 skrll Exp $ */
+/* $NetBSD: efifdt.c,v 1.22 2020/05/14 19:20:08 riastradh Exp $ */
/*-
* Copyright (c) 2019 Jason R. Thorpe
@@ -391,6 +391,7 @@ efi_fdt_initrd(u_long initrd_addr, u_lon
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 @@ efi_fdt_rndseed(u_long rndseed_addr, u_l
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);
+}
Index: src/sys/stand/efiboot/efifdt.h
diff -u src/sys/stand/efiboot/efifdt.h:1.7 src/sys/stand/efiboot/efifdt.h:1.8
--- src/sys/stand/efiboot/efifdt.h:1.7 Wed Dec 18 21:46:03 2019
+++ src/sys/stand/efiboot/efifdt.h Thu May 14 19:20:08 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.h,v 1.7 2019/12/18 21:46:03 riastradh Exp $ */
+/* $NetBSD: efifdt.h,v 1.8 2020/05/14 19:20:08 riastradh Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -38,5 +38,6 @@ void efi_fdt_show(void);
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);
Index: src/sys/stand/efiboot/exec.c
diff -u src/sys/stand/efiboot/exec.c:1.13 src/sys/stand/efiboot/exec.c:1.14
--- src/sys/stand/efiboot/exec.c:1.13 Sat Jan 25 10:53:13 2020
+++ src/sys/stand/efiboot/exec.c Thu May 14 19:20:08 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.13 2020/01/25 10:53:13 jmcneill Exp $ */
+/* $NetBSD: exec.c,v 1.14 2020/05/14 19:20:08 riastradh Exp $ */
/*-
* Copyright (c) 2019 Jason R. Thorpe
@@ -31,6 +31,7 @@
#include "efienv.h"
#include "efifdt.h"
#include "efiacpi.h"
+#include "efirng.h"
#include <sys/reboot.h>
@@ -41,8 +42,8 @@ u_long load_offset = 0;
#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 @@ load_fdt_overlays(void)
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 @@ exec_netbsd(const char *fname, const cha
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 @@ exec_netbsd(const char *fname, const cha
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())