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())

Reply via email to