| // SPDX-License-Identifier: BSD-2-Clause |
| /* |
| * Copyright (c) 2014, STMicroelectronics International N.V. |
| * All rights reserved. |
| */ |
| |
| #include "storage.h" |
| #include "ta_storage.h" |
| |
| #include <tee_api.h> |
| #include <trace.h> |
| |
| #define ASSERT_PARAM_TYPE(pt) \ |
| do { \ |
| if ((pt) != param_types) \ |
| return TEE_ERROR_BAD_PARAMETERS; \ |
| } while (0) |
| |
| #define VAL2HANDLE(v) (void *)(uintptr_t)(v) |
| |
| TEE_Result ta_storage_cmd_open(uint32_t command, |
| uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_Result res = TEE_ERROR_GENERIC; |
| TEE_ObjectHandle o = TEE_HANDLE_NULL; |
| void *object_id = NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_MEMREF_INPUT, |
| TEE_PARAM_TYPE_VALUE_INOUT, |
| TEE_PARAM_TYPE_VALUE_INPUT, |
| TEE_PARAM_TYPE_NONE)); |
| |
| switch (command) { |
| case TA_STORAGE_CMD_OPEN: |
| if (params[0].memref.buffer) { |
| object_id = TEE_Malloc(params[0].memref.size, 0); |
| if (!object_id) |
| return TEE_ERROR_OUT_OF_MEMORY; |
| |
| TEE_MemMove(object_id, params[0].memref.buffer, |
| params[0].memref.size); |
| } |
| break; |
| case TA_STORAGE_CMD_OPEN_ID_IN_SHM: |
| object_id = params[0].memref.buffer; |
| break; |
| default: |
| return TEE_ERROR_NOT_SUPPORTED; |
| } |
| |
| res = TEE_OpenPersistentObject(params[2].value.a, |
| object_id, params[0].memref.size, |
| params[1].value.a, &o); |
| |
| params[1].value.b = (uintptr_t)o; |
| |
| if (command == TA_STORAGE_CMD_OPEN) |
| TEE_Free(object_id); |
| |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_create(uint32_t command, |
| uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_Result res = TEE_ERROR_GENERIC; |
| TEE_ObjectHandle o = TEE_HANDLE_NULL; |
| void *object_id = NULL; |
| TEE_ObjectHandle ref_handle = TEE_HANDLE_NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_MEMREF_INPUT, |
| TEE_PARAM_TYPE_VALUE_INOUT, |
| TEE_PARAM_TYPE_VALUE_INPUT, |
| TEE_PARAM_TYPE_MEMREF_INPUT)); |
| |
| switch (command) { |
| case TA_STORAGE_CMD_CREATE: |
| if (params[0].memref.buffer) { |
| object_id = TEE_Malloc(params[0].memref.size, 0); |
| if (!object_id) |
| return TEE_ERROR_OUT_OF_MEMORY; |
| |
| TEE_MemMove(object_id, params[0].memref.buffer, |
| params[0].memref.size); |
| } |
| break; |
| case TA_STORAGE_CMD_CREATE_ID_IN_SHM: |
| object_id = params[0].memref.buffer; |
| break; |
| default: |
| return TEE_ERROR_NOT_SUPPORTED; |
| } |
| |
| ref_handle = (TEE_ObjectHandle)(uintptr_t)params[2].value.a; |
| |
| res = TEE_CreatePersistentObject(params[2].value.b, |
| object_id, params[0].memref.size, |
| params[1].value.a, ref_handle, |
| params[3].memref.buffer, |
| params[3].memref.size, &o); |
| |
| if (command == TA_STORAGE_CMD_CREATE) |
| TEE_Free(object_id); |
| |
| params[1].value.b = (uintptr_t)o; |
| |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_create_overwrite(uint32_t command, |
| uint32_t param_types, |
| TEE_Param params[4]) |
| { |
| TEE_Result res = TEE_ERROR_GENERIC; |
| TEE_ObjectHandle o = TEE_HANDLE_NULL; |
| void *object_id = NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_MEMREF_INPUT, |
| TEE_PARAM_TYPE_VALUE_INPUT, |
| TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE)); |
| |
| switch (command) { |
| case TA_STORAGE_CMD_CREATE_OVERWRITE: |
| object_id = TEE_Malloc(params[0].memref.size, 0); |
| if (!object_id) |
| return TEE_ERROR_OUT_OF_MEMORY; |
| |
| TEE_MemMove(object_id, params[0].memref.buffer, |
| params[0].memref.size); |
| break; |
| case TA_STORAGE_CMD_CREATEOVER_ID_IN_SHM: |
| object_id = params[0].memref.buffer; |
| break; |
| default: |
| return TEE_ERROR_NOT_SUPPORTED; |
| } |
| |
| res = TEE_CreatePersistentObject(params[1].value.a, |
| object_id, params[0].memref.size, |
| TEE_DATA_FLAG_OVERWRITE, |
| NULL, NULL, 0, &o); |
| TEE_CloseObject(o); |
| |
| if (command == TA_STORAGE_CMD_CREATE_OVERWRITE) |
| TEE_Free(object_id); |
| |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_close(uint32_t param_types, TEE_Param params[4]) |
| { |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| TEE_CloseObject((TEE_ObjectHandle)(uintptr_t)params[0].value.a); |
| |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_read(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = VAL2HANDLE(params[1].value.a); |
| TEE_Result res = TEE_SUCCESS; |
| size_t sz = 0; |
| void *b0 = NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_MEMREF_OUTPUT, |
| TEE_PARAM_TYPE_VALUE_INOUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE)); |
| |
| b0 = TEE_Malloc(params[0].memref.size, 0); |
| if (!b0) |
| return TEE_ERROR_OUT_OF_MEMORY; |
| |
| sz = params[1].value.b; |
| res = TEE_ReadObjectData(o, b0, params[0].memref.size, &sz); |
| params[1].value.b = sz; |
| if (!res) |
| TEE_MemMove(params[0].memref.buffer, b0, params[0].memref.size); |
| TEE_Free(b0); |
| |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_write(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = VAL2HANDLE(params[1].value.a); |
| TEE_Result res = TEE_SUCCESS; |
| void *b0 = NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_MEMREF_INPUT, |
| TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE)); |
| |
| b0 = TEE_Malloc(params[0].memref.size, 0); |
| if (!b0) |
| return TEE_ERROR_OUT_OF_MEMORY; |
| TEE_MemMove(b0, params[0].memref.buffer, params[0].memref.size); |
| |
| res = TEE_WriteObjectData(o, b0, params[0].memref.size); |
| TEE_Free(b0); |
| |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_seek(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_Result res = TEE_ERROR_GENERIC; |
| TEE_ObjectInfo info; |
| TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a); |
| int32_t offs = 0; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, |
| TEE_PARAM_TYPE_VALUE_INOUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE)); |
| |
| offs = *(int32_t *)¶ms[0].value.b; |
| res = TEE_SeekObjectData(o, offs, params[1].value.a); |
| if (res != TEE_SUCCESS) |
| return res; |
| res = TEE_GetObjectInfo1(o, &info); |
| |
| params[1].value.b = info.dataPosition; |
| |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_unlink(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a); |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| TEE_CloseAndDeletePersistentObject1(o); |
| |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_rename(uint32_t command, uint32_t param_types, |
| TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a); |
| void *object_id = NULL; |
| TEE_Result res = TEE_ERROR_GENERIC; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, |
| TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE)); |
| |
| switch (command) { |
| case TA_STORAGE_CMD_RENAME: |
| if (params[0].memref.buffer) { |
| object_id = TEE_Malloc(params[1].memref.size, 0); |
| if (!object_id) |
| return TEE_ERROR_OUT_OF_MEMORY; |
| |
| TEE_MemMove(object_id, params[1].memref.buffer, |
| params[1].memref.size); |
| } |
| break; |
| case TA_STORAGE_CMD_RENAME_ID_IN_SHM: |
| object_id = params[1].memref.buffer; |
| break; |
| default: |
| return TEE_ERROR_NOT_SUPPORTED; |
| } |
| |
| res = TEE_RenamePersistentObject(o, object_id, params[1].memref.size); |
| |
| if (command == TA_STORAGE_CMD_RENAME) |
| TEE_Free(object_id); |
| |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_trunc(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a); |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| return TEE_TruncateObjectData(o, params[0].value.b); |
| } |
| |
| TEE_Result ta_storage_cmd_alloc_enum(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_Result res = TEE_ERROR_GENERIC; |
| TEE_ObjectEnumHandle oe = TEE_HANDLE_NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| res = TEE_AllocatePersistentObjectEnumerator(&oe); |
| params[0].value.a = (uintptr_t)oe; |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_free_enum(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a); |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| TEE_FreePersistentObjectEnumerator(oe); |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_reset_enum(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a); |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| TEE_ResetPersistentObjectEnumerator(oe); |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_start_enum(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a); |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| return TEE_StartPersistentObjectEnumerator(oe, params[0].value.b); |
| } |
| |
| TEE_Result ta_storage_cmd_next_enum(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a); |
| TEE_Result res = TEE_SUCCESS; |
| TEE_ObjectInfo *obj = NULL; |
| void *b2 = NULL; |
| |
| if (TEE_PARAM_TYPE_GET(param_types, 0) != TEE_PARAM_TYPE_VALUE_INPUT) |
| return TEE_ERROR_BAD_PARAMETERS; |
| if (TEE_PARAM_TYPE_GET(param_types, 2) != TEE_PARAM_TYPE_MEMREF_OUTPUT) |
| return TEE_ERROR_BAD_PARAMETERS; |
| if (TEE_PARAM_TYPE_GET(param_types, 3) != TEE_PARAM_TYPE_NONE) |
| return TEE_ERROR_BAD_PARAMETERS; |
| |
| if (params[2].memref.size < TEE_OBJECT_ID_MAX_LEN) |
| return TEE_ERROR_SHORT_BUFFER; |
| |
| if (TEE_PARAM_TYPE_GET(param_types, 1) == TEE_PARAM_TYPE_NONE) |
| obj = NULL; |
| else if (TEE_PARAM_TYPE_GET(param_types, 1) == |
| TEE_PARAM_TYPE_MEMREF_OUTPUT) { |
| if (params[1].memref.size < sizeof(TEE_ObjectInfo)) { |
| params[1].memref.size = sizeof(TEE_ObjectInfo); |
| return TEE_ERROR_SHORT_BUFFER; |
| } |
| params[1].memref.size = sizeof(TEE_ObjectInfo); |
| obj = TEE_Malloc(sizeof(TEE_ObjectInfo), 0); |
| if (!obj) |
| return TEE_ERROR_OUT_OF_MEMORY; |
| } else |
| return TEE_ERROR_BAD_PARAMETERS; |
| |
| b2 = TEE_Malloc(params[2].memref.size, 0); |
| if (!b2) { |
| res = TEE_ERROR_OUT_OF_MEMORY; |
| goto out; |
| } |
| |
| res = TEE_GetNextPersistentObject(oe, obj, b2, ¶ms[2].memref.size); |
| if (res) |
| goto out; |
| |
| TEE_MemMove(params[2].memref.buffer, b2, params[2].memref.size); |
| if (obj) |
| TEE_MemMove(params[1].memref.buffer, obj, sizeof(*obj)); |
| out: |
| TEE_Free(b2); |
| TEE_Free(obj); |
| |
| return res; |
| } |
| |
| static TEE_Result check_obj(TEE_ObjectInfo *o1, TEE_ObjectInfo *o2) |
| { |
| if ((o1->objectType != o2->objectType) || |
| (o1->objectSize != o2->objectSize) || |
| (o1->maxObjectSize != o2->maxObjectSize) || |
| (o1->objectUsage != o2->objectUsage)) |
| return TEE_ERROR_GENERIC; |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_key_in_persistent(uint32_t param_types, |
| TEE_Param params[4]) |
| { |
| TEE_Result result = TEE_SUCCESS; |
| TEE_ObjectHandle transient_key = TEE_HANDLE_NULL; |
| TEE_ObjectHandle persistent_key = TEE_HANDLE_NULL; |
| TEE_ObjectHandle key = TEE_HANDLE_NULL; |
| TEE_OperationHandle encrypt_op = TEE_HANDLE_NULL; |
| TEE_ObjectInfo keyInfo; |
| TEE_ObjectInfo keyInfo2; |
| TEE_ObjectInfo keyInfo3; |
| uint32_t alg = TEE_ALG_AES_CBC_NOPAD; |
| void *IV = NULL; |
| size_t IVlen = 16; |
| size_t key_size = 256; |
| uint32_t objectID = 1; |
| uint32_t flags = TEE_DATA_FLAG_ACCESS_READ | |
| TEE_DATA_FLAG_ACCESS_WRITE | |
| TEE_DATA_FLAG_ACCESS_WRITE_META | |
| TEE_DATA_FLAG_SHARE_READ | |
| TEE_DATA_FLAG_SHARE_WRITE; |
| |
| TEE_MemFill(&keyInfo, 0, sizeof(keyInfo)); |
| TEE_MemFill(&keyInfo2, 0, sizeof(keyInfo2)); |
| TEE_MemFill(&keyInfo3, 0, sizeof(keyInfo3)); |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| result = TEE_AllocateTransientObject(TEE_TYPE_AES, key_size, |
| &transient_key); |
| if (result != TEE_SUCCESS) { |
| EMSG("Failed to Allocate transient object handle : 0x%x", |
| result); |
| goto cleanup1; |
| } |
| |
| result = TEE_GenerateKey(transient_key, key_size, NULL, 0); |
| if (result != TEE_SUCCESS) { |
| EMSG("Failed to generate a transient key: 0x%x", result); |
| goto cleanup2; |
| } |
| |
| TEE_GetObjectInfo1(transient_key, &keyInfo); |
| result = TEE_CreatePersistentObject(params[0].value.a, |
| &objectID, sizeof(objectID), |
| flags, transient_key, NULL, 0, |
| &persistent_key); |
| if (result != TEE_SUCCESS) { |
| EMSG("Failed to create a persistent key: 0x%x", result); |
| goto cleanup2; |
| } |
| |
| TEE_GetObjectInfo1(persistent_key, &keyInfo2); |
| result = check_obj(&keyInfo, &keyInfo2); |
| if (result != TEE_SUCCESS) { |
| EMSG("keyInfo and keyInfo2 are different"); |
| goto cleanup2; |
| } |
| |
| TEE_CloseAndDeletePersistentObject1(persistent_key); |
| |
| /* Transform the transient object into a persistent object */ |
| result = TEE_CreatePersistentObject(params[0].value.a, |
| &objectID, sizeof(objectID), |
| flags, transient_key, NULL, 0, |
| NULL); |
| if (result != TEE_SUCCESS) { |
| EMSG("Failed to create a persistent key: 0x%x", result); |
| goto cleanup2; |
| } |
| persistent_key = transient_key; |
| transient_key = TEE_HANDLE_NULL; |
| |
| TEE_GetObjectInfo1(persistent_key, &keyInfo2); |
| result = check_obj(&keyInfo, &keyInfo2); |
| if (result != TEE_SUCCESS) { |
| EMSG("keyInfo and keyInfo2 are different"); |
| goto cleanup2; |
| } |
| |
| TEE_CloseObject(persistent_key); |
| |
| result = TEE_OpenPersistentObject(params[0].value.a, |
| &objectID, sizeof(objectID), |
| flags, &key); |
| if (result != TEE_SUCCESS) { |
| EMSG("Failed to open persistent key: 0x%x", result); |
| goto cleanup2; |
| } |
| |
| TEE_GetObjectInfo(key, &keyInfo3); |
| result = check_obj(&keyInfo3, &keyInfo2); |
| if (result != TEE_SUCCESS) { |
| EMSG("keyInfo2 and keyInfo3 are different"); |
| goto cleanup2; |
| } |
| |
| result = TEE_AllocateOperation(&encrypt_op, alg, TEE_MODE_ENCRYPT, |
| keyInfo3.maxObjectSize); |
| if (result != TEE_SUCCESS) { |
| EMSG("Failed to allocate an operation: 0x%x", result); |
| goto cleanup3; |
| } |
| |
| result = TEE_SetOperationKey(encrypt_op, key); |
| if (result != TEE_SUCCESS) { |
| EMSG("Failed to set operation key: 0x%x", result); |
| goto cleanup4; |
| } |
| |
| IV = TEE_Malloc(IVlen, 0); |
| if (!IV) { |
| EMSG("Out of memory for IV."); |
| result = TEE_ERROR_OUT_OF_MEMORY; |
| goto cleanup4; |
| } |
| |
| TEE_CipherInit(encrypt_op, IV, IVlen); |
| TEE_Free(IV); |
| |
| cleanup4: |
| TEE_FreeOperation(encrypt_op); |
| cleanup3: |
| TEE_CloseAndDeletePersistentObject1(key); |
| cleanup2: |
| TEE_FreeTransientObject(transient_key); |
| cleanup1: |
| return result; |
| } |
| |
| TEE_Result ta_storage_cmd_loop(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectHandle object = TEE_HANDLE_NULL; |
| TEE_Result res = TEE_ERROR_GENERIC; |
| int object_id = 0; |
| uint32_t flags = TEE_DATA_FLAG_OVERWRITE | |
| TEE_DATA_FLAG_ACCESS_WRITE_META; |
| int i = 0; |
| |
| (void)params; |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| for (i = 0; i < 20; i++) { |
| DMSG("\n\nLOOP : %d", i); |
| object = TEE_HANDLE_NULL; |
| object_id = i; |
| res = TEE_CreatePersistentObject(params[0].value.a, |
| &object_id, sizeof(int), flags, |
| TEE_HANDLE_NULL, NULL, 0, |
| &object); |
| |
| if (res != TEE_SUCCESS) { |
| EMSG("FAIL"); |
| return res; |
| } |
| |
| res = TEE_CloseAndDeletePersistentObject1(object); |
| if (res != TEE_SUCCESS) { |
| EMSG("FAIL"); |
| return res; |
| } |
| } |
| |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_restrict_usage(uint32_t param_types, |
| TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = TEE_HANDLE_NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| o = (TEE_ObjectHandle)(uintptr_t)params[0].value.a; |
| TEE_RestrictObjectUsage1(o, params[0].value.b); |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_alloc_obj(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_Result res = TEE_ERROR_GENERIC; |
| TEE_ObjectHandle o = TEE_HANDLE_NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, |
| TEE_PARAM_TYPE_VALUE_OUTPUT, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| res = TEE_AllocateTransientObject(params[0].value.a, params[0].value.b, |
| &o); |
| params[1].value.a = (uint32_t)(uintptr_t)o; |
| return res; |
| } |
| |
| TEE_Result ta_storage_cmd_free_obj(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = TEE_HANDLE_NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| o = (TEE_ObjectHandle)(uintptr_t)params[0].value.a; |
| TEE_FreeTransientObject(o); |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_reset_obj(uint32_t param_types, TEE_Param params[4]) |
| { |
| TEE_ObjectHandle o = TEE_HANDLE_NULL; |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); |
| |
| o = (TEE_ObjectHandle)(uintptr_t)params[0].value.a; |
| TEE_ResetTransientObject(o); |
| return TEE_SUCCESS; |
| } |
| |
| TEE_Result ta_storage_cmd_get_obj_info(uint32_t param_types, |
| TEE_Param params[4]) |
| { |
| TEE_Result res = TEE_ERROR_GENERIC; |
| struct ta_storage_obj_info oi = { }; |
| TEE_ObjectInfo info = { }; |
| TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a); |
| |
| ASSERT_PARAM_TYPE(TEE_PARAM_TYPES |
| (TEE_PARAM_TYPE_VALUE_INPUT, |
| TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE, |
| TEE_PARAM_TYPE_NONE)); |
| |
| if (params[1].memref.size < sizeof(oi)) |
| return TEE_ERROR_SHORT_BUFFER; |
| res = TEE_GetObjectInfo1(o, &info); |
| if (!res) { |
| params[1].memref.size = sizeof(oi); |
| oi.object_type = info.objectType; |
| oi.object_size = info.objectSize; |
| oi.max_object_size = info.maxObjectSize; |
| oi.object_usage = info.objectUsage; |
| oi.data_size = info.dataSize; |
| oi.data_position = info.dataPosition; |
| oi.handle_flags = info.handleFlags; |
| TEE_MemMove(params[1].memref.buffer, &oi, sizeof(oi)); |
| } |
| |
| return res; |
| } |