mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-15 11:41:31 +00:00
efi: qemu: arm64: Add efi_rng_protocol implementation for the platform
Add support for the EFI_RNG_PROTOCOL routines for the qemu arm64 platform. EFI_RNG_PROTOCOL is an uefi boottime service which is invoked by the efi stub in the kernel for getting random seed for kaslr. The routines are platform specific, and use the virtio-rng device on the platform to get random data. The feature can be enabled through the following config CONFIG_EFI_RNG_PROTOCOL Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> Changed SPDX header to use /* instead of //. Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
4f24ac08af
commit
f552fa496c
5 changed files with 195 additions and 0 deletions
|
@ -91,3 +91,45 @@ void *board_fdt_blob_setup(void)
|
|||
/* QEMU loads a generated DTB for us at the start of RAM. */
|
||||
return (void *)CONFIG_SYS_SDRAM_BASE;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_EFI_RNG_PROTOCOL)
|
||||
#include <efi_loader.h>
|
||||
#include <efi_rng.h>
|
||||
|
||||
#include <dm/device-internal.h>
|
||||
|
||||
efi_status_t platform_get_rng_device(struct udevice **dev)
|
||||
{
|
||||
int ret;
|
||||
efi_status_t status = EFI_DEVICE_ERROR;
|
||||
struct udevice *bus, *devp;
|
||||
|
||||
for (uclass_first_device(UCLASS_VIRTIO, &bus); bus;
|
||||
uclass_next_device(&bus)) {
|
||||
for (device_find_first_child(bus, &devp); devp;
|
||||
device_find_next_child(&devp)) {
|
||||
if (device_get_uclass_id(devp) == UCLASS_RNG) {
|
||||
*dev = devp;
|
||||
status = EFI_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
debug("No rng device found\n");
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (*dev) {
|
||||
ret = device_probe(*dev);
|
||||
if (ret)
|
||||
return EFI_DEVICE_ERROR;
|
||||
} else {
|
||||
debug("Couldn't get child device\n");
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
#endif /* CONFIG_EFI_RNG_PROTOCOL */
|
||||
|
|
32
include/efi_rng.h
Normal file
32
include/efi_rng.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2019, Linaro Limited
|
||||
*/
|
||||
|
||||
#if !defined _EFI_RNG_H_
|
||||
#define _EFI_RNG_H_
|
||||
|
||||
#include <efi.h>
|
||||
#include <efi_api.h>
|
||||
|
||||
/* EFI random number generation protocol related GUID definitions */
|
||||
#define EFI_RNG_PROTOCOL_GUID \
|
||||
EFI_GUID(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, \
|
||||
0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
|
||||
|
||||
#define EFI_RNG_ALGORITHM_RAW \
|
||||
EFI_GUID(0xe43176d7, 0xb6e8, 0x4827, 0xb7, 0x84, \
|
||||
0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61)
|
||||
|
||||
struct efi_rng_protocol {
|
||||
efi_status_t (EFIAPI *get_info)(struct efi_rng_protocol *protocol,
|
||||
efi_uintn_t *rng_algorithm_list_size,
|
||||
efi_guid_t *rng_algorithm_list);
|
||||
efi_status_t (EFIAPI *get_rng)(struct efi_rng_protocol *protocol,
|
||||
efi_guid_t *rng_algorithm,
|
||||
efi_uintn_t rng_value_length, uint8_t *rng_value);
|
||||
};
|
||||
|
||||
efi_status_t platform_get_rng_device(struct udevice **dev);
|
||||
|
||||
#endif /* _EFI_RNG_H_ */
|
|
@ -121,4 +121,12 @@ config EFI_GRUB_ARM32_WORKAROUND
|
|||
GRUB prior to version 2.04 requires U-Boot to disable caches. This
|
||||
workaround currently is also needed on systems with caches that
|
||||
cannot be managed via CP15.
|
||||
|
||||
config EFI_RNG_PROTOCOL
|
||||
bool "EFI_RNG_PROTOCOL support"
|
||||
depends on DM_RNG
|
||||
help
|
||||
"Support for EFI_RNG_PROTOCOL implementation. Uses the rng
|
||||
device on the platform"
|
||||
|
||||
endif
|
||||
|
|
|
@ -42,3 +42,4 @@ obj-$(CONFIG_PARTITIONS) += efi_disk.o
|
|||
obj-$(CONFIG_NET) += efi_net.o
|
||||
obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o
|
||||
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o
|
||||
obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o
|
||||
|
|
112
lib/efi_loader/efi_rng.c
Normal file
112
lib/efi_loader/efi_rng.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2019, Linaro Limited
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <efi_loader.h>
|
||||
#include <efi_rng.h>
|
||||
#include <rng.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
__weak efi_status_t platform_get_rng_device(struct udevice **dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *devp;
|
||||
|
||||
ret = uclass_get_device(UCLASS_RNG, 0, &devp);
|
||||
if (ret) {
|
||||
debug("Unable to get rng device\n");
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
*dev = devp;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
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_status_t ret = EFI_SUCCESS;
|
||||
efi_guid_t rng_algo_guid = EFI_RNG_ALGORITHM_RAW;
|
||||
|
||||
EFI_ENTRY("%p, %p, %p", this, rng_algorithm_list_size,
|
||||
rng_algorithm_list);
|
||||
|
||||
if (!this || !rng_algorithm_list_size) {
|
||||
ret = EFI_INVALID_PARAMETER;
|
||||
goto back;
|
||||
}
|
||||
|
||||
if (!rng_algorithm_list ||
|
||||
*rng_algorithm_list_size < sizeof(*rng_algorithm_list)) {
|
||||
*rng_algorithm_list_size = sizeof(*rng_algorithm_list);
|
||||
ret = EFI_BUFFER_TOO_SMALL;
|
||||
goto back;
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, use EFI_RNG_ALGORITHM_RAW as the default
|
||||
* algorithm. If a new algorithm gets added in the
|
||||
* future through a Kconfig, rng_algo_guid will be set
|
||||
* based on that Kconfig option
|
||||
*/
|
||||
*rng_algorithm_list_size = sizeof(*rng_algorithm_list);
|
||||
guidcpy(rng_algorithm_list, &rng_algo_guid);
|
||||
|
||||
back:
|
||||
return EFI_EXIT(ret);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
efi_status_t status = EFI_SUCCESS;
|
||||
struct udevice *dev;
|
||||
const efi_guid_t rng_raw_guid = EFI_RNG_ALGORITHM_RAW;
|
||||
|
||||
EFI_ENTRY("%p, %p, %zu, %p", this, rng_algorithm, rng_value_length,
|
||||
rng_value);
|
||||
|
||||
if (!this || !rng_value || !rng_value_length) {
|
||||
status = EFI_INVALID_PARAMETER;
|
||||
goto back;
|
||||
}
|
||||
|
||||
if (rng_algorithm) {
|
||||
EFI_PRINT("RNG algorithm %pUl\n", rng_algorithm);
|
||||
if (guidcmp(rng_algorithm, &rng_raw_guid)) {
|
||||
status = EFI_UNSUPPORTED;
|
||||
goto back;
|
||||
}
|
||||
}
|
||||
|
||||
ret = platform_get_rng_device(&dev);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
EFI_PRINT("Rng device not found\n");
|
||||
status = EFI_UNSUPPORTED;
|
||||
goto back;
|
||||
}
|
||||
|
||||
ret = dm_rng_read(dev, rng_value, rng_value_length);
|
||||
if (ret < 0) {
|
||||
EFI_PRINT("Rng device read failed\n");
|
||||
status = EFI_DEVICE_ERROR;
|
||||
goto back;
|
||||
}
|
||||
|
||||
back:
|
||||
return EFI_EXIT(status);
|
||||
}
|
||||
|
||||
const struct efi_rng_protocol efi_rng_protocol = {
|
||||
.get_info = rng_getinfo,
|
||||
.get_rng = getrng,
|
||||
};
|
Loading…
Add table
Reference in a new issue