aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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"