Re: efistub: EFI_RNG_PROTOCOL on Dell Inc. Latitude 7390

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Oct 28, 2019 at 11:51:01AM +0100, Ard Biesheuvel wrote:
> > It might be an issue with the size of the output.
> >
> > The original RDRAND based driver in EDK2 contains an apparent
> > misconception that, due to the fact that certain SP800-90-CTR-256
> > DRBGs require 32 bytes of raw entropy as a seed, it is only valid for
> > the RAW algorithm to be called with an output size of 32.
> >
> > So in this case, it might be that 32 is treated as a magic number too,
> > and any other size is rejected by the RAW algorithm.
> >
> > Not sure why the other one fails, though, but the fact that RAW and
> > SP800-90-CTR-256 are the only supported algorithms suggests that your
> > implementation is at least similar to the RDRAND based RngDxe
> > implementation in EDK2.
> 
> I've updated the RngTest-X64.efi binary with a version that invokes
> both the RAW and the default algorithm twice with a request for 64
> bytes of entropy, like we do in the kernel. It runs fine on my
> Thinkpad, can you check whether it works on your Dell system as well?

RngTest-X64.efi seems to run through fine.[*] Additionally, if I modify the
kernel code to request only 32 bytes, it returns EFI_INVALID_PARAMETER as
well. So something else seems to be missing... Just to verify: does
efi_random_get_seed() work on your Thinkpad, if called from efi_main()? Have
you tested that, by chance?[**]

Thanks,
	Dominik


[*] As a sidenote: I say "seems" as the screen is immediately blanked
once the RngTest-X64.efi binary has run through, so I have to capture the
output with a camera. Maybe add a delay of some sort to the RngTest-X86.efi
binary?

[**] patch with additional debug outputs (on top of Linus' tree) here:


diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index d6662fdef300..4b909e5ab857 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -781,6 +781,9 @@ efi_main(struct efi_config *c, struct boot_params *boot_params)
 
 	/* Ask the firmware to clear memory on unclean shutdown */
 	efi_enable_reset_attack_mitigation(sys_table);
+
+	efi_random_get_seed(sys_table);
+
 	efi_retrieve_tpm2_eventlog(sys_table);
 
 	setup_graphics(boot_params);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index de434feb873a..45572b7e0548 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -2515,6 +2515,14 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
  */
 void add_bootloader_randomness(const void *buf, unsigned int size)
 {
+	unsigned long *data = buf;
+
+	pr_notice("random: adding %u bits of %sbootloader-provided randomness",
+		size * 8,
+		IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER) ? "trusted " : "");
+
+	pr_notice("random: is this random? %lx", *data);
+
 	if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
 		add_hwgenerator_randomness(buf, size, size * 8);
 	else
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 69f00f7453a3..e98bbf8e56d9 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -554,7 +554,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
 					      sizeof(*seed) + size);
 			if (seed != NULL) {
 				pr_notice("seeding entropy pool\n");
-				add_device_randomness(seed->bits, seed->size);
+				add_bootloader_randomness(seed->bits, seed->size);
 				early_memunmap(seed, sizeof(*seed) + size);
 			} else {
 				pr_err("Could not map UEFI random seed!\n");
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 0460c7581220..ece24c60fc2c 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -38,7 +38,8 @@ OBJECT_FILES_NON_STANDARD	:= y
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
 KCOV_INSTRUMENT			:= n
 
-lib-y				:= efi-stub-helper.o gop.o secureboot.o tpm.o
+lib-y				:= efi-stub-helper.o gop.o secureboot.o tpm.o \
+				   random.o
 
 # include the stub's generic dependencies from lib/ when building for ARM/arm64
 arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
@@ -47,7 +48,7 @@ arm-deps-$(CONFIG_ARM64) += sort.c
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
-lib-$(CONFIG_EFI_ARMSTUB)	+= arm-stub.o fdt.o string.o random.o \
+lib-$(CONFIG_EFI_ARMSTUB)	+= arm-stub.o fdt.o string.o \
 				   $(patsubst %.c,lib-%.o,$(arm-deps-y))
 
 lib-$(CONFIG_ARM)		+= arm32-stub.o
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 7f1556fd867d..05739ae013c8 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -63,8 +63,6 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
 
 efi_status_t check_platform_features(efi_system_table_t *sys_table_arg);
 
-efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg);
-
 void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid);
 
 /* Helper macros for the usual case of using simple C variables: */
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
index b4b1d1dcb5fd..70612cdd62c8 100644
--- a/drivers/firmware/efi/libstub/random.c
+++ b/drivers/firmware/efi/libstub/random.c
@@ -152,33 +152,49 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
 
 	status = efi_call_early(locate_protocol, &rng_proto, NULL,
 				(void **)&rng);
-	if (status != EFI_SUCCESS)
+	if (status != EFI_SUCCESS) {
+		pr_efi_err(sys_table_arg, "random: no protocol");
 		return status;
+	}
 
 	status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
 				sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
 				(void **)&seed);
-	if (status != EFI_SUCCESS)
+	if (status != EFI_SUCCESS){
+		pr_efi_err(sys_table_arg, "random: no pool");
 		return status;
+	}
 
 	status = rng->get_rng(rng, &rng_algo_raw, EFI_RANDOM_SEED_SIZE,
 			      seed->bits);
-	if (status == EFI_UNSUPPORTED)
+	if (status == EFI_DEVICE_ERROR)
+		pr_efi_err(sys_table_arg, "random: device error");
+	if (status == EFI_NOT_READY)
+		pr_efi_err(sys_table_arg, "random: not ready");
+	if (status == EFI_INVALID_PARAMETER)
+		pr_efi_err(sys_table_arg, "random: invalid parameter"); // that's the reason...
+	if (status == EFI_UNSUPPORTED) {
 		/*
 		 * Use whatever algorithm we have available if the raw algorithm
 		 * is not implemented.
 		 */
+
 		status = rng->get_rng(rng, NULL, EFI_RANDOM_SEED_SIZE,
 				      seed->bits);
+	}
 
-	if (status != EFI_SUCCESS)
+	if (status != EFI_SUCCESS) {
+		pr_efi_err(sys_table_arg, "random: no bytes");
 		goto err_freepool;
+	}
 
 	seed->size = EFI_RANDOM_SEED_SIZE;
 	status = efi_call_early(install_configuration_table, &rng_table_guid,
 				seed);
-	if (status != EFI_SUCCESS)
+	if (status != EFI_SUCCESS) {
+		pr_efi_err(sys_table_arg, "random: install_configuration_table");
 		goto err_freepool;
+	}
 
 	return EFI_SUCCESS;
 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index bd3837022307..a17cc5841668 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1631,6 +1631,8 @@ static inline void
 efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { }
 #endif
 
+efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg);
+
 void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table);
 
 /*



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux