obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
endif
-obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += vbe.o vbe_fixup.o
+obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += vbe.o vbe_request.o
obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE_SIMPLE) += vbe_simple.o
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Verified Boot for Embedded (VBE) device tree fixup functions
- *
- * Copyright 2022 Google LLC
- * Written by Simon Glass <sjg@chromium.org>
- */
-
-#define LOG_CATEGORY LOGC_BOOT
-
-#include <common.h>
-#include <dm.h>
-#include <event.h>
-#include <image.h>
-#include <malloc.h>
-#include <rng.h>
-#include <dm/ofnode.h>
-
-#define VBE_PREFIX "vbe,"
-#define VBE_PREFIX_LEN (sizeof(VBE_PREFIX) - 1)
-#define VBE_ERR_STR_LEN 128
-#define VBE_MAX_RAND_SIZE 256
-
-struct vbe_result {
- int errnum;
- char err_str[VBE_ERR_STR_LEN];
-};
-
-typedef int (*vbe_req_func)(ofnode node, struct vbe_result *result);
-
-static int handle_random_req(ofnode node, int default_size,
- struct vbe_result *result)
-{
- char buf[VBE_MAX_RAND_SIZE];
- struct udevice *dev;
- u32 size;
- int ret;
-
- if (!IS_ENABLED(CONFIG_DM_RNG))
- return -ENOTSUPP;
-
- if (ofnode_read_u32(node, "vbe,size", &size)) {
- if (!default_size) {
- snprintf(result->err_str, VBE_ERR_STR_LEN,
- "Missing vbe,size property");
- return log_msg_ret("byt", -EINVAL);
- }
- size = default_size;
- }
- if (size > VBE_MAX_RAND_SIZE) {
- snprintf(result->err_str, VBE_ERR_STR_LEN,
- "vbe,size %#x exceeds max size %#x", size,
- VBE_MAX_RAND_SIZE);
- return log_msg_ret("siz", -E2BIG);
- }
- ret = uclass_first_device_err(UCLASS_RNG, &dev);
- if (ret) {
- snprintf(result->err_str, VBE_ERR_STR_LEN,
- "Cannot find random-number device (err=%d)", ret);
- return log_msg_ret("wr", ret);
- }
- ret = dm_rng_read(dev, buf, size);
- if (ret) {
- snprintf(result->err_str, VBE_ERR_STR_LEN,
- "Failed to read random-number device (err=%d)", ret);
- return log_msg_ret("rd", ret);
- }
- ret = ofnode_write_prop(node, "data", buf, size, true);
- if (ret)
- return log_msg_ret("wr", -EINVAL);
-
- return 0;
-}
-
-static int vbe_req_random_seed(ofnode node, struct vbe_result *result)
-{
- return handle_random_req(node, 0, result);
-}
-
-static int vbe_req_aslr_move(ofnode node, struct vbe_result *result)
-{
- return -ENOTSUPP;
-}
-
-static int vbe_req_aslr_rand(ofnode node, struct vbe_result *result)
-{
- return handle_random_req(node, 4, result);
-}
-
-static int vbe_req_efi_runtime_rand(ofnode node, struct vbe_result *result)
-{
- return handle_random_req(node, 4, result);
-}
-
-static struct vbe_req {
- const char *compat;
- vbe_req_func func;
-} vbe_reqs[] = {
- /* address space layout randomization - move the OS in memory */
- { "aslr-move", vbe_req_aslr_move },
-
- /* provide random data for address space layout randomization */
- { "aslr-rand", vbe_req_aslr_rand },
-
- /* provide random data for EFI-runtime-services address */
- { "efi-runtime-rand", vbe_req_efi_runtime_rand },
-
- /* generate random data bytes to see the OS's rand generator */
- { "random-rand", vbe_req_random_seed },
-
-};
-
-static int vbe_process_request(ofnode node, struct vbe_result *result)
-{
- const char *compat, *req_name;
- int i;
-
- compat = ofnode_read_string(node, "compatible");
- if (!compat)
- return 0;
-
- if (strlen(compat) <= VBE_PREFIX_LEN ||
- strncmp(compat, VBE_PREFIX, VBE_PREFIX_LEN))
- return -EINVAL;
-
- req_name = compat + VBE_PREFIX_LEN; /* drop "vbe," prefix */
- for (i = 0; i < ARRAY_SIZE(vbe_reqs); i++) {
- if (!strcmp(vbe_reqs[i].compat, req_name)) {
- int ret;
-
- ret = vbe_reqs[i].func(node, result);
- if (ret)
- return log_msg_ret("req", ret);
- return 0;
- }
- }
- snprintf(result->err_str, VBE_ERR_STR_LEN, "Unknown request: %s",
- req_name);
-
- return -ENOTSUPP;
-}
-
-/**
- * bootmeth_vbe_ft_fixup() - Process VBE OS requests and do device tree fixups
- *
- * If there are no images provided, this does nothing and returns 0.
- *
- * @ctx: Context for event
- * @event: Event to process
- * @return 0 if OK, -ve on error
- */
-static int bootmeth_vbe_ft_fixup(void *ctx, struct event *event)
-{
- const struct event_ft_fixup *fixup = &event->data.ft_fixup;
- const struct bootm_headers *images = fixup->images;
- ofnode parent, dest_parent, root, node;
- oftree fit;
-
- if (!images || !images->fit_hdr_os)
- return 0;
-
- /* Get the image node with requests in it */
- log_debug("fit=%p, noffset=%d\n", images->fit_hdr_os,
- images->fit_noffset_os);
- fit = oftree_from_fdt(images->fit_hdr_os);
- root = oftree_root(fit);
- if (of_live_active()) {
- log_warning("Cannot fix up live tree\n");
- return 0;
- }
- if (!ofnode_valid(root))
- return log_msg_ret("rt", -EINVAL);
- parent = noffset_to_ofnode(root, images->fit_noffset_os);
- if (!ofnode_valid(parent))
- return log_msg_ret("img", -EINVAL);
- dest_parent = oftree_path(fixup->tree, "/chosen");
- if (!ofnode_valid(dest_parent))
- return log_msg_ret("dst", -EINVAL);
-
- ofnode_for_each_subnode(node, parent) {
- const char *name = ofnode_get_name(node);
- struct vbe_result result;
- ofnode dest;
- int ret;
-
- log_debug("copy subnode: %s\n", name);
- ret = ofnode_add_subnode(dest_parent, name, &dest);
- if (ret && ret != -EEXIST)
- return log_msg_ret("add", ret);
- ret = ofnode_copy_props(node, dest);
- if (ret)
- return log_msg_ret("cp", ret);
-
- *result.err_str = '\0';
- ret = vbe_process_request(dest, &result);
- if (ret) {
- result.errnum = ret;
- log_err("Failed to process VBE request %s (err=%d)\n",
- ofnode_get_name(dest), ret);
- if (*result.err_str) {
- char *msg = strdup(result.err_str);
-
- if (!msg)
- return log_msg_ret("msg", -ENOMEM);
- ret = ofnode_write_string(dest, "vbe,error",
- msg);
- if (ret) {
- free(msg);
- return log_msg_ret("str", -ENOMEM);
- }
- }
- if (result.errnum) {
- ret = ofnode_write_u32(dest, "vbe,errnum",
- result.errnum);
- if (ret)
- return log_msg_ret("num", -ENOMEM);
- if (result.errnum != -ENOTSUPP)
- return log_msg_ret("pro",
- result.errnum);
- if (result.errnum == -ENOTSUPP &&
- ofnode_read_bool(dest, "vbe,required")) {
- log_err("Cannot handle required request: %s\n",
- ofnode_get_name(dest));
- return log_msg_ret("req",
- result.errnum);
- }
- }
- }
- }
-
- return 0;
-}
-EVENT_SPY(EVT_FT_FIXUP, bootmeth_vbe_ft_fixup);
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Verified Boot for Embedded (VBE) OS request (device tree fixup) functions
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#define LOG_CATEGORY LOGC_BOOT
+
+#include <common.h>
+#include <dm.h>
+#include <event.h>
+#include <image.h>
+#include <malloc.h>
+#include <rng.h>
+#include <dm/ofnode.h>
+
+#define VBE_PREFIX "vbe,"
+#define VBE_PREFIX_LEN (sizeof(VBE_PREFIX) - 1)
+#define VBE_ERR_STR_LEN 128
+#define VBE_MAX_RAND_SIZE 256
+
+struct vbe_result {
+ int errnum;
+ char err_str[VBE_ERR_STR_LEN];
+};
+
+typedef int (*vbe_req_func)(ofnode node, struct vbe_result *result);
+
+static int handle_random_req(ofnode node, int default_size,
+ struct vbe_result *result)
+{
+ char buf[VBE_MAX_RAND_SIZE];
+ struct udevice *dev;
+ u32 size;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_DM_RNG))
+ return -ENOTSUPP;
+
+ if (ofnode_read_u32(node, "vbe,size", &size)) {
+ if (!default_size) {
+ snprintf(result->err_str, VBE_ERR_STR_LEN,
+ "Missing vbe,size property");
+ return log_msg_ret("byt", -EINVAL);
+ }
+ size = default_size;
+ }
+ if (size > VBE_MAX_RAND_SIZE) {
+ snprintf(result->err_str, VBE_ERR_STR_LEN,
+ "vbe,size %#x exceeds max size %#x", size,
+ VBE_MAX_RAND_SIZE);
+ return log_msg_ret("siz", -E2BIG);
+ }
+ ret = uclass_first_device_err(UCLASS_RNG, &dev);
+ if (ret) {
+ snprintf(result->err_str, VBE_ERR_STR_LEN,
+ "Cannot find random-number device (err=%d)", ret);
+ return log_msg_ret("wr", ret);
+ }
+ ret = dm_rng_read(dev, buf, size);
+ if (ret) {
+ snprintf(result->err_str, VBE_ERR_STR_LEN,
+ "Failed to read random-number device (err=%d)", ret);
+ return log_msg_ret("rd", ret);
+ }
+ ret = ofnode_write_prop(node, "data", buf, size, true);
+ if (ret)
+ return log_msg_ret("wr", -EINVAL);
+
+ return 0;
+}
+
+static int vbe_req_random_seed(ofnode node, struct vbe_result *result)
+{
+ return handle_random_req(node, 0, result);
+}
+
+static int vbe_req_aslr_move(ofnode node, struct vbe_result *result)
+{
+ return -ENOTSUPP;
+}
+
+static int vbe_req_aslr_rand(ofnode node, struct vbe_result *result)
+{
+ return handle_random_req(node, 4, result);
+}
+
+static int vbe_req_efi_runtime_rand(ofnode node, struct vbe_result *result)
+{
+ return handle_random_req(node, 4, result);
+}
+
+static struct vbe_req {
+ const char *compat;
+ vbe_req_func func;
+} vbe_reqs[] = {
+ /* address space layout randomization - move the OS in memory */
+ { "aslr-move", vbe_req_aslr_move },
+
+ /* provide random data for address space layout randomization */
+ { "aslr-rand", vbe_req_aslr_rand },
+
+ /* provide random data for EFI-runtime-services address */
+ { "efi-runtime-rand", vbe_req_efi_runtime_rand },
+
+ /* generate random data bytes to see the OS's rand generator */
+ { "random-rand", vbe_req_random_seed },
+
+};
+
+static int vbe_process_request(ofnode node, struct vbe_result *result)
+{
+ const char *compat, *req_name;
+ int i;
+
+ compat = ofnode_read_string(node, "compatible");
+ if (!compat)
+ return 0;
+
+ if (strlen(compat) <= VBE_PREFIX_LEN ||
+ strncmp(compat, VBE_PREFIX, VBE_PREFIX_LEN))
+ return -EINVAL;
+
+ req_name = compat + VBE_PREFIX_LEN; /* drop "vbe," prefix */
+ for (i = 0; i < ARRAY_SIZE(vbe_reqs); i++) {
+ if (!strcmp(vbe_reqs[i].compat, req_name)) {
+ int ret;
+
+ ret = vbe_reqs[i].func(node, result);
+ if (ret)
+ return log_msg_ret("req", ret);
+ return 0;
+ }
+ }
+ snprintf(result->err_str, VBE_ERR_STR_LEN, "Unknown request: %s",
+ req_name);
+
+ return -ENOTSUPP;
+}
+
+/**
+ * bootmeth_vbe_ft_fixup() - Process VBE OS requests and do device tree fixups
+ *
+ * If there are no images provided, this does nothing and returns 0.
+ *
+ * @ctx: Context for event
+ * @event: Event to process
+ * @return 0 if OK, -ve on error
+ */
+static int bootmeth_vbe_ft_fixup(void *ctx, struct event *event)
+{
+ const struct event_ft_fixup *fixup = &event->data.ft_fixup;
+ const struct bootm_headers *images = fixup->images;
+ ofnode parent, dest_parent, root, node;
+ oftree fit;
+
+ if (!images || !images->fit_hdr_os)
+ return 0;
+
+ /* Get the image node with requests in it */
+ log_debug("fit=%p, noffset=%d\n", images->fit_hdr_os,
+ images->fit_noffset_os);
+ fit = oftree_from_fdt(images->fit_hdr_os);
+ root = oftree_root(fit);
+ if (of_live_active()) {
+ log_warning("Cannot fix up live tree\n");
+ return 0;
+ }
+ if (!ofnode_valid(root))
+ return log_msg_ret("rt", -EINVAL);
+ parent = noffset_to_ofnode(root, images->fit_noffset_os);
+ if (!ofnode_valid(parent))
+ return log_msg_ret("img", -EINVAL);
+ dest_parent = oftree_path(fixup->tree, "/chosen");
+ if (!ofnode_valid(dest_parent))
+ return log_msg_ret("dst", -EINVAL);
+
+ ofnode_for_each_subnode(node, parent) {
+ const char *name = ofnode_get_name(node);
+ struct vbe_result result;
+ ofnode dest;
+ int ret;
+
+ log_debug("copy subnode: %s\n", name);
+ ret = ofnode_add_subnode(dest_parent, name, &dest);
+ if (ret && ret != -EEXIST)
+ return log_msg_ret("add", ret);
+ ret = ofnode_copy_props(node, dest);
+ if (ret)
+ return log_msg_ret("cp", ret);
+
+ *result.err_str = '\0';
+ ret = vbe_process_request(dest, &result);
+ if (ret) {
+ result.errnum = ret;
+ log_err("Failed to process VBE request %s (err=%d)\n",
+ ofnode_get_name(dest), ret);
+ if (*result.err_str) {
+ char *msg = strdup(result.err_str);
+
+ if (!msg)
+ return log_msg_ret("msg", -ENOMEM);
+ ret = ofnode_write_string(dest, "vbe,error",
+ msg);
+ if (ret) {
+ free(msg);
+ return log_msg_ret("str", -ENOMEM);
+ }
+ }
+ if (result.errnum) {
+ ret = ofnode_write_u32(dest, "vbe,errnum",
+ result.errnum);
+ if (ret)
+ return log_msg_ret("num", -ENOMEM);
+ if (result.errnum != -ENOTSUPP)
+ return log_msg_ret("pro",
+ result.errnum);
+ if (result.errnum == -ENOTSUPP &&
+ ofnode_read_bool(dest, "vbe,required")) {
+ log_err("Cannot handle required request: %s\n",
+ ofnode_get_name(dest));
+ return log_msg_ret("req",
+ result.errnum);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+EVENT_SPY(EVT_FT_FIXUP, bootmeth_vbe_ft_fixup);
out = util.run_and_log(cons, ['scripts/event_dump.py', sandbox])
expect = '''.*Event type Id Source location
-------------------- ------------------------------ ------------------------------
-EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*vbe_fixup.c:.*
+EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*vbe_request.c:.*
EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*vbe_simple.c:.*
EVT_MISC_INIT_F sandbox_misc_init_f .*start.c:'''
assert re.match(expect, out, re.MULTILINE) is not None