> From: "Theo de Raadt" <[email protected]>
> Date: Sat, 07 Apr 2018 15:26:30 -0600
>
> Mark Kettenis <[email protected]> wrote:
>
> > The UEFI firmware for the MACCHIATObin implements the EFI Random
> > Number Generator Protocol. That makes it possible to implement the
> > mdrandom() function for arm64's EFIBOOT. The random data is XORed
> > onto the buffer so bad random data can't hurt us.
> >
> > The code is written such that it can be easily dropped into our other
> > EFI bootloaders. That raises a question though. On amd64 we already
> > have an mdrandom() implementation. Should I call the function
> > fwrandom() instead and and an
> >
> > #ifdef FWRANDOM
> > fwrandom(rnddata, sizeof(rnddata));
> > #endif
> >
> > next to the mdrandom() call in boot.c?
>
> Yes, it should call every thing like that.
Here is a diff that implements that aproach.
ok?
Index: stand/boot/boot.c
===================================================================
RCS file: /cvs/src/sys/stand/boot/boot.c,v
retrieving revision 1.44
diff -u -p -r1.44 boot.c
--- stand/boot/boot.c 19 Jun 2017 22:50:50 -0000 1.44
+++ stand/boot/boot.c 8 Apr 2018 11:18:26 -0000
@@ -103,6 +103,9 @@ boot(dev_t bootdev)
#ifdef MDRANDOM
mdrandom(rnddata, sizeof(rnddata));
#endif
+#ifdef FWRANDOM
+ fwrandom(rnddata, sizeof(rnddata));
+#endif
st = 0;
bootprompt = 1; /* allow reselect should we fail */
Index: stand/boot/bootarg.h
===================================================================
RCS file: /cvs/src/sys/stand/boot/bootarg.h,v
retrieving revision 1.14
diff -u -p -r1.14 bootarg.h
--- stand/boot/bootarg.h 2 Sep 2015 01:52:26 -0000 1.14
+++ stand/boot/bootarg.h 8 Apr 2018 11:18:26 -0000
@@ -50,7 +50,8 @@ extern bootarg_t *bootargp;
#endif
void loadrandom(char *name, char *buf, size_t buflen);
-int mdrandom(char *buf, size_t buflen);
+void mdrandom(char *buf, size_t buflen);
+void fwrandom(char *buf, size_t buflen);
#ifdef _STANDALONE
void addbootarg(int, size_t, void *);
Index: arch/arm64/stand/efiboot/Makefile
===================================================================
RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/Makefile,v
retrieving revision 1.4
diff -u -p -r1.4 Makefile
--- arch/arm64/stand/efiboot/Makefile 31 Mar 2018 17:43:53 -0000 1.4
+++ arch/arm64/stand/efiboot/Makefile 8 Apr 2018 11:18:26 -0000
@@ -8,8 +8,8 @@ PROG= BOOTAA64.EFI
OBJFMT= binary
INSTALL_STRIP=
BINDIR= /usr/mdec
-SRCS= start.S self_reloc.c efiboot.c conf.c exec.c efidev.c efipxe.c
-SRCS+= fdt.c
+SRCS= start.S self_reloc.c efiboot.c conf.c exec.c efidev.c
+SRCS+= efipxe.c efirng.c fdt.c
S= ${.CURDIR}/../../../..
EFIDIR= ${S}/stand/efi
@@ -43,7 +43,7 @@ CPPFLAGS+= -I${S} -I. -I${.CURDIR}
CPPFLAGS+= -I${EFIDIR}/include -I${EFIDIR}/include/arm64
CPPFLAGS+= -D_STANDALONE
CPPFLAGS+= -DSMALL -DSLOW -DNOBYFOUR -D__INTERNAL_LIBSA_CREAD
-CPPFLAGS+= -DNEEDS_HEAP_H
+CPPFLAGS+= -DNEEDS_HEAP_H -DFWRANDOM
COPTS+= -Wno-attributes -Wno-format
COPTS+= -ffreestanding -fno-stack-protector
COPTS+= -fshort-wchar -fPIC -fno-builtin
Index: arch/arm64/stand/efiboot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/conf.c,v
retrieving revision 1.14
diff -u -p -r1.14 conf.c
--- arch/arm64/stand/efiboot/conf.c 31 Mar 2018 17:44:57 -0000 1.14
+++ arch/arm64/stand/efiboot/conf.c 8 Apr 2018 11:18:26 -0000
@@ -36,7 +36,7 @@
#include "efidev.h"
#include "efipxe.h"
-const char version[] = "0.12";
+const char version[] = "0.13";
int debug = 0;
struct fs_ops file_system[] = {
Index: arch/arm64/stand/efiboot/efirng.c
===================================================================
RCS file: arch/arm64/stand/efiboot/efirng.c
diff -N arch/arm64/stand/efiboot/efirng.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ arch/arm64/stand/efiboot/efirng.c 8 Apr 2018 11:18:26 -0000
@@ -0,0 +1,87 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2018 Mark Kettenis <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+
+#include <efi.h>
+#include <efiapi.h>
+
+#include "eficall.h"
+#include "libsa.h"
+
+extern EFI_BOOT_SERVICES *BS;
+
+/* Random Number Generator Protocol */
+
+#define EFI_RNG_PROTOCOL_GUID \
+ { 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f,
0x44} }
+
+INTERFACE_DECL(_EFI_RNG_PROTOCOL);
+
+typedef EFI_GUID EFI_RNG_ALGORITHM;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_INFO) (
+ IN struct _EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_RNG) (
+ IN struct _EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ );
+
+typedef struct _EFI_RNG_PROTOCOL {
+ EFI_RNG_GET_INFO GetInfo;
+ EFI_RNG_GET_RNG GetRNG;
+} EFI_RNG_PROTOCOL;
+
+static EFI_GUID rng_guid = EFI_RNG_PROTOCOL_GUID;
+
+void
+fwrandom(char *buf, size_t buflen)
+{
+ EFI_STATUS status;
+ EFI_RNG_PROTOCOL *rng = NULL;
+ UINT8 *random;
+ size_t i;
+
+ status = EFI_CALL(BS->LocateProtocol, &rng_guid, NULL, (void **)&rng);
+ if (rng == NULL || EFI_ERROR(status))
+ return;
+
+ random = alloc(buflen);
+
+ status = EFI_CALL(rng->GetRNG, rng, NULL, buflen, random);
+ if (EFI_ERROR(status)) {
+ printf("RNG GetRNG() failed (%d)\n", status);
+ goto out;
+ }
+
+ for (i = 0; i < buflen; i++)
+ buf[i] ^= random[i];
+
+out:
+ free(random, buflen);
+}