
Tests the TEE uclass with a sandbox tee driver.
Signed-off-by: Jens Wiklander jens.wiklander@linaro.org --- drivers/tee/Kconfig | 5 +- test/dm/Makefile | 1 + test/dm/tee.c | 182 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 test/dm/tee.c
diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig index 3e7fe6ddcc5d..032aff4777c6 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). @@ -14,5 +14,4 @@ menu "TEE drivers" source "drivers/tee/optee/Kconfig"
endmenu - endif diff --git a/test/dm/Makefile b/test/dm/Makefile index d2ed96c61533..272374b92fb0 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -44,4 +44,5 @@ obj-$(CONFIG_DM_VIDEO) += video.o obj-$(CONFIG_ADC) += adc.o obj-$(CONFIG_SPMI) += spmi.o obj-$(CONFIG_WDT) += wdt.o +obj-$(CONFIG_TEE) += tee.o endif diff --git a/test/dm/tee.c b/test/dm/tee.c new file mode 100644 index 000000000000..bf9db0c130ac --- /dev/null +++ b/test/dm/tee.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Linaro Limited + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> +#include <tee.h> +#include <test/ut.h> + +struct sandbox_tee_state { + u32 session; + int num_shms; +}; + +static void sandbox_tee_get_version(struct udevice *dev, + struct tee_version_data *vers) +{ + memset(vers, 0, sizeof(*vers)); +} + +static int sandbox_tee_close_session(struct udevice *dev, u32 session) +{ + struct sandbox_tee_state *state = dev_get_priv(dev); + + if (!state->session || state->session != session) + return -EINVAL; + + state->session = 0; + + return 0; +} + +static int sandbox_tee_open_session(struct udevice *dev, + struct tee_open_session_arg *arg, + ulong num_params, struct tee_param *params) +{ + struct sandbox_tee_state *state = dev_get_priv(dev); + + if (state->session) + return -EBUSY; + + state->session = 1; + arg->session = state->session; + + return 0; +} + +static int sandbox_tee_invoke_func(struct udevice *dev, + struct tee_invoke_arg *arg, + ulong num_params, struct tee_param *params) +{ + struct sandbox_tee_state *state = dev_get_priv(dev); + + if (!arg->session) + return -EINVAL; + + if (arg->session != state->session) + return -EINVAL; + + if (arg->func != 1) + return -ENOENT; + + 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), +}; + +static int open_session(struct udevice *dev, u32 *session) +{ + struct tee_open_session_arg arg; + int rc; + + memset(&arg, 0, sizeof(arg)); + rc = tee_open_session(dev, &arg, 0, NULL); + if (rc) + return rc; + if (arg.ret) + return -EIO; + *session = arg.session; + + return 0; +} + +static int invoke_func(struct udevice *dev, u32 session, u32 func) +{ + struct tee_invoke_arg arg = { .session = session, .func = func }; + + return tee_invoke_func(dev, &arg, 0, NULL); +} + +static int match(struct tee_version_data *vers, const void *data) +{ + return !vers->gen_caps; +} + +static int dm_test_tee(struct unit_test_state *uts) +{ + struct tee_version_data vers; + struct udevice *dev; + struct sandbox_tee_state *state; + u32 session; + int rc; + u8 data[128]; + struct tee_shm *reg_shm; + struct tee_shm *alloc_shm; + + dev = tee_find_device(NULL, match, NULL, &vers); + ut_assert(dev); + state = dev_get_priv(dev); + ut_assert(!state->session); + + rc = open_session(dev, &session); + ut_assert(!rc); + ut_assert(session == state->session); + + rc = invoke_func(dev, session, 1); + ut_assert(!rc); + + rc = tee_close_session(dev, session); + ut_assert(!rc); + ut_assert(!state->session); + + ut_assert(!state->num_shms); + reg_shm = tee_shm_register(dev, data, sizeof(data), 0); + ut_assert(reg_shm); + ut_assert(state->num_shms == 1); + + alloc_shm = tee_shm_alloc(dev, 256, 0); + ut_assert(alloc_shm); + ut_assert(state->num_shms == 2); + + ut_assert(tee_shm_is_registered(reg_shm, dev)); + ut_assert(tee_shm_is_registered(alloc_shm, dev)); + + tee_shm_free(reg_shm); + tee_shm_free(alloc_shm); + ut_assert(!state->num_shms); + + return 0; +} + +DM_TEST(dm_test_tee, DM_TESTF_SCAN_FDT);