diff options
-rw-r--r-- | arch/arm/cpu/armv8/sec_firmware.c | 39 | ||||
-rw-r--r-- | boot/fdt_support.c | 54 | ||||
-rw-r--r-- | cmd/kaslrseed.c | 20 | ||||
-rw-r--r-- | configs/sandbox_defconfig | 2 | ||||
-rw-r--r-- | drivers/core/Kconfig | 3 | ||||
-rw-r--r-- | drivers/core/ofnode.c | 29 | ||||
-rw-r--r-- | include/dm/ofnode.h | 12 | ||||
-rw-r--r-- | include/fdt_support.h | 9 | ||||
-rw-r--r-- | lib/Kconfig | 7 |
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" |