[PATCH 3/5] hw_random: add EFI RNG driver
Ahmad Fatoum
a.fatoum at pengutronix.de
Sun Oct 9 23:08:40 PDT 2022
The EFI_RNG_PROTOCOL_GUID is quite simple and as such was a good first
protocol to implement for the barebox EFI loader support. We don't yet
have a payload-side driver making use of it though, so add that here.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
common/efi/guid.c | 1 +
drivers/hw_random/Kconfig | 7 +++++
drivers/hw_random/Makefile | 1 +
drivers/hw_random/efi-rng.c | 53 +++++++++++++++++++++++++++++++++++++
include/efi.h | 18 +++++++++++++
5 files changed, 80 insertions(+)
create mode 100644 drivers/hw_random/efi-rng.c
diff --git a/common/efi/guid.c b/common/efi/guid.c
index f16c597a20fc..93418d57b469 100644
--- a/common/efi/guid.c
+++ b/common/efi/guid.c
@@ -11,6 +11,7 @@ efi_guid_t efi_unknown_device_guid = EFI_UNKNOWN_DEVICE_GUID;
efi_guid_t efi_null_guid = EFI_NULL_GUID;
efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_guid_t efi_block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
+efi_guid_t efi_rng_protocol_guid = EFI_RNG_PROTOCOL_GUID;
efi_guid_t efi_barebox_vendor_guid = EFI_BAREBOX_VENDOR_GUID;
efi_guid_t efi_systemd_vendor_guid = EFI_SYSTEMD_VENDOR_GUID;
diff --git a/drivers/hw_random/Kconfig b/drivers/hw_random/Kconfig
index 32b84b028b0e..bf86240623c4 100644
--- a/drivers/hw_random/Kconfig
+++ b/drivers/hw_random/Kconfig
@@ -44,4 +44,11 @@ config HW_RANDOM_STARFIVE
This driver provides barebox support for the Random Number
Generator hardware found on the StarFive family of SoCs.
+config HW_RANDOM_EFI
+ tristate "EFI Random Number Generator"
+ depends on EFI
+ help
+ This driver provides barebox support for the Random Number
+ Generator Protocol offered by EFI firmware
+
endif
diff --git a/drivers/hw_random/Makefile b/drivers/hw_random/Makefile
index 6fe21bb84c28..9ea064340916 100644
--- a/drivers/hw_random/Makefile
+++ b/drivers/hw_random/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_HWRNG_STM32) += stm32-rng.o
obj-$(CONFIG_HWRNG_DEV_RANDOM) += dev-random.o
obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
obj-$(CONFIG_HW_RANDOM_STARFIVE) += starfive-vic-rng.o
+obj-$(CONFIG_HW_RANDOM_EFI) += efi-rng.o
diff --git a/drivers/hw_random/efi-rng.c b/drivers/hw_random/efi-rng.c
new file mode 100644
index 000000000000..b74075e3a4ac
--- /dev/null
+++ b/drivers/hw_random/efi-rng.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <linux/hw_random.h>
+#include <efi/efi-util.h>
+#include <efi/efi-device.h>
+
+struct efi_rng_priv {
+ struct efi_rng_protocol *protocol;
+ struct hwrng hwrng;
+};
+
+static inline struct efi_rng_priv *to_efi_rng(struct hwrng *hwrng)
+{
+ return container_of(hwrng, struct efi_rng_priv, hwrng);
+}
+
+static int efi_rng_read(struct hwrng *hwrng, void *data, size_t len, bool wait)
+{
+ struct efi_rng_protocol *protocol = to_efi_rng(hwrng)->protocol;
+ efi_status_t efiret;
+
+ efiret = protocol->get_rng(protocol, NULL, len, data);
+
+ return -efi_errno(efiret) ?: len;
+}
+
+static int efi_rng_probe(struct efi_device *efidev)
+{
+ struct efi_rng_priv *priv;
+
+ priv = xzalloc(sizeof(*priv));
+
+ BS->handle_protocol(efidev->handle, &efi_rng_protocol_guid,
+ (void **)&priv->protocol);
+ if (!priv->protocol)
+ return -ENODEV;
+
+ priv->hwrng.name = dev_name(&efidev->dev);
+ priv->hwrng.read = efi_rng_read;
+
+ return hwrng_register(&efidev->dev, &priv->hwrng);
+}
+
+static struct efi_driver efi_rng_driver = {
+ .driver = {
+ .name = "efi-rng",
+ },
+ .probe = efi_rng_probe,
+ .guid = EFI_RNG_PROTOCOL_GUID,
+};
+device_efi_driver(efi_rng_driver);
diff --git a/include/efi.h b/include/efi.h
index 864158259c53..149c4e74c6cb 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -538,6 +538,7 @@ extern efi_guid_t efi_unknown_device_guid;
extern efi_guid_t efi_null_guid;
extern efi_guid_t efi_global_variable_guid;
extern efi_guid_t efi_block_io_protocol_guid;
+extern efi_guid_t efi_rng_protocol_guid;
extern efi_guid_t efi_barebox_vendor_guid;
extern efi_guid_t efi_systemd_vendor_guid;
@@ -691,4 +692,21 @@ char *device_path_to_partuuid(struct efi_device_path *dev_path);
const char *efi_guid_string(efi_guid_t *g);
+#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,
+ size_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,
+ size_t rng_value_length, uint8_t *rng_value);
+};
+
#endif /* _LINUX_EFI_H */
--
2.30.2
More information about the barebox
mailing list