[gbl] Implement software-based EFI_RNG_PROTOCOL Implement a software-based EFI_RNG_PROTOCOL using a Pseudo-Random Number Generator (LCG) seeded by the system timer. This is used when CONFIG_EFI_RNG_PROTOCOL (hardware-based) is disabled, satisfying GBL's requirement for generating stack canaries. TAG=agy CONV=236c2e4e-69e4-48b6-a8ea-8986bc68bb04 Change-Id: I0b00e0b37ef168d57111060a1454b449920784f5 Reviewed-on: https://turquoise-internal-review.googlesource.com/c/third_party/u-boot/+/1369888 Reviewed-by: David Pursell <dpursell@google.com> Commit-Queue: Sergii Parubochyi <sergiip@google.com> GitOrigin-RevId: ffe301df3f23f90350c526c9464eb37de022d887
diff --git a/board/khadas/Kconfig b/board/khadas/Kconfig index 34b9c8a..98db604 100644 --- a/board/khadas/Kconfig +++ b/board/khadas/Kconfig
@@ -42,3 +42,12 @@ source "board/khadas/kvim2/Kconfig" endif +# Note: EFI_RNG_NON_SECURE_SW_PROTOCOL is defined here because lib/efi_loader/Kconfig +# is not processed by the build system in this U-Boot fork. +config EFI_RNG_NON_SECURE_SW_PROTOCOL + bool "Software EFI_RNG_PROTOCOL support" + depends on !EFI_RNG_PROTOCOL + default n + help + Provide a software-based EFI_RNG_PROTOCOL implementation. +
diff --git a/board/khadas/defconfigs/kvim3_zircon_defconfig b/board/khadas/defconfigs/kvim3_zircon_defconfig index 7dc84e5..c5eca17 100644 --- a/board/khadas/defconfigs/kvim3_zircon_defconfig +++ b/board/khadas/defconfigs/kvim3_zircon_defconfig
@@ -9,3 +9,4 @@ CONFIG_AUTOBOOT_KEYED=y CONFIG_AUTOBOOT_STOP_STR="f" CONFIG_ZIRCON_VERIFIED_BOOT=y +CONFIG_EFI_RNG_NON_SECURE_SW_PROTOCOL=y
diff --git a/include/efi_loader.h b/include/efi_loader.h index 525a8ec..17f2175 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h
@@ -580,6 +580,7 @@ /* Called by efi_init_obj_list() to install EFI_ANDROID_BOOT_PROTOCOL */ efi_status_t efi_android_boot_register(void); efi_status_t efi_gbl_fastboot_transport_register(void); +efi_status_t efi_rng_sw_register(void); /* Called by efi_init_obj_list() to do initial measurement */ efi_status_t efi_tcg2_do_initial_measurement(void); /* measure the pe-coff image, extend PCR and add Event Log */
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 09f51ac..4d6d1ca 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o +obj-$(CONFIG_EFI_RNG_NON_SECURE_SW_PROTOCOL) += efi_rng_sw.o obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o
diff --git a/lib/efi_loader/efi_rng_sw.c b/lib/efi_loader/efi_rng_sw.c new file mode 100644 index 0000000..fd8d32a --- /dev/null +++ b/lib/efi_loader/efi_rng_sw.c
@@ -0,0 +1,98 @@ +/* + * Copyright (c) 2026 The Fuchsia Authors + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * WARNING: This is a software-based pseudo-random number generator (PRNG) + * intended ONLY for development and debugging. It uses U-Boot's native + * rand() which is NOT cryptographically secure. + * + * DO NOT use this implementation in production environments or for security- + * sensitive applications (e.g. key generation, cryptography). + */ + +#include <common.h> +#include <efi_loader.h> +#include <efi_rng.h> + +static const efi_guid_t rng_raw_guid = EFI_RNG_ALGORITHM_RAW; + +static efi_status_t EFIAPI rng_getinfo(struct efi_rng_protocol *this, + efi_uintn_t *rng_algorithm_list_size, + efi_guid_t *rng_algorithm_list) +{ + EFI_ENTRY("%p, %p, %p", this, rng_algorithm_list_size, + rng_algorithm_list); + + if (!this || !rng_algorithm_list_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (!rng_algorithm_list || + *rng_algorithm_list_size < sizeof(*rng_algorithm_list)) { + *rng_algorithm_list_size = sizeof(*rng_algorithm_list); + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + + *rng_algorithm_list_size = sizeof(*rng_algorithm_list); + guidcpy(rng_algorithm_list, &rng_raw_guid); + + return EFI_EXIT(EFI_SUCCESS); +} + +/* + * WARNING: U-Boot's rand() is a simple LCG and is NOT cryptographically + * secure. This is strictly for development and debugging. + * + * DO NOT use this implementation in production environments or for security- + * sensitive applications. + */ +static efi_status_t EFIAPI getrng(struct efi_rng_protocol *this, + efi_guid_t *rng_algorithm, + efi_uintn_t rng_value_length, + uint8_t *rng_value) +{ + EFI_ENTRY("%p, %p, %zu, %p", this, rng_algorithm, rng_value_length, + rng_value); + + if (!this || !rng_value || !rng_value_length) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (rng_algorithm) { + if (guidcmp(rng_algorithm, &rng_raw_guid)) + return EFI_EXIT(EFI_UNSUPPORTED); + } + + for (efi_uintn_t i = 0; i < rng_value_length; i++) { + rng_value[i] = rand() & 0xff; + } + + return EFI_EXIT(EFI_SUCCESS); +} + +static const struct efi_rng_protocol efi_rng_protocol = { + .get_info = rng_getinfo, + .get_rng = getrng, +}; + +const efi_guid_t efi_guid_rng_protocol = EFI_RNG_PROTOCOL_GUID; + +efi_status_t efi_rng_sw_register(void) +{ + efi_status_t ret; + + printf("\n*****************************************************************\n"); + printf("WARNING: Registering a SOFTWARE-BASED (INSECURE) EFI RNG Protocol!\n"); + printf("This is ONLY for development and debugging. DO NOT use in production!\n"); + printf("*****************************************************************\n\n"); + + srand(timer_get_us()); + + ret = efi_add_protocol(efi_root, &efi_guid_rng_protocol, + (void *)&efi_rng_protocol); + if (ret != EFI_SUCCESS) + printf("Cannot install software EFI_RNG_PROTOCOL\n"); + + return ret; +}
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 22337b3..1bdb868 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c
@@ -298,6 +298,11 @@ if (ret != EFI_SUCCESS) goto out; } + if (IS_ENABLED(CONFIG_EFI_RNG_NON_SECURE_SW_PROTOCOL)) { + ret = efi_rng_sw_register(); + if (ret != EFI_SUCCESS) + goto out; + } if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) { ret = efi_riscv_register();