efi: stub: implement efi_get_random_bytes() based on EFI_RNG_PROTOCOL
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sun, 10 Jan 2016 10:29:07 +0000 (11:29 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Wed, 24 Feb 2016 14:57:28 +0000 (14:57 +0000)
This exposes the firmware's implementation of EFI_RNG_PROTOCOL via a new
function efi_get_random_bytes().

Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
drivers/firmware/efi/libstub/Makefile
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/libstub/random.c [new file with mode: 0644]
include/linux/efi.h

index aaf9c0b..ad07794 100644 (file)
@@ -36,7 +36,7 @@ lib-$(CONFIG_EFI_ARMSTUB)     += arm-stub.o fdt.o string.o \
                                   $(patsubst %.c,lib-%.o,$(arm-deps))
 
 lib-$(CONFIG_ARM)              += arm32-stub.o
-lib-$(CONFIG_ARM64)            += arm64-stub.o
+lib-$(CONFIG_ARM64)            += arm64-stub.o random.o
 CFLAGS_arm64-stub.o            := -DTEXT_OFFSET=$(TEXT_OFFSET)
 
 #
index 6b6548f..206b725 100644 (file)
@@ -43,4 +43,7 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
                     unsigned long desc_size, efi_memory_desc_t *runtime_map,
                     int *count);
 
+efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table,
+                                 unsigned long size, u8 *out);
+
 #endif
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
new file mode 100644 (file)
index 0000000..97941ee
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Linaro Ltd;  <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "efistub.h"
+
+struct efi_rng_protocol {
+       efi_status_t (*get_info)(struct efi_rng_protocol *,
+                                unsigned long *, efi_guid_t *);
+       efi_status_t (*get_rng)(struct efi_rng_protocol *,
+                               efi_guid_t *, unsigned long, u8 *out);
+};
+
+efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg,
+                                 unsigned long size, u8 *out)
+{
+       efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+       efi_status_t status;
+       struct efi_rng_protocol *rng;
+
+       status = efi_call_early(locate_protocol, &rng_proto, NULL,
+                               (void **)&rng);
+       if (status != EFI_SUCCESS)
+               return status;
+
+       return rng->get_rng(rng, NULL, size, out);
+}
index 569b5a8..e747eb0 100644 (file)
@@ -299,7 +299,7 @@ typedef struct {
        void *open_protocol_information;
        void *protocols_per_handle;
        void *locate_handle_buffer;
-       void *locate_protocol;
+       efi_status_t (*locate_protocol)(efi_guid_t *, void *, void **);
        void *install_multiple_protocol_interfaces;
        void *uninstall_multiple_protocol_interfaces;
        void *calculate_crc32;
@@ -599,6 +599,10 @@ void efi_native_runtime_setup(void);
 #define EFI_PROPERTIES_TABLE_GUID \
     EFI_GUID(  0x880aaca3, 0x4adc, 0x4a04, 0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5 )
 
+#define EFI_RNG_PROTOCOL_GUID \
+       EFI_GUID(0x3152bca5, 0xeade, 0x433d, \
+                0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
+
 typedef struct {
        efi_guid_t guid;
        u64 table;