From: Jens Wiklander <jens.wiklander@linaro.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v4 14/19] tee: add sandbox driver
Date: Tue, 25 Sep 2018 16:40:18 +0200 [thread overview]
Message-ID: <20180925144023.24555-15-jens.wiklander@linaro.org> (raw)
In-Reply-To: <20180925144023.24555-1-jens.wiklander@linaro.org>
Adds a sandbox tee driver which emulates a generic TEE with the OP-TEE
AVB TA.
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
---
drivers/tee/Kconfig | 18 ++-
drivers/tee/Makefile | 1 +
drivers/tee/optee/Kconfig | 2 +-
drivers/tee/sandbox.c | 308 ++++++++++++++++++++++++++++++++++++++
include/sandboxtee.h | 21 +++
5 files changed, 347 insertions(+), 3 deletions(-)
create mode 100644 drivers/tee/sandbox.c
create mode 100644 include/sandboxtee.h
diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
index 835c256e9239..5c0c89043fac 100644
--- a/drivers/tee/Kconfig
+++ b/drivers/tee/Kconfig
@@ -1,8 +1,8 @@
# Generic Trusted Execution Environment Configuration
config TEE
bool "Trusted Execution Environment support"
- depends on ARM && (ARM64 || CPU_V7A)
- select ARM_SMCCC
+ depends on (ARM && (ARM64 || CPU_V7A)) || SANDBOX
+ select ARM_SMCCC if ARM
help
This implements a generic interface towards a Trusted Execution
Environment (TEE). A TEE is a trusted OS running in some secure
@@ -14,6 +14,20 @@ if TEE
menu "TEE drivers"
+config SANDBOX_TEE
+ bool "Sandbox TEE emulator"
+ depends on SANDBOX
+ default y
+ help
+ This emulates a generic TEE needed for testing including the AVB
+ TA. The emulation provides all callbacks of a regular TEE and
+ supports session and shared memory management. The AVB TA is
+ emulated with rollback indexes and device lock-state, the state
+ of the TA is only kept in RAM and will be reset on each boot.
+ The emulation only supports one open session at a time.
+ Interaction from the U-Boot command line in possible via the
+ "avb" commands.
+
source "drivers/tee/optee/Kconfig"
endmenu
diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
index 19633b60f235..f72c68c09f33 100644
--- a/drivers/tee/Makefile
+++ b/drivers/tee/Makefile
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += tee-uclass.o
+obj-$(CONFIG_SANDBOX) += sandbox.o
obj-$(CONFIG_OPTEE) += optee/
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index dbfa7846a30f..d489834df926 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -10,7 +10,7 @@ config OPTEE
handle Remote Procedure Calls (RPC) from OP-TEE needed to
execute a service. For more information see: https://www.op-tee.org
-if OPTEE
+if OPTEE || SANDBOX
menu "OP-TEE options"
diff --git a/drivers/tee/sandbox.c b/drivers/tee/sandbox.c
new file mode 100644
index 000000000000..10a1e8dffa69
--- /dev/null
+++ b/drivers/tee/sandbox.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Linaro Limited
+ */
+#include <common.h>
+#include <dm.h>
+#include <sandboxtee.h>
+#include <tee.h>
+#include <tee/optee_ta_avb.h>
+
+/*
+ * The sandbox tee driver tries to emulate a generic Trusted Exectution
+ * Environment (TEE) with the Trusted Application (TA) OPTEE_TA_AVB
+ * available.
+ */
+
+/**
+ * struct ta_entry - TA entries
+ * @uuid: UUID of an emulated TA
+ * @open_session Called when a session is openened to the TA
+ * @invoke_func Called when a function in the TA is to be invoked
+ *
+ * This struct is used to register TAs in this sandbox emulation of a TEE.
+ */
+struct ta_entry {
+ struct tee_optee_ta_uuid uuid;
+ u32 (*open_session)(uint num_params, struct tee_param *params);
+ u32 (*invoke_func)(u32 func, uint num_params, struct tee_param *params);
+};
+
+#ifdef CONFIG_OPTEE_TA_AVB
+static u32 get_attr(uint n, uint num_params, struct tee_param *params)
+{
+ if (n >= num_params)
+ return TEE_PARAM_ATTR_TYPE_NONE;
+
+ return params[n].attr;
+}
+
+static u32 check_params(u8 p0, u8 p1, u8 p2, u8 p3, uint num_params,
+ struct tee_param *params)
+{
+ u8 p[] = { p0, p1, p2, p3};
+ uint n;
+
+ for (n = 0; n < ARRAY_SIZE(p); n++)
+ if (p[n] != get_attr(n, num_params, params))
+ goto bad_params;
+
+ for (; n < num_params; n++)
+ if (get_attr(n, num_params, params))
+ goto bad_params;
+
+ return TEE_SUCCESS;
+
+bad_params:
+ printf("Bad param attrs\n");
+
+ return TEE_ERROR_BAD_PARAMETERS;
+}
+
+static u64 ta_avb_rollback_indexes[TA_AVB_MAX_ROLLBACK_LOCATIONS];
+static u32 ta_avb_lock_state;
+
+static u32 ta_avb_open_session(uint num_params, struct tee_param *params)
+{
+ /*
+ * We don't expect additional parameters when opening a session to
+ * this TA.
+ */
+ return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+}
+
+static u32 ta_avb_invoke_func(u32 func, uint num_params,
+ struct tee_param *params)
+{
+ u32 res;
+ uint slot;
+ u64 val;
+
+ switch (func) {
+ case TA_AVB_CMD_READ_ROLLBACK_INDEX:
+ res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
+ TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+ if (res)
+ return res;
+
+ slot = params[0].u.value.a;
+ if (slot >= ARRAY_SIZE(ta_avb_rollback_indexes)) {
+ printf("Rollback index slot out of bounds %lu\n", slot);
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ val = ta_avb_rollback_indexes[slot];
+ params[1].u.value.a = val >> 32;
+ params[1].u.value.b = val;
+ return TEE_SUCCESS;
+
+ case TA_AVB_CMD_WRITE_ROLLBACK_INDEX:
+ res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
+ TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+ if (res)
+ return res;
+
+ slot = params[0].u.value.a;
+ if (slot >= ARRAY_SIZE(ta_avb_rollback_indexes)) {
+ printf("Rollback index slot out of bounds %lu\n", slot);
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ val = (u64)params[1].u.value.a << 32 | params[1].u.value.b;
+ if (val < ta_avb_rollback_indexes[slot])
+ return TEE_ERROR_SECURITY;
+
+ ta_avb_rollback_indexes[slot] = val;
+ return TEE_SUCCESS;
+
+ case TA_AVB_CMD_READ_LOCK_STATE:
+ res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+ if (res)
+ return res;
+
+ params[0].u.value.a = ta_avb_lock_state;
+ return TEE_SUCCESS;
+
+ case TA_AVB_CMD_WRITE_LOCK_STATE:
+ res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+ if (res)
+ return res;
+
+ if (ta_avb_lock_state != params[0].u.value.a) {
+ ta_avb_lock_state = params[0].u.value.a;
+ memset(ta_avb_rollback_indexes, 0,
+ sizeof(ta_avb_rollback_indexes));
+ }
+
+ return TEE_SUCCESS;
+
+ default:
+ return TEE_ERROR_NOT_SUPPORTED;
+ }
+}
+#endif /*OPTEE_TA_AVB*/
+
+static const struct ta_entry ta_entries[] = {
+#ifdef CONFIG_OPTEE_TA_AVB
+ { .uuid = TA_AVB_UUID,
+ .open_session = ta_avb_open_session,
+ .invoke_func = ta_avb_invoke_func,
+ },
+#endif
+};
+
+static void sandbox_tee_get_version(struct udevice *dev,
+ struct tee_version_data *vers)
+{
+ struct tee_version_data v = {
+ .gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM,
+ };
+
+ *vers = v;
+}
+
+static int sandbox_tee_close_session(struct udevice *dev, u32 session)
+{
+ struct sandbox_tee_state *state = dev_get_priv(dev);
+
+ if (!state->ta || state->session != session)
+ return -EINVAL;
+
+ state->session = 0;
+ state->ta = NULL;
+
+ return 0;
+}
+
+static const struct ta_entry *find_ta_entry(u8 uuid[TEE_UUID_LEN])
+{
+ struct tee_optee_ta_uuid u;
+ uint n;
+
+ tee_optee_ta_uuid_from_octets(&u, uuid);
+
+ for (n = 0; n < ARRAY_SIZE(ta_entries); n++)
+ if (!memcmp(&u, &ta_entries[n].uuid, sizeof(u)))
+ return ta_entries + n;
+
+ return NULL;
+}
+
+static int sandbox_tee_open_session(struct udevice *dev,
+ struct tee_open_session_arg *arg,
+ uint num_params, struct tee_param *params)
+{
+ struct sandbox_tee_state *state = dev_get_priv(dev);
+ const struct ta_entry *ta;
+
+ if (state->ta) {
+ printf("A session is already open\n");
+ return -EBUSY;
+ }
+
+ ta = find_ta_entry(arg->uuid);
+ if (!ta) {
+ printf("Cannot find TA\n");
+ arg->ret = TEE_ERROR_ITEM_NOT_FOUND;
+ arg->ret_origin = TEE_ORIGIN_TEE;
+
+ return 0;
+ }
+
+ arg->ret = ta->open_session(num_params, params);
+ arg->ret_origin = TEE_ORIGIN_TRUSTED_APP;
+
+ if (!arg->ret) {
+ state->ta = (void *)ta;
+ state->session = 1;
+ arg->session = state->session;
+ } else {
+ printf("Cannot open session, TA returns error\n");
+ }
+
+ return 0;
+}
+
+static int sandbox_tee_invoke_func(struct udevice *dev,
+ struct tee_invoke_arg *arg,
+ uint num_params, struct tee_param *params)
+{
+ struct sandbox_tee_state *state = dev_get_priv(dev);
+ struct ta_entry *ta = state->ta;
+
+ if (!arg->session) {
+ printf("Missing session\n");
+ return -EINVAL;
+ }
+
+ if (!ta) {
+ printf("TA session not available\n");
+ return -EINVAL;
+ }
+
+ if (arg->session != state->session) {
+ printf("Session mismatch\n");
+ return -EINVAL;
+ }
+
+ arg->ret = ta->invoke_func(arg->func, num_params, params);
+ arg->ret_origin = TEE_ORIGIN_TRUSTED_APP;
+
+ return 0;
+}
+
+static int sandbox_tee_shm_register(struct udevice *dev, struct tee_shm *shm)
+{
+ struct sandbox_tee_state *state = dev_get_priv(dev);
+
+ state->num_shms++;
+
+ return 0;
+}
+
+static int sandbox_tee_shm_unregister(struct udevice *dev, struct tee_shm *shm)
+{
+ struct sandbox_tee_state *state = dev_get_priv(dev);
+
+ state->num_shms--;
+
+ return 0;
+}
+
+static const struct tee_driver_ops sandbox_tee_ops = {
+ .get_version = sandbox_tee_get_version,
+ .open_session = sandbox_tee_open_session,
+ .close_session = sandbox_tee_close_session,
+ .invoke_func = sandbox_tee_invoke_func,
+ .shm_register = sandbox_tee_shm_register,
+ .shm_unregister = sandbox_tee_shm_unregister,
+};
+
+static const struct udevice_id sandbox_tee_match[] = {
+ { .compatible = "sandbox,tee" },
+ {},
+};
+
+U_BOOT_DRIVER(sandbox_tee) = {
+ .name = "sandbox_tee",
+ .id = UCLASS_TEE,
+ .of_match = sandbox_tee_match,
+ .ops = &sandbox_tee_ops,
+ .priv_auto_alloc_size = sizeof(struct sandbox_tee_state),
+};
diff --git a/include/sandboxtee.h b/include/sandboxtee.h
new file mode 100644
index 000000000000..44f653d9cf3b
--- /dev/null
+++ b/include/sandboxtee.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Linaro Limited
+ */
+
+#ifndef __SANDBOXTEE_H
+#define __SANDBOXTEE_H
+
+/**
+ * struct sandbox_tee_state - internal state of the sandbox TEE
+ * @session: current open session
+ * @num_shms: number of registered shared memory objects
+ * @ta: Trusted Application of current session
+ */
+struct sandbox_tee_state {
+ u32 session;
+ int num_shms;
+ void *ta;
+};
+
+#endif /*__SANDBOXTEE_H*/
--
2.17.1
next prev parent reply other threads:[~2018-09-25 14:40 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-25 14:40 [U-Boot] [PATCH v4 00/19] AVB using OP-TEE Jens Wiklander
2018-09-25 14:40 ` [U-Boot] [PATCH v4 01/19] dm: fdt: scan for devices under /firmware too Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 02/19] cmd: avb read_rb: print rb_idx in hexadecimal Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 03/19] cmd: avb: print error message if command fails Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 04/19] mmc: rpmb: add mmc_rpmb_route_frames() Jens Wiklander
2018-10-02 11:21 ` Simon Glass
2018-10-08 1:40 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 05/19] Add UCLASS_TEE for Trusted Execution Environment Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 06/19] dt/bindings: add bindings for optee Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot,v4,06/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 07/19] tee: add OP-TEE driver Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot,v4,07/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 08/19] Documentation: tee uclass and op-tee driver Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 09/19] arm: dt: hikey: Add optee node Jens Wiklander
2018-10-08 1:40 ` [U-Boot] [U-Boot,v4,09/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 10/19] optee: support routing of rpmb data frames to mmc Jens Wiklander
2018-10-02 11:21 ` Simon Glass
2018-10-08 1:40 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 11/19] tee: optee: support AVB trusted application Jens Wiklander
2018-10-02 11:21 ` Simon Glass
2018-10-08 1:41 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 12/19] sandbox: dt: add sandbox_tee node Jens Wiklander
2018-10-08 1:41 ` [U-Boot] [U-Boot,v4,12/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 13/19] sandbox: imply CONFIG_TEE (TEE uclass) Jens Wiklander
2018-10-08 1:41 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` Jens Wiklander [this message]
2018-10-02 11:21 ` [U-Boot] [PATCH v4 14/19] tee: add sandbox driver Simon Glass
2018-10-08 1:41 ` [U-Boot] [U-Boot,v4,14/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 15/19] test: tee: test TEE uclass Jens Wiklander
2018-10-08 1:41 ` [U-Boot] [U-Boot,v4,15/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 16/19] avb_verify: support using OP-TEE TA AVB Jens Wiklander
2018-10-08 1:41 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 17/19] test_avb: Update pymark.buildconfigspec information for the AVB tests Jens Wiklander
2018-10-08 1:41 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 18/19] avb_verify: support sandbox configuration Jens Wiklander
2018-10-02 11:21 ` Simon Glass
2018-10-08 1:41 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 19/19] Kconfig: sandbox: enable cmd_avb and dependencies Jens Wiklander
2018-10-08 1:41 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-10-02 11:21 ` [U-Boot] [PATCH v4 00/19] AVB using OP-TEE Simon Glass
2018-10-08 7:18 ` Jens Wiklander
2018-10-09 3:40 ` Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180925144023.24555-15-jens.wiklander@linaro.org \
--to=jens.wiklander@linaro.org \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.