aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-12-16 11:07:20 -0500
committerTom Rini <trini@konsulko.com>2023-12-16 11:08:09 -0500
commited346475d1231a636f1ce55a52f4e51a07c95a34 (patch)
tree4d481cabda4f6f6439c9df4f9fc89cf47276b896
parentcd948210332783c2b1c6d10a982a80c0da4f69b9 (diff)
parent2fd5e1c11bc665eb573358a8c618373d4265bd21 (diff)
downloadu-boot-WIP/16Dec2023-next.zip
u-boot-WIP/16Dec2023-next.tar.gz
u-boot-WIP/16Dec2023-next.tar.bz2
Merge patch series "Populate kaslr seed with RNG"WIP/16Dec2023-next
To quote the author: This patch series creates a common API (fdt_fixup_kaslr_seed()) for populating the kaslr seed in the DTB. Existing users (kaslrseed, and ARMv8 sec firmware) have been updated to use this common API. New functionality has been introduced to populate the kaslr using the RNG. This can be enabled with CONFIG_RNG_TPM_SEED.
-rw-r--r--arch/arm/cpu/armv8/sec_firmware.c39
-rw-r--r--boot/fdt_support.c54
-rw-r--r--cmd/kaslrseed.c20
-rw-r--r--configs/sandbox_defconfig2
-rw-r--r--drivers/core/Kconfig3
-rw-r--r--drivers/core/ofnode.c29
-rw-r--r--include/dm/ofnode.h12
-rw-r--r--include/fdt_support.h9
-rw-r--r--lib/Kconfig7
9 files changed, 129 insertions, 46 deletions
diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c
index c0e8726..5f25693 100644
--- a/arch/arm/cpu/armv8/sec_firmware.c
+++ b/arch/arm/cpu/armv8/sec_firmware.c
@@ -411,46 +411,35 @@ int sec_firmware_init(const void *sec_firmware_img,
/*
* fdt_fix_kaslr - Add kalsr-seed node in Device tree
* @fdt: Device tree
- * @eret: 0 in case of error, 1 for success
+ * @eret: 0 for success
*/
int fdt_fixup_kaslr(void *fdt)
{
- int nodeoffset;
- int err, ret = 0;
- u8 rand[8];
+ int ret = 0;
#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)
+ u8 rand[8];
+ ofnode root;
+
/* Check if random seed generation is supported */
if (sec_firmware_support_hwrng() == false) {
printf("WARNING: SEC firmware not running, no kaslr-seed\n");
- return 0;
+ return -EOPNOTSUPP;
}
- err = sec_firmware_get_random(rand, 8);
- if (err < 0) {
+ ret = sec_firmware_get_random(rand, 8);
+ if (ret < 0) {
printf("WARNING: No random number to set kaslr-seed\n");
- return 0;
+ return ret;
}
- err = fdt_check_header(fdt);
- if (err < 0) {
- printf("fdt_chosen: %s\n", fdt_strerror(err));
- return 0;
+ ret = ofnode_root_from_fdt(fdt, &root);
+ if (ret < 0) {
+ printf("WARNING: Unable to get root ofnode\n");
+ return ret;
}
- /* find or create "/chosen" node. */
- nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
- if (nodeoffset < 0)
- return 0;
-
- err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", rand,
- sizeof(rand));
- if (err < 0) {
- printf("WARNING: can't set kaslr-seed %s.\n",
- fdt_strerror(err));
- return 0;
- }
- ret = 1;
+ ret = fdt_fixup_kaslr_seed(root, rand, sizeof(rand));
#endif
return ret;
diff --git a/boot/fdt_support.c b/boot/fdt_support.c
index 090d82e..89f4753 100644
--- a/boot/fdt_support.c
+++ b/boot/fdt_support.c
@@ -12,7 +12,10 @@
#include <log.h>
#include <mapmem.h>
#include <net.h>
+#include <rng.h>
#include <stdio_dev.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
#include <dm/ofnode.h>
#include <linux/ctype.h>
#include <linux/types.h>
@@ -631,6 +634,57 @@ void fdt_fixup_ethernet(void *fdt)
}
}
+int fdt_fixup_kaslr_seed(ofnode node, const u8 *seed, int len)
+{
+ ofnode chosen;
+ int ret;
+
+ /* find or create "/chosen" node. */
+ ret = ofnode_add_subnode(node, "chosen", &chosen);
+ if (ret && ret != -EEXIST)
+ return -ENOENT;
+
+ ret = ofnode_write_prop(chosen, "kaslr-seed", seed, len, true);
+ if (ret) {
+ printf("WARNING: can't set kaslr-seed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_KASLR_RNG_SEED)
+int fdt_rng_kaslr_seed(void *ctx, struct event *event)
+{
+ u8 rand[8] = {0};
+ struct udevice *dev;
+ int ret;
+ oftree tree = event->data.ft_fixup.tree;
+ ofnode root_node = oftree_root(tree);
+
+ ret = uclass_first_device_err(UCLASS_RNG, &dev);
+ if (ret) {
+ printf("ERROR: Failed to find RNG device\n");
+ return ret;
+ }
+
+ ret = dm_rng_read(dev, rand, sizeof(rand));
+ if (ret) {
+ printf("ERROR: RNG read failed, ret=%d\n", ret);
+ return ret;
+ }
+
+ ret = fdt_fixup_kaslr_seed(root_node, rand, sizeof(rand));
+ if (ret) {
+ printf("ERROR: failed to add kaslr-seed to fdt\n");
+ return ret;
+ }
+
+ return 0;
+}
+EVENT_SPY_FULL(EVT_FT_FIXUP, fdt_rng_kaslr_seed);
+#endif
+
int fdt_record_loadable(void *blob, u32 index, const char *name,
uintptr_t load_addr, u32 size, uintptr_t entry_point,
const char *type, const char *os, const char *arch)
diff --git a/cmd/kaslrseed.c b/cmd/kaslrseed.c
index 9acb8e1..9339d82 100644
--- a/cmd/kaslrseed.c
+++ b/cmd/kaslrseed.c
@@ -19,7 +19,7 @@ static int do_kaslr_seed(struct cmd_tbl *cmdtp, int flag, int argc, char *const
size_t n = 0x8;
struct udevice *dev;
u64 *buf;
- int nodeoffset;
+ ofnode root;
int ret = CMD_RET_SUCCESS;
if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
@@ -45,21 +45,15 @@ static int do_kaslr_seed(struct cmd_tbl *cmdtp, int flag, int argc, char *const
return CMD_RET_FAILURE;
}
- ret = fdt_check_header(working_fdt);
- if (ret < 0) {
- printf("fdt_chosen: %s\n", fdt_strerror(ret));
+ ret = ofnode_root_from_fdt(working_fdt, &root);
+ if (ret) {
+ printf("ERROR: Unable to get root ofnode\n");
return CMD_RET_FAILURE;
}
- nodeoffset = fdt_find_or_add_subnode(working_fdt, 0, "chosen");
- if (nodeoffset < 0) {
- printf("Reading chosen node failed\n");
- return CMD_RET_FAILURE;
- }
-
- ret = fdt_setprop(working_fdt, nodeoffset, "kaslr-seed", buf, sizeof(buf));
- if (ret < 0) {
- printf("Unable to set kaslr-seed on chosen node: %s\n", fdt_strerror(ret));
+ ret = fdt_fixup_kaslr_seed(root, (u8 *)buf, sizeof(buf));
+ if (ret) {
+ printf("ERROR: failed to add kaslr-seed to fdt\n");
return CMD_RET_FAILURE;
}
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index af3e7d8..f714a1e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -358,4 +358,4 @@ CONFIG_EFI_SECURE_BOOT=y
CONFIG_TEST_FDTDEC=y
CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
-CONFIG_UT_DM=y
+CONFIG_UT_DM=y \ No newline at end of file
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 1081d61..a962584 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -423,7 +423,8 @@ config DM_DEV_READ_INLINE
config OFNODE_MULTI_TREE
bool "Allow the ofnode interface to access any tree"
- default y if EVENT && !DM_DEV_READ_INLINE && !DM_INLINE_OFNODE
+ depends on OF_CONTROL
+ default y
help
Normally U-Boot makes use of its control FDT, the one used to bind
devices and provide options. In some cases, U-Boot must also process
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 21a233f..ab6a5ad 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -140,12 +140,6 @@ int oftree_new(oftree *treep)
return 0;
}
-void oftree_dispose(oftree tree)
-{
- if (of_live_active())
- of_live_free(tree.np);
-}
-
void *ofnode_lookup_fdt(ofnode node)
{
if (gd->flags & GD_FLG_RELOC) {
@@ -248,6 +242,12 @@ int oftree_new(oftree *treep)
#endif /* OFNODE_MULTI_TREE */
+void oftree_dispose(oftree tree)
+{
+ if (of_live_active())
+ of_live_free(tree.np);
+}
+
int oftree_to_fdt(oftree tree, struct abuf *buf)
{
int ret;
@@ -971,6 +971,23 @@ ofnode oftree_path(oftree tree, const char *path)
}
}
+int ofnode_root_from_fdt(void *fdt, ofnode *root_node)
+{
+ oftree tree;
+ /* If OFNODE_MULTI_TREE is not set, and if fdt is not the control FDT,
+ * oftree_from_fdt() will return NULL
+ */
+ tree = oftree_from_fdt(fdt);
+
+ if (!oftree_valid(tree)) {
+ printf("Cannot create oftree\n");
+ return -EINVAL;
+ }
+ *root_node = oftree_root(tree);
+
+ return 0;
+}
+
const void *ofnode_read_chosen_prop(const char *propname, int *sizep)
{
ofnode chosen_node;
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 5795115..b3bb133 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -937,6 +937,18 @@ ofnode oftree_path(oftree tree, const char *path);
ofnode oftree_root(oftree tree);
/**
+ * ofnode_root_from_fdt() - Gets the root ofnode given an FDT blob.
+ * Note, this will fail if OFNODE_MULTI_TREE
+ * is not set.
+ *
+ * @fdt: Device tree to use
+ * @root_node : Root ofnode
+ *
+ * Return: 0 if OK, -ve on error
+ */
+int ofnode_root_from_fdt(void *fdt, ofnode *root_node);
+
+/**
* ofnode_read_chosen_prop() - get the value of a chosen property
*
* This looks for a property within the /chosen node and returns its value.
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 25600d6..804ca7f 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -10,6 +10,7 @@
#if !defined(USE_HOSTCC)
#include <asm/u-boot.h>
+#include <dm/ofnode_decl.h>
#include <linux/libfdt.h>
#include <abuf.h>
@@ -130,6 +131,14 @@ static inline int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[],
#endif
void fdt_fixup_ethernet(void *fdt);
+
+/*
+ * fdt_fixup_kaslr_seed - Add kaslr-seed node in Device tree
+ * @node: ofnode
+ * @eret: 0 for success
+ */
+int fdt_fixup_kaslr_seed(ofnode node, const u8 *seed, int len);
+
int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
const void *val, int len, int create);
void fdt_fixup_qe_firmware(void *fdt);
diff --git a/lib/Kconfig b/lib/Kconfig
index 9ae846e..da19613 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -484,6 +484,13 @@ config VPL_TPM
for the low-level TPM interface, but only one TPM is supported at
a time by the TPM library.
+config KASLR_RNG_SEED
+ bool "Use RNG driver for KASLR random seed"
+ depends on DM_RNG
+ help
+ This enables support for using the RNG driver as entropy source for
+ KASLR seed populated in kernel's device tree.
+
endmenu
menu "Android Verified Boot"