ta
secure_storage_ta.cHuongnm
c_cpp
2 months ago
6.4 kB
8
Indexable
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2017, Linaro Limited
* All rights reserved.
*/
#include <inttypes.h>
#include <secure_storage_ta.h>
#include <tee_internal_api.h>
#include <tee_internal_api_extensions.h>
static TEE_Result delete_object(uint32_t param_types, TEE_Param params[4])
{
const uint32_t exp_param_types =
TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);
TEE_ObjectHandle object = TEE_HANDLE_NULL;
TEE_Result res = TEE_ERROR_GENERIC;
char *obj_id = NULL;
size_t obj_id_sz = 0;
/*
* Safely get the invocation parameters
*/
if (param_types != exp_param_types)
return TEE_ERROR_BAD_PARAMETERS;
obj_id_sz = params[0].memref.size;
obj_id = TEE_Malloc(obj_id_sz, 0);
if (!obj_id)
return TEE_ERROR_OUT_OF_MEMORY;
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
/*
* Check object exists and delete it
*/
res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
obj_id, obj_id_sz,
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, /* we must be allowed to delete it */
&object);
if (res != TEE_SUCCESS) {
EMSG("Failed to open persistent object, res=0x%08x", res);
TEE_Free(obj_id);
return res;
}
TEE_CloseAndDeletePersistentObject1(object);
TEE_Free(obj_id);
return res;
}
static TEE_Result create_raw_object(uint32_t param_types, TEE_Param params[4])
{
const uint32_t exp_param_types =
TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);
TEE_ObjectHandle object = TEE_HANDLE_NULL;
TEE_Result res = TEE_ERROR_GENERIC;
char *obj_id = NULL;
size_t obj_id_sz = 0;
char *data = NULL;
size_t data_sz = 0;
uint32_t obj_data_flag = 0;
/*
* Safely get the invocation parameters
*/
if (param_types != exp_param_types)
return TEE_ERROR_BAD_PARAMETERS;
obj_id_sz = params[0].memref.size;
obj_id = TEE_Malloc(obj_id_sz, 0);
if (!obj_id)
return TEE_ERROR_OUT_OF_MEMORY;
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
data_sz = params[1].memref.size;
data = TEE_Malloc(data_sz, 0);
if (!data) {
TEE_Free(obj_id);
return TEE_ERROR_OUT_OF_MEMORY;
}
TEE_MemMove(data, params[1].memref.buffer, data_sz);
/*
* Create object in secure storage and fill with data
*/
obj_data_flag = TEE_DATA_FLAG_ACCESS_READ | /* we can later read the oject */
TEE_DATA_FLAG_ACCESS_WRITE | /* we can later write into the object */
TEE_DATA_FLAG_ACCESS_WRITE_META | /* we can later destroy or rename the object */
TEE_DATA_FLAG_OVERWRITE; /* destroy existing object of same ID */
res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
obj_id, obj_id_sz,
obj_data_flag,
TEE_HANDLE_NULL,
NULL, 0, /* we may not fill it right now */
&object);
if (res != TEE_SUCCESS) {
EMSG("TEE_CreatePersistentObject failed 0x%08x", res);
TEE_Free(obj_id);
TEE_Free(data);
return res;
}
res = TEE_WriteObjectData(object, data, data_sz);
if (res != TEE_SUCCESS) {
EMSG("TEE_WriteObjectData failed 0x%08x", res);
TEE_CloseAndDeletePersistentObject1(object);
} else {
TEE_CloseObject(object);
}
TEE_Free(obj_id);
TEE_Free(data);
return res;
}
static TEE_Result read_raw_object(uint32_t param_types, TEE_Param params[4])
{
const uint32_t exp_param_types =
TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_MEMREF_OUTPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);
TEE_ObjectHandle object = TEE_HANDLE_NULL;
TEE_ObjectInfo object_info = { };
TEE_Result res = TEE_ERROR_GENERIC;
uint32_t read_bytes = 0;
char *obj_id = NULL;
size_t obj_id_sz = 0;
char *data = NULL;
size_t data_sz = 0;
/*
* Safely get the invocation parameters
*/
if (param_types != exp_param_types)
return TEE_ERROR_BAD_PARAMETERS;
obj_id_sz = params[0].memref.size;
obj_id = TEE_Malloc(obj_id_sz, 0);
if (!obj_id)
return TEE_ERROR_OUT_OF_MEMORY;
TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
data_sz = params[1].memref.size;
data = TEE_Malloc(data_sz, 0);
if (!data) {
TEE_Free(obj_id);
return TEE_ERROR_OUT_OF_MEMORY;
}
/*
* Check the object exist and can be dumped into output buffer
* then dump it.
*/
res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
obj_id, obj_id_sz,
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_SHARE_READ,
&object);
if (res != TEE_SUCCESS) {
EMSG("Failed to open persistent object, res=0x%08x", res);
TEE_Free(obj_id);
TEE_Free(data);
return res;
}
res = TEE_GetObjectInfo1(object, &object_info);
if (res != TEE_SUCCESS) {
EMSG("Failed to create persistent object, res=0x%08x", res);
goto exit;
}
if (object_info.dataSize > data_sz) {
/*
* Provided buffer is too short.
* Return the expected size together with status "short buffer"
*/
params[1].memref.size = object_info.dataSize;
res = TEE_ERROR_SHORT_BUFFER;
goto exit;
}
res = TEE_ReadObjectData(object, data, object_info.dataSize,
&read_bytes);
if (res == TEE_SUCCESS)
TEE_MemMove(params[1].memref.buffer, data, read_bytes);
if (res != TEE_SUCCESS || read_bytes != object_info.dataSize) {
EMSG("TEE_ReadObjectData failed 0x%08x, read %" PRIu32 " over %u",
res, read_bytes, object_info.dataSize);
goto exit;
}
/* Return the number of byte effectively filled */
params[1].memref.size = read_bytes;
exit:
TEE_CloseObject(object);
TEE_Free(obj_id);
TEE_Free(data);
return res;
}
TEE_Result TA_CreateEntryPoint(void)
{
/* Nothing to do */
return TEE_SUCCESS;
}
void TA_DestroyEntryPoint(void)
{
/* Nothing to do */
}
TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types,
TEE_Param __unused params[4],
void __unused **session)
{
/* Nothing to do */
return TEE_SUCCESS;
}
void TA_CloseSessionEntryPoint(void __unused *session)
{
/* Nothing to do */
}
TEE_Result TA_InvokeCommandEntryPoint(void __unused *session,
uint32_t command,
uint32_t param_types,
TEE_Param params[4])
{
switch (command) {
case TA_SECURE_STORAGE_CMD_WRITE_RAW:
return create_raw_object(param_types, params);
case TA_SECURE_STORAGE_CMD_READ_RAW:
return read_raw_object(param_types, params);
case TA_SECURE_STORAGE_CMD_DELETE:
return delete_object(param_types, params);
default:
EMSG("Command ID 0x%x is not supported", command);
return TEE_ERROR_NOT_SUPPORTED;
}
}
Editor is loading...
Leave a Comment