From 2f18ee67fdf5eed9863d946d1a8440acf7939739 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Thu, 30 Nov 2023 16:54:40 -0800 Subject: fdt: common API to populate kaslr seed fdt_fixup_kaslr_seed() will update given ofnode with random seed value. Source for random seed can be TPM or RNG driver in u-boot or sec firmware (ARM). Signed-off-by: Dhananjay Phadke Signed-off-by: Sean Edmond --- arch/arm/cpu/armv8/sec_firmware.c | 39 ++++++++++++++------------------------- boot/fdt_support.c | 19 +++++++++++++++++++ drivers/core/ofnode.c | 17 +++++++++++++++++ include/dm/ofnode.h | 12 ++++++++++++ include/fdt_support.h | 9 +++++++++ 5 files changed, 71 insertions(+), 25 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 b15d077..49d14a9 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -631,6 +631,25 @@ 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; +} + 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/drivers/core/ofnode.c b/drivers/core/ofnode.c index f72ea41..557a4a1 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -966,6 +966,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 2cd8366..0624650 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -11,6 +11,7 @@ !defined(USE_HOSTCC) #include +#include #include #include @@ -121,6 +122,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); -- cgit v1.1 From f8aea7dff60a158aab8c1e086cf12ee1acc9cf42 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Thu, 30 Nov 2023 16:54:41 -0800 Subject: fdt: kaslr seed from RNG device Add support for KASLR seed from the RNG device. Invokes dm_rng_read() API to read 8-bytes of random bytes. Performs the FDT fixup using event spy. To enable use CONFIG_KASLR_RNG_SEED Signed-off-by: Dhananjay Phadke Signed-off-by: Drew Kluemke Signed-off-by: Sean Edmond Reviewed-by: Simon Glass --- boot/fdt_support.c | 35 +++++++++++++++++++++++++++++++++++ configs/sandbox_defconfig | 2 +- lib/Kconfig | 7 +++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/boot/fdt_support.c b/boot/fdt_support.c index 49d14a9..b51154f 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -12,7 +12,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -650,6 +653,38 @@ int fdt_fixup_kaslr_seed(ofnode node, const u8 *seed, int len) 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/configs/sandbox_defconfig b/configs/sandbox_defconfig index bc5bcb2..b71790e 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -348,4 +348,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/lib/Kconfig b/lib/Kconfig index 1964951..4f5dfc0 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -477,6 +477,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" -- cgit v1.1 From f9dc535525ae798298c6b98ad241574509859eee Mon Sep 17 00:00:00 2001 From: Sean Edmond Date: Thu, 30 Nov 2023 16:54:42 -0800 Subject: cmd: kaslrseed: Use common API to fixup FDT Use the newly introduced common API fdt_fixup_kaslr_seed() in the kaslrseed command. Signed-off-by: Sean Edmond Reviewed-by: Simon Glass --- cmd/kaslrseed.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) 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; } -- cgit v1.1 From 0478bf357bc6b65ebeb6a23ff109930c4fb312b3 Mon Sep 17 00:00:00 2001 From: Sean Edmond Date: Thu, 30 Nov 2023 16:54:43 -0800 Subject: dm: core: Modify default for OFNODE_MULTI_TREE There is a preference to use the "ofnode" API for FDT fixups moving forward. The FDT fixup will usually be for the kernel FDT. To fixup the kernel FDT with the ofnode API, it's required to set the OFNODE_MULTI_TREE option. To ensure existing users of kaslr fdt fixup are not impacted, Let's modify the default value for OFNODE_MULTI_TREE to ensure it's always set. This will cause a 1007 byte increase in the code size. Signed-off-by: Sean Edmond Reviewed-by: Simon Glass --- drivers/core/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 737d459..c01a8dc 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 -- cgit v1.1 From 2fd5e1c11bc665eb573358a8c618373d4265bd21 Mon Sep 17 00:00:00 2001 From: Sean Edmond Date: Thu, 30 Nov 2023 16:54:44 -0800 Subject: fdt: Fix compile error for !OFNODE_MULTI_TREE Required to fix the following compile error when building sandbox: /tmp/cci9ibby.ltrans21.ltrans.o: In function `do_cedit_load': :(.text+0x601d): undefined reference to `oftree_dispose' Signed-off-by: Sean Edmond Reviewed-by: Simon Glass --- drivers/core/ofnode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 557a4a1..f4af184 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -135,12 +135,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) { @@ -243,6 +237,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; -- cgit v1.1