aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlias Apalodimas <ilias.apalodimas@linaro.org>2020-03-31 22:00:05 +0300
committerIlias Apalodimas <ilias.apalodimas@linaro.org>2020-04-06 23:57:31 +0300
commit27a22e38e2dd70005b548d90386a818319581133 (patch)
tree0c40a2c5c87477c3e2592a3f53b515702819ce1e
parent5e3ef32d241e4757977862cf477ac52ccf102a9f (diff)
Write from StMM workingnew
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r--core/arch/arm/include/kernel/secure_partition.h2
-rw-r--r--core/arch/arm/kernel/secure_partition.c30
-rw-r--r--core/include/tee/tee_svc_storage.h11
-rw-r--r--core/tee/tee_svc_storage.c185
4 files changed, 226 insertions, 2 deletions
diff --git a/core/arch/arm/include/kernel/secure_partition.h b/core/arch/arm/include/kernel/secure_partition.h
index c00e3588..4990e677 100644
--- a/core/arch/arm/include/kernel/secure_partition.h
+++ b/core/arch/arm/include/kernel/secure_partition.h
@@ -37,6 +37,8 @@
#define SP_SVC_EVENT_COMPLETE_64 0xC4000061
#define SP_SVC_MEMORY_ATTRIBUTES_GET_64 0xC4000064
#define SP_SVC_MEMORY_ATTRIBUTES_SET_64 0xC4000065
+#define SP_SVC_RPMB_READ 0xC4000066
+#define SP_SVC_RPMB_WRITE 0xC4000067
/* Param header types */
#define SP_PARAM_EP UINT8_C(0x01)
diff --git a/core/arch/arm/kernel/secure_partition.c b/core/arch/arm/kernel/secure_partition.c
index d21a4a56..a01a6723 100644
--- a/core/arch/arm/kernel/secure_partition.c
+++ b/core/arch/arm/kernel/secure_partition.c
@@ -14,12 +14,15 @@
#include <zlib.h>
#include "thread_private.h"
+#include <tee/tee_svc_storage.h>
+#include <crypto/crypto.h>
+#include <tee_api_defines_extensions.h>
static const TEE_UUID stmm_uuid = PTA_STMM_UUID;
static const unsigned int stmm_entry;
-static const unsigned int stmm_stack_size = 4 * SMALL_PAGE_SIZE;
-static const unsigned int stmm_heap_size = 398 * SMALL_PAGE_SIZE;
+static const unsigned int stmm_stack_size = 128 * SMALL_PAGE_SIZE;
+static const unsigned int stmm_heap_size = 1024 * SMALL_PAGE_SIZE;
static const unsigned int stmm_sec_buf_size = SMALL_PAGE_SIZE;
static const unsigned int stmm_ns_comm_buf_size = SMALL_PAGE_SIZE;
@@ -519,6 +522,13 @@ static void set_svc_retval(struct thread_svc_regs *regs, uint64_t ret_val)
static bool stmm_handle_svc(struct thread_svc_regs *regs)
{
+ uint32_t flags = TEE_DATA_FLAG_ACCESS_READ |
+ TEE_DATA_FLAG_ACCESS_WRITE |
+ TEE_DATA_FLAG_SHARE_READ |
+ TEE_DATA_FLAG_SHARE_WRITE |
+ TEE_DATA_FLAG_OVERWRITE;
+ TEE_Result res = TEE_SUCCESS;
+
switch (regs->x0) {
case SP_SVC_VERSION:
set_svc_retval(regs, SP_VERSION);
@@ -534,6 +544,22 @@ static bool stmm_handle_svc(struct thread_svc_regs *regs)
sp_svc_set_mem_attr(regs->x1, regs->x2,
regs->x3));
return true;
+ case SP_SVC_RPMB_READ:
+ res = sec_storage_obj_read(TEE_STORAGE_PRIVATE_RPMB,
+ (void*)regs->x1, regs->x2,
+ (void*)regs->x3, regs->x4,
+ flags);
+ set_svc_retval(regs, res);
+
+ return true;
+ case SP_SVC_RPMB_WRITE:
+ res = sec_storage_obj_write(TEE_STORAGE_PRIVATE_RPMB,
+ (void*)regs->x1, regs->x2,
+ (void*)regs->x3, regs->x4, regs->x5,
+ flags);
+ set_svc_retval(regs, res);
+
+ return true;
default:
EMSG("Undefined syscall 0x%"PRIx32, (uint32_t)regs->x0);
return return_helper(true, 0xbadfbadf, regs);
diff --git a/core/include/tee/tee_svc_storage.h b/core/include/tee/tee_svc_storage.h
index 33d94413..688c7022 100644
--- a/core/include/tee/tee_svc_storage.h
+++ b/core/include/tee/tee_svc_storage.h
@@ -18,6 +18,17 @@
const struct tee_file_operations *tee_svc_storage_file_ops(uint32_t storage_id);
/*
+ * Combined read/write ops from secure partition running StnadAloneMM
+ */
+TEE_Result sec_storage_obj_read(unsigned long storage_id, void *object_id,
+ size_t object_id_len, void *data, size_t len,
+ unsigned long flags);
+
+TEE_Result sec_storage_obj_write(unsigned long storage_id, void *object_id,
+ size_t object_id_len, void *data, size_t len,
+ size_t offset, unsigned long flags);
+
+/*
* Persistant Object Functions
*/
TEE_Result syscall_storage_obj_open(unsigned long storage_id, void *object_id,
diff --git a/core/tee/tee_svc_storage.c b/core/tee/tee_svc_storage.c
index 5602504a..fa9d28f3 100644
--- a/core/tee/tee_svc_storage.c
+++ b/core/tee/tee_svc_storage.c
@@ -6,6 +6,7 @@
#include <kernel/mutex.h>
#include <kernel/tee_misc.h>
#include <kernel/tee_ta_manager.h>
+#include <kernel/secure_partition.h>
#include <mm/tee_mmu.h>
#include <string.h>
#include <tee_api_defines_extensions.h>
@@ -395,6 +396,190 @@ exit:
return res;
}
+/*
+ * Combined read from secure partition, this will open, read and
+ * close the fh
+ */
+TEE_Result sec_storage_obj_read(unsigned long storage_id, void *object_id,
+ size_t object_id_len, void *data, size_t len,
+ unsigned long flags)
+
+{
+ const struct tee_file_operations *fops =
+ tee_svc_storage_file_ops(storage_id);
+ struct tee_ta_session *sess = NULL;
+ TEE_Result res = TEE_ERROR_BAD_STATE;
+ struct tee_pobj *po = NULL;
+ size_t pos_tmp = 0;
+ /*
+ * We don't need to add an object here on the list we'll create the file
+ * and exit
+ */
+ struct tee_obj o;
+ size_t bytes = 0;
+
+ memset(&o, 0, sizeof(o));
+ if (!fops)
+ return TEE_ERROR_ITEM_NOT_FOUND;
+
+ if (object_id_len > TEE_OBJECT_ID_MAX_LEN)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ res = tee_ta_get_current_session(&sess);
+ if (res != TEE_SUCCESS)
+ return res;
+
+ res = tee_pobj_get((void *)&sess->ctx->uuid, object_id,
+ object_id_len, flags, false, fops, &po);
+ if (res != TEE_SUCCESS)
+ return res;
+
+ o.info.handleFlags =
+ TEE_HANDLE_FLAG_PERSISTENT | TEE_HANDLE_FLAG_INITIALIZED |
+ TEE_DATA_FLAG_ACCESS_READ;
+ o.flags = flags;
+ o.pobj = po;
+
+ res = tee_svc_storage_read_head(&o);
+ if (res != TEE_SUCCESS) {
+ if (res == TEE_ERROR_CORRUPT_OBJECT) {
+ EMSG("Object corrupt");
+ goto err;
+ }
+ goto err;
+ }
+
+ /* Always reading the full file */
+ if (ADD_OVERFLOW(0, len, &pos_tmp)) {
+ res = TEE_ERROR_OVERFLOW;
+ goto err;
+ }
+
+ /*
+ * FIXME @Jens, we don't need that since we always control the
+ * heap/stack of stmm right?
+ */
+#if 0
+ res = tee_mmu_check_access_rights(&spc->uctx,
+ TEE_MEMORY_ACCESS_WRITE |
+ TEE_MEMORY_ACCESS_ANY_OWNER,
+ (uaddr_t)data, len);
+ if (res != TEE_SUCCESS)
+ goto err;
+#endif
+
+ /*
+ * Not needed but keep the check in case we want to read at an offset
+ * and change '0' with the offset value
+ */
+ if (ADD_OVERFLOW(o.ds_pos, 0, &pos_tmp)) {
+ res = TEE_ERROR_OVERFLOW;
+ goto err;
+ }
+
+ bytes = len;
+ res = o.pobj->fops->read(o.fh, pos_tmp, data, &bytes);
+ if (res != TEE_SUCCESS) {
+ if (res == TEE_ERROR_CORRUPT_OBJECT) {
+ EMSG("Object corrupt");
+ o.pobj->fops->remove(o.pobj);
+ }
+ goto err;
+ }
+ o.pobj->fops->close(&o.fh);
+
+ return res;
+
+err:
+ o.pobj->fops->close(&o.fh);
+ if (po)
+ tee_pobj_release(po);
+ if (res == TEE_ERROR_NO_DATA || res == TEE_ERROR_BAD_FORMAT)
+ res = TEE_ERROR_CORRUPT_OBJECT;
+
+ return res;
+}
+
+/*
+ * Combined write from secure partition, this will create/open, write and
+ * close the fh
+ */
+TEE_Result sec_storage_obj_write(unsigned long storage_id, void *object_id,
+ size_t object_id_len, void *data, size_t len,
+ size_t offset, unsigned long flags)
+
+{
+ const struct tee_file_operations *fops =
+ tee_svc_storage_file_ops(storage_id);
+ struct tee_ta_session *sess = NULL;
+ TEE_Result res = TEE_SUCCESS;
+ struct tee_pobj *po = NULL;
+ size_t pos_tmp = 0;
+ /*
+ * We don't need to add an object here on the list we'll create the file
+ * and exit
+ */
+ struct tee_obj o;
+
+ memset(&o, 0, sizeof(o));
+ if (!fops)
+ return TEE_ERROR_ITEM_NOT_FOUND;
+
+ if (object_id_len > TEE_OBJECT_ID_MAX_LEN)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ res = tee_ta_get_current_session(&sess);
+ if (res != TEE_SUCCESS)
+ return res;
+
+ res = tee_pobj_get((void *)&sess->ctx->uuid, object_id,
+ object_id_len, flags, false, fops, &po);
+ if (res != TEE_SUCCESS)
+ return res;
+
+ o.info.handleFlags =
+ TEE_HANDLE_FLAG_PERSISTENT | TEE_HANDLE_FLAG_INITIALIZED |
+ TEE_DATA_FLAG_ACCESS_WRITE;
+ o.flags = flags;
+ o.pobj = po;
+
+ res = tee_svc_storage_init_file(&o, NULL, NULL, 0);
+ if (res != TEE_SUCCESS)
+ return res;
+ /*
+ * Guard o->info.dataPosition += bytes below from overflowing.
+ * The driver is expected to send the overall offset in the file for
+ * each write, so we can ignore dataPosition
+ */
+ if (ADD_OVERFLOW(offset, len, &pos_tmp)) {
+ res = TEE_ERROR_OVERFLOW;
+ goto err;
+ }
+
+ if (ADD_OVERFLOW(o.ds_pos, offset, &pos_tmp)) {
+ res = TEE_ERROR_ACCESS_CONFLICT;
+ goto err;
+ }
+ /* FIXME remove after tests */
+ //pos_tmp += offset;
+
+ res = o.pobj->fops->write(o.fh, pos_tmp, data, len);
+ if (res != TEE_SUCCESS)
+ goto err;
+
+ o.pobj->fops->close(&o.fh);
+
+ return TEE_SUCCESS;
+
+err:
+ if (res == TEE_ERROR_NO_DATA || res == TEE_ERROR_BAD_FORMAT)
+ res = TEE_ERROR_CORRUPT_OBJECT;
+ if (po)
+ tee_pobj_release(po);
+
+ return res;
+}
+
TEE_Result syscall_storage_obj_create(unsigned long storage_id, void *object_id,
size_t object_id_len, unsigned long flags,
unsigned long attr, void *data, size_t len,