> From: "Theo de Raadt" <dera...@openbsd.org>
> Date: Sat, 07 Apr 2018 15:26:30 -0600
> 
> Mark Kettenis <mark.kette...@xs4all.nl> 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 <kette...@openbsd.org>
+ *
+ * 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);
+}

Reply via email to