blob: c0e8e904fe3db3a1a3f9569bb333f904e3768750 [file] [log] [blame]
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License Version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <adbg.h>
#include <xtest_test.h>
#include <xtest_helpers.h>
#include <tee_client_api.h>
#include <ta_storage.h>
#include <tee_api_defines.h>
#include <tee_api_defines_extensions.h>
#include <tee_api_types.h>
#ifdef WITH_GP_TESTS
#include <TTA_DS_protocol.h>
#endif
#include <util.h>
static uint32_t storage_ids[] = {
TEE_STORAGE_PRIVATE,
#ifdef CFG_REE_FS
TEE_STORAGE_PRIVATE_REE,
#endif
#ifdef CFG_RPMB_FS
TEE_STORAGE_PRIVATE_RPMB,
#endif
};
static uint8_t file_00[] = {
0x00, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
0xF0, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
0xE9, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
0xF0, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x8E
};
static uint8_t file_01[] = {
0x01, 0x00
};
static uint8_t file_02[] = {
0x02, 0x11, 0x02
};
static uint8_t file_03[] = {
0x03, 0x13, 0x03
};
static uint8_t file_04[] = {
0x00, 0x01, 0x02
};
static uint8_t data_00[] = {
0x00, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
0x00, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
0x00, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
0x00, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x00
};
static uint8_t data_01[] = {
0x01, 0x6E, 0x04, 0x57, 0x08, 0xFB, 0x71, 0x96,
0x01, 0x2E, 0x55, 0x3D, 0x02, 0xC3, 0xA6, 0x92,
0x01, 0xC3, 0xEF, 0x8A, 0xB2, 0x34, 0x53, 0xE6,
0x01, 0x74, 0x9C, 0xD6, 0x36, 0xE7, 0xA8, 0x01
};
static uint32_t fs_id_for_tee_storage_private(void)
{
#if defined(CFG_REE_FS)
return TEE_STORAGE_PRIVATE_REE;
#elif defined(CFG_RPMB_FS)
return TEE_STORAGE_PRIVATE_RPMB;
#endif
}
static uint32_t real_id_for(uint32_t id)
{
if (id == TEE_STORAGE_PRIVATE)
return fs_id_for_tee_storage_private();
return id;
}
static bool storage_is(uint32_t id1, uint32_t id2)
{
return (real_id_for(id1) == real_id_for(id2));
}
static TEEC_Result fs_open(TEEC_Session *sess, void *id, uint32_t id_size,
uint32_t flags, uint32_t *obj, uint32_t storage_id)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
TEEC_Result res;
uint32_t org;
op.params[0].tmpref.buffer = id;
op.params[0].tmpref.size = id_size;
op.params[1].value.a = flags;
op.params[1].value.b = 0;
op.params[2].value.a = storage_id;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_VALUE_INOUT, TEEC_VALUE_INPUT,
TEEC_NONE);
res = TEEC_InvokeCommand(sess, TA_STORAGE_CMD_OPEN, &op, &org);
if (res == TEEC_SUCCESS)
*obj = op.params[1].value.b;
return res;
}
static TEEC_Result fs_create(TEEC_Session *sess, void *id, uint32_t id_size,
uint32_t flags, uint32_t attr, void *data,
uint32_t data_size, uint32_t *obj,
uint32_t storage_id)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
TEEC_Result res;
uint32_t org;
op.params[0].tmpref.buffer = id;
op.params[0].tmpref.size = id_size;
op.params[1].value.a = flags;
op.params[1].value.b = 0;
op.params[2].value.a = attr;
op.params[2].value.b = storage_id;
op.params[3].tmpref.buffer = data;
op.params[3].tmpref.size = data_size;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_VALUE_INOUT, TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT);
res = TEEC_InvokeCommand(sess, TA_STORAGE_CMD_CREATE, &op, &org);
if (res == TEEC_SUCCESS)
*obj = op.params[1].value.b;
return res;
}
static TEEC_Result fs_create_overwrite(TEEC_Session *sess, void *id,
uint32_t id_size, uint32_t storage_id)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
TEEC_Result res;
uint32_t org;
op.params[0].tmpref.buffer = id;
op.params[0].tmpref.size = id_size;
op.params[1].value.a = storage_id;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE);
res = TEEC_InvokeCommand(sess, TA_STORAGE_CMD_CREATE_OVERWRITE, &op, &org);
return res;
}
static TEEC_Result fs_close(TEEC_Session *sess, uint32_t obj)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_CLOSE, &op, &org);
}
static TEEC_Result fs_read(TEEC_Session *sess, uint32_t obj, void *data,
uint32_t data_size, uint32_t *count)
{
TEEC_Result res;
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].tmpref.buffer = data;
op.params[0].tmpref.size = data_size;
op.params[1].value.a = obj;
op.params[1].value.b = 0;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
TEEC_VALUE_INOUT, TEEC_NONE,
TEEC_NONE);
res = TEEC_InvokeCommand(sess, TA_STORAGE_CMD_READ, &op, &org);
if (res == TEEC_SUCCESS)
*count = op.params[1].value.b;
return res;
}
static TEEC_Result fs_write(TEEC_Session *sess, uint32_t obj, void *data,
uint32_t data_size)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].tmpref.buffer = data;
op.params[0].tmpref.size = data_size;
op.params[1].value.a = obj;
op.params[1].value.b = 0;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_WRITE, &op, &org);
}
static TEEC_Result fs_seek(TEEC_Session *sess, uint32_t obj, int32_t offset,
int32_t whence)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.params[0].value.b = *(uint32_t *)&offset;
op.params[1].value.a = whence;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INOUT,
TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_SEEK, &op, &org);
}
static TEEC_Result fs_unlink(TEEC_Session *sess, uint32_t obj)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_UNLINK, &op, &org);
}
static TEEC_Result fs_trunc(TEEC_Session *sess, uint32_t obj, uint32_t len)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.params[0].value.b = len;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_TRUNC, &op, &org);
}
static TEEC_Result fs_rename(TEEC_Session *sess, uint32_t obj, void *id,
uint32_t id_size)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.params[1].tmpref.buffer = id;
op.params[1].tmpref.size = id_size;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_RENAME, &op, &org);
}
static TEEC_Result fs_alloc_enum(TEEC_Session *sess, uint32_t *e)
{
TEEC_Result res;
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
res = TEEC_InvokeCommand(sess, TA_STORAGE_CMD_ALLOC_ENUM, &op, &org);
if (res == TEEC_SUCCESS)
*e = op.params[0].value.a;
return res;
}
static TEEC_Result fs_reset_enum(TEEC_Session *sess, uint32_t e)
{
TEEC_Result res;
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
op.params[0].value.a = e;
res = TEEC_InvokeCommand(sess, TA_STORAGE_CMD_RESET_ENUM, &op, &org);
return res;
}
static TEEC_Result fs_free_enum(TEEC_Session *sess, uint32_t e)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
TEEC_NONE);
op.params[0].value.a = e;
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_FREE_ENUM, &op, &org);
}
static TEEC_Result fs_start_enum(TEEC_Session *sess, uint32_t e,
uint32_t storage_id)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
op.params[0].value.a = e;
op.params[0].value.b = storage_id;
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_START_ENUM, &op, &org);
}
static TEEC_Result fs_next_enum(TEEC_Session *sess, uint32_t e, void *obj_info,
size_t info_size, void *id, uint32_t id_size)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
if (obj_info && info_size)
op.paramTypes |= (TEEC_MEMREF_TEMP_OUTPUT << 4);
op.params[0].value.a = e;
op.params[1].tmpref.buffer = obj_info;
op.params[1].tmpref.size = info_size;
op.params[2].tmpref.buffer = id;
op.params[2].tmpref.size = id_size;
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_NEXT_ENUM, &op, &org);
}
static TEEC_Result fs_restrict_usage(TEEC_Session *sess, uint32_t obj,
uint32_t obj_usage)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.params[0].value.b = obj_usage;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_RESTRICT_USAGE,
&op, &org);
}
static TEEC_Result fs_alloc_obj(TEEC_Session *sess, uint32_t obj_type,
uint32_t max_key_size, uint32_t *obj)
{
TEEC_Result res;
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj_type;
op.params[0].value.b = max_key_size;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
TEEC_NONE, TEEC_NONE);
res = TEEC_InvokeCommand(sess, TA_STORAGE_CMD_ALLOC_OBJ, &op, &org);
*obj = op.params[1].value.a;
return res;
}
static TEEC_Result fs_free_obj(TEEC_Session *sess, uint32_t obj)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_FREE_OBJ, &op, &org);
}
static TEEC_Result fs_reset_obj(TEEC_Session *sess, uint32_t obj)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.params[0].value.a = obj;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_RESET_OBJ, &op, &org);
}
static TEEC_Result fs_get_obj_info(TEEC_Session *sess, uint32_t obj,
void *obj_info, size_t info_size)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_OUTPUT,
TEEC_NONE, TEEC_NONE);
op.params[0].value.a = obj;
op.params[1].tmpref.buffer = obj_info;
op.params[1].tmpref.size = info_size;
return TEEC_InvokeCommand(sess, TA_STORAGE_CMD_GET_OBJ_INFO, &op, &org);
}
/* trunc */
static void test_truncate_file_length(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint8_t out[10] = { 0 };
uint32_t count;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
/* trunc */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_trunc(&sess, obj, 10)))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, fs_seek(&sess, obj, 5, TEE_DATA_SEEK_SET)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* check buffer */
(void)ADBG_EXPECT_BUFFER(c, &data_00[5], 5, out, count);
/* close */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
/* open */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, fs_seek(&sess, obj, 5, TEE_DATA_SEEK_SET)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* check buffer */
(void)ADBG_EXPECT_BUFFER(c, &data_00[5], 5, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
/* extend */
static void test_extend_file_length(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint8_t out[10] = { 0 };
uint8_t expect[10] = { 0 };
uint32_t count;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
/* extend */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_trunc(&sess, obj, 40)))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, fs_seek(&sess, obj, 30, TEE_DATA_SEEK_SET)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* check buffer */
expect[0] = data_00[30];
expect[1] = data_00[31];
(void)ADBG_EXPECT_BUFFER(c, &expect[0], 10, out, count);
/* close */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
/* open */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, fs_seek(&sess, obj, 30, TEE_DATA_SEEK_SET)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* check buffer */
expect[0] = data_00[30];
expect[1] = data_00[31];
(void)ADBG_EXPECT_BUFFER(c, &expect[0], 10, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
/* file hole */
static void test_file_hole(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint8_t out[10] = { 0 };
uint8_t expect[10] = { 0 };
uint32_t count;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, fs_seek(&sess, obj, 80, TEE_DATA_SEEK_SET)))
goto exit;
/* write */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_write(&sess, obj, data_00,
sizeof(data_00))))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, fs_seek(&sess, obj, 74, TEE_DATA_SEEK_SET)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* check buffer */
expect[6] = data_00[0];
expect[7] = data_00[1];
expect[8] = data_00[2];
expect[9] = data_00[3];
(void)ADBG_EXPECT_BUFFER(c, &expect[0], 10, out, count);
/* close */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
/* open */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, fs_seek(&sess, obj, 74, TEE_DATA_SEEK_SET)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* check buffer */
expect[6] = data_00[0];
expect[7] = data_00[1];
expect[8] = data_00[2];
expect[9] = data_00[3];
(void)ADBG_EXPECT_BUFFER(c, &expect[0], 10, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
#ifdef WITH_GP_TESTS
static TEEC_Result ds_seek_obj_inv_handle(TEEC_Session *sess)
{
TEEC_Operation op;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
op.params[0].value.a = CASE_DATA_OBJECT_NOT_PERSISTENT;
return TEEC_InvokeCommand(
sess, CMD_SeekObjectData_panic, &op, &org);
}
static TEEC_Result ds_seek_gp(
TEEC_Session *sess, TEE_Whence wh, uint32_t wh_off, uint32_t set_off,
void *in, size_t in_size, void *out, size_t out_size)
{
TEEC_Operation op;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_OUTPUT);
op.params[0].value.a = wh;
op.params[0].value.b = wh_off;
op.params[1].value.a = set_off;
op.params[2].tmpref.buffer = in;
op.params[2].tmpref.size = in_size;
op.params[3].tmpref.buffer = out;
op.params[3].tmpref.size = out_size;
return TEEC_InvokeCommand(sess, CMD_SeekWriteReadObjectData, &op, &org);
}
static TEEC_Result ds_init_object_and_attributes(TEEC_Session *sess,
uint32_t obj_type, uint32_t obj_size, const void *attr_meta,
size_t attr_meta_len, const void *attr_data, size_t attr_data_len,
uint32_t option)
{
TEEC_Operation op;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_INPUT, TEEC_VALUE_INPUT);
op.params[0].value.a = obj_type;
op.params[0].value.b = obj_size;
op.params[1].tmpref.buffer = (void *)attr_meta;
op.params[1].tmpref.size = attr_meta_len;
op.params[2].tmpref.buffer = (void *)attr_data;
op.params[2].tmpref.size = attr_data_len;
op.params[3].value.a = option;
return TEEC_InvokeCommand(sess, CMD_InitObjectAndAttributes, &op, &org);
}
static TEEC_Result ds_rename_access_conflict(TEEC_Session *sess)
{
TEEC_Operation op;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(
sess, CMD_RenamePersistentObject_AccessConflict, &op, &org);
}
static TEEC_Result ds_start_enum_no_item(TEEC_Session *sess)
{
TEEC_Operation op;
uint32_t org;
TEEC_Result res;
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
res = TEEC_InvokeCommand(
sess, CMD_StartNGetPersistentObjectEnumerator_itemNotFound, &op, &org);
if (res != TEEC_SUCCESS)
return res;
if (op.params[0].value.a != 0 || op.params[0].value.b != 0)
return TEEC_ERROR_GENERIC;
return res;
}
static TEEC_Result ds_rename_success(TEEC_Session *sess)
{
TEEC_Operation op;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(
sess, CMD_RenamePersistentObject_Success, &op, &org);
}
static TEEC_Result ds_null_close_free_reset(TEEC_Session *sess)
{
TEEC_Operation op;
uint32_t org;
op.paramTypes = TEEC_PARAM_TYPES(
TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
return TEEC_InvokeCommand(
sess, CMD_CloseFreeAndResetObjectSuccessHandleNull, &op, &org);
}
#endif
/* create */
static void xtest_tee_test_6001_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_00, sizeof(file_00),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
#define DEFINE_TEST_MULTIPLE_STORAGE_IDS(test_name) \
static void test_name(ADBG_Case_t *c) \
{ \
size_t i; \
\
for (i = 0; i < ARRAY_SIZE(storage_ids); i++) { \
Do_ADBG_BeginSubCase(c, "Storage id: %08x", storage_ids[i]); \
test_name##_single(c, storage_ids[i]); \
Do_ADBG_EndSubCase(c, "Storage id: %08x", storage_ids[i]); \
} \
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6001)
/* open */
static void xtest_tee_test_6002_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6002)
/* read */
static void xtest_tee_test_6003_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint8_t out[10] = { 0 };
uint32_t count;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_01,
sizeof(data_01), &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
(void)ADBG_EXPECT_BUFFER(c, data_01, 10, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6003)
/* write */
static void xtest_tee_test_6004_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint8_t out[10] = { 0 };
uint32_t count;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_01,
sizeof(data_01), &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
/* write new data */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_WRITE, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_write(&sess, obj, data_00, sizeof(data_00))))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
(void)ADBG_EXPECT_BUFFER(c, data_00, 10, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6004)
/* seek */
static void xtest_tee_test_6005_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint8_t out[10] = { 0 };
uint32_t count;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
/* seek */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_seek(&sess, obj, 10, TEE_DATA_SEEK_SET)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
(void)ADBG_EXPECT_BUFFER(c, &data_00[10], 10, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6005)
/* unlink */
static void xtest_tee_test_6006_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
/* del & close */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
/* check result */
if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ITEM_NOT_FOUND,
fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_READ, &obj, storage_id)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6006)
static void xtest_tee_test_6007_single(ADBG_Case_t *c, uint32_t storage_id)
{
Do_ADBG_BeginSubCase(c, "Test truncate file length");
test_truncate_file_length(c, storage_id);
Do_ADBG_EndSubCase(c, "Test truncate file length");
Do_ADBG_BeginSubCase(c, "Test extend file length");
test_extend_file_length(c, storage_id);
Do_ADBG_EndSubCase(c, "Test extend file length");
Do_ADBG_BeginSubCase(c, "Test file hole");
test_file_hole(c, storage_id);
Do_ADBG_EndSubCase(c, "Test file hole");
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6007)
static void xtest_tee_test_6008_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj;
uint8_t out[10] = { 0 };
uint32_t count;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_01,
sizeof(data_01), &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
/* write new data */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_write(&sess, obj, data_00, sizeof(data_00))))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_rename(&sess, obj, file_03, sizeof(file_03))))
goto exit;
/* close */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_03, sizeof(file_03),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* check buffer */
(void)ADBG_EXPECT_BUFFER(c, data_00, 10, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6008)
static void xtest_tee_test_6009_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t obj0;
uint32_t obj1;
uint32_t obj2;
uint32_t e = 0;
uint8_t info[200];
uint8_t id[200];
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
/* create file 00 */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_00, sizeof(file_00),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_01,
sizeof(data_01), &obj0, storage_id)))
goto exit;
/* create file 01 */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_01,
sizeof(data_01), &obj1, storage_id)))
goto exit;
/* create file 02 */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_01,
sizeof(data_01), &obj2, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj0)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj1)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj2)))
goto exit;
/* iterate */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_alloc_enum(&sess, &e)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_start_enum(&sess, e, storage_id)))
goto exit;
/* get 00 */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_next_enum(&sess, e, info, sizeof(info), id, sizeof(id))))
goto exit;
/* get 01 */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_next_enum(&sess, e, NULL, 0, id, sizeof(id))))
goto exit;
/* get 02 */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_next_enum(&sess, e, info, sizeof(info), id, sizeof(id))))
goto exit;
/* we should not have more files */
if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ITEM_NOT_FOUND,
fs_next_enum(&sess, e, info, sizeof(info), id, sizeof(id))))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_free_enum(&sess, e)))
goto exit;
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_00, sizeof(file_00),
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj0, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj0)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj1, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj1)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_02, sizeof(file_02),
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj2, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj2)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6009)
static void xtest_tee_test_6010_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t orig;
uint32_t o1;
uint32_t o2;
uint32_t e;
uint32_t f;
uint8_t data[1024];
uint8_t out[1024];
uint32_t n;
for (n = 0; n < ARRAY_SIZE(data); n++)
data[n] = n;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
Do_ADBG_BeginSubCase(c, "CreatePersistentObject AccessConflict");
o1 = TEE_HANDLE_NULL;
o2 = TEE_HANDLE_NULL;
f = 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_DATA_FLAG_OVERWRITE;
ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_00, sizeof(file_00), f, 0, data,
sizeof(data), &o1, storage_id));
f = TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE;
ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ACCESS_CONFLICT,
fs_create(&sess, file_00, sizeof(file_00), f, 0, data,
sizeof(data), &o2, storage_id));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, o1));
if (o2)
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, o2));
Do_ADBG_EndSubCase(c, "CreatePersistentObject AccessConflict");
Do_ADBG_BeginSubCase(c, "RestrictObjectUsage Panic");
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_TARGET_DEAD,
fs_restrict_usage(&sess, 0xffffbad0, 0xffffffff));
Do_ADBG_EndSubCase(c, "RestrictObjectUsage Panic");
TEEC_CloseSession(&sess);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
Do_ADBG_BeginSubCase(c, "SeekObjectData BadHandle");
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_TARGET_DEAD,
fs_seek(&sess, 0xffffbad0, 5, TEE_DATA_SEEK_SET));
Do_ADBG_EndSubCase(c, "SeekObjectData BadHandle");
TEEC_CloseSession(&sess);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
Do_ADBG_BeginSubCase(c, "SeekObjectData NotPersist");
o1 = 0;
ADBG_EXPECT_TEEC_SUCCESS(c,
fs_alloc_obj(&sess, TEE_TYPE_AES, 256, &o1));
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_TARGET_DEAD,
fs_seek(&sess, o1, 5, TEE_DATA_SEEK_SET));
Do_ADBG_EndSubCase(c, "SeekObjectData NotPersist");
TEEC_CloseSession(&sess);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
Do_ADBG_BeginSubCase(c, "SeekWriteRead");
o1 = 0;
f = 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_DATA_FLAG_OVERWRITE;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_00, sizeof(file_00), f, 0, data,
sizeof(data), &o1, storage_id)))
goto seek_write_read_out;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_seek(&sess, o1, 2, TEE_DATA_SEEK_SET)))
goto seek_write_read_out;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_seek(&sess, o1, 0, TEE_DATA_SEEK_END)))
goto seek_write_read_out;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_write(&sess, o1, data, sizeof(data))))
goto seek_write_read_out;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_seek(&sess, o1, sizeof(data), TEE_DATA_SEEK_SET)))
goto seek_write_read_out;
memset(out, 0xab, sizeof(out));
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_read(&sess, o1, out, sizeof(out), &n)))
goto seek_write_read_out;
ADBG_EXPECT_BUFFER(c, data, sizeof(data), out, n);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_seek(&sess, o1, 10, TEE_DATA_SEEK_END)))
goto seek_write_read_out;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_read(&sess, o1, out, sizeof(out), &n)))
goto seek_write_read_out;
ADBG_EXPECT_COMPARE_UNSIGNED(c, n, ==, 0);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_seek(&sess, o1, -(int32_t)sizeof(data) / 2,
TEE_DATA_SEEK_END)))
goto seek_write_read_out;
memset(out, 0xab, sizeof(out) / 2);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_read(&sess, o1, out, sizeof(out) / 2, &n)))
goto seek_write_read_out;
ADBG_EXPECT_BUFFER(c,
data + sizeof(data) / 2, sizeof(data) / 2,
out, n);
seek_write_read_out:
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, o1));
Do_ADBG_EndSubCase(c, "SeekWriteRead");
Do_ADBG_BeginSubCase(c, "Rename Access Conflict");
o1 = TEE_HANDLE_NULL;
o2 = TEE_HANDLE_NULL;
f = 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_DATA_FLAG_OVERWRITE;
ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_00, sizeof(file_00), f, 0, data,
sizeof(data), &o1, storage_id));
ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01), f, 0, data,
sizeof(data) / 2, &o2, storage_id));
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_ACCESS_CONFLICT,
fs_rename(&sess, o2, file_00, sizeof(file_00)));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, o1));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, o2));
Do_ADBG_EndSubCase(c, "Rename Access Conflict");
Do_ADBG_BeginSubCase(c, "AllocPersistentObjectEnumerator + "
"ResetPersistentObjectEnumerator");
e = TEE_HANDLE_NULL;
ADBG_EXPECT_TEEC_SUCCESS(c, fs_alloc_enum(&sess, &e));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_reset_enum(&sess, e));
Do_ADBG_EndSubCase(c, "AllocPersistentObjectEnumerator + "
"ResetPersistentObjectEnumerator");
Do_ADBG_BeginSubCase(c, "StartPersistentObjectEnumerator ItemNotFound");
e = TEE_HANDLE_NULL;
ADBG_EXPECT_TEEC_SUCCESS(c, fs_alloc_enum(&sess, &e));
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_ITEM_NOT_FOUND,
fs_next_enum(&sess, e, NULL, 0, out, sizeof(out)));
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_ITEM_NOT_FOUND,
fs_start_enum(&sess, e, storage_id));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_free_enum(&sess, e));
Do_ADBG_EndSubCase(c, "StartPersistentObjectEnumerator ItemNotFound");
Do_ADBG_BeginSubCase(c, "RenamePersistent ReadWrite");
o1 = TEE_HANDLE_NULL;
f = 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_DATA_FLAG_OVERWRITE;
ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_00, sizeof(file_00), f, 0, data,
sizeof(data), &o1, storage_id));
ADBG_EXPECT_TEEC_SUCCESS(c,
fs_rename(&sess, o1, file_01, sizeof(file_01)));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, o1));
Do_ADBG_EndSubCase(c, "RenamePersistent ReadWrite");
Do_ADBG_BeginSubCase(c, "Close Free Reset Null");
ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, TEE_HANDLE_NULL));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_free_obj(&sess, TEE_HANDLE_NULL));
ADBG_EXPECT_TEEC_SUCCESS(c, fs_reset_obj(&sess, TEE_HANDLE_NULL));
Do_ADBG_EndSubCase(c, "Close Free Reset Null");
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6010)
#ifdef WITH_GP_TESTS
static void xtest_tee_test_6011(ADBG_Case_t *c)
{
TEEC_Session sess;
uint32_t orig;
/*
* Test data from
* Invoke_InitObjectAndAttributes_TEE_TYPE_AES_success_attribute_
* TEE_ATTR_SECRET_VALUE_correct_size (9d-9a-91)
*/
static const uint8_t attr_meta[] = {
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
static const uint8_t attr_data[] = {
0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,
0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,
0xdf,0xf4,
};
if (!ADBG_EXPECT_TEEC_SUCCESS(
c, xtest_teec_open_session(
&sess, &gp_tta_ds_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, ds_init_object_and_attributes(&sess,
0xa0000010, 0x100, attr_meta, sizeof(attr_meta), attr_data,
sizeof(attr_data), 0)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
#endif /*WITH_GP_TESTS*/
static void xtest_tee_test_6012_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t orig;
uint32_t obj;
/*
* create the object a first time (forced through with overwrite attribute)
*/
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create_overwrite(&sess, file_04, sizeof(file_04), storage_id)))
goto bail1;
TEEC_CloseSession(&sess);
/*
* re-create the object two times with overwrite attribute
*/
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create_overwrite(&sess, file_04, sizeof(file_04),
storage_id)))
goto bail1;
/* re-create it with an object */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_04, sizeof(file_04),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE, 0, NULL, 0, &obj,
storage_id)))
goto bail2;
TEEC_CloseSession(&sess);
/*
* re-create it again without overwrite flag: should fail and
* existing object should not be altered.
*/
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ACCESS_CONFLICT,
fs_create(&sess, file_04, sizeof(file_04),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, NULL, 0, &obj,
storage_id)))
goto bail2;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_04, sizeof(file_04),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj,
storage_id)))
goto bail1;
bail2:
/* remove the object so that xtest 600x can be replayed */
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj));
bail1:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6012)
static void xtest_tee_test_6013_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t orig;
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
op.params[0].value.a = storage_id;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
ADBG_EXPECT_TEEC_SUCCESS(c,
TEEC_InvokeCommand(&sess, TA_STORAGE_CMD_KEY_IN_PERSISTENT,
&op, &orig));
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6013)
static void xtest_tee_test_6014_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
uint32_t orig;
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
op.params[0].value.a = storage_id;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
ADBG_EXPECT_TEEC_SUCCESS(c,
TEEC_InvokeCommand(&sess, TA_STORAGE_CMD_LOOP, &op, &orig));
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6014)
static void xtest_tee_test_6015_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
TEEC_Session sess2;
uint32_t orig;
uint32_t obj;
uint32_t obj2;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess2, &storage2_ta_uuid, NULL,
&orig)))
goto exit2;
/* TA #1 creates a persistent object */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit;
/* TA #2 tries to open the object created by TA #1 */
if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_ITEM_NOT_FOUND,
fs_open(&sess2, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_READ, &obj2, storage_id)))
goto clean;
clean:
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj));
exit:
TEEC_CloseSession(&sess2);
exit2:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6015)
struct test_6016_thread_arg {
ADBG_Case_t *case_t;
uint32_t storage_id;
char file_name[8];
TEEC_Session session;
};
static void *test_6016_thread(void *arg)
{
struct test_6016_thread_arg *a = arg;
TEEC_Session sess = a->session;
uint32_t obj;
uint8_t out[10] = { 0 };
uint32_t count;
/* create */
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t,
fs_create(&sess, a->file_name, sizeof(a->file_name),
TEE_DATA_FLAG_ACCESS_WRITE, 0, data_01,
sizeof(data_01), &obj, a->storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t, fs_close(&sess, obj)))
goto exit;
/* write new data */
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t,
fs_open(&sess, a->file_name, sizeof(a->file_name),
TEE_DATA_FLAG_ACCESS_WRITE, &obj, a->storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t,
fs_write(&sess, obj, data_00, sizeof(data_00))))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t, fs_close(&sess, obj)))
goto exit;
/* verify */
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t,
fs_open(&sess, a->file_name, sizeof(a->file_name),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, a->storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t,
fs_read(&sess, obj, out, 10, &count)))
goto exit;
(void)ADBG_EXPECT_BUFFER(a->case_t, data_00, 10, out, count);
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(a->case_t, fs_unlink(&sess, obj)))
goto exit;
exit:
return NULL;
}
#define NUM_THREADS 4
static void xtest_tee_test_6016_loop(ADBG_Case_t *c, uint32_t storage_id)
{
size_t num_threads = NUM_THREADS;
struct test_6016_thread_arg arg[num_threads];
pthread_t thr[num_threads];
uint32_t orig;
size_t i;
size_t n = 0;
size_t m;
memset(arg, 0, sizeof(arg));
for (m = 0; m < num_threads; m++)
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&arg[m].session,
&storage_ta_uuid, NULL, &orig)))
goto out;
for (n = 0; n < num_threads; n++) {
arg[n].case_t = c;
arg[n].storage_id = storage_id;
snprintf(arg[n].file_name, sizeof(arg[n].file_name),
"file_%zu", n);
if (!ADBG_EXPECT(c, 0, pthread_create(thr + n, NULL,
test_6016_thread, arg + n)))
goto out;
}
out:
for (i = 0; i < n; i++)
ADBG_EXPECT(c, 0, pthread_join(thr[i], NULL));
for (i = 0; i < m; i++)
TEEC_CloseSession(&arg[i].session);
}
/* concurency */
static void xtest_tee_test_6016_single(ADBG_Case_t *c, uint32_t storage_id)
{
int i;
int loops = 8;
Do_ADBG_Log(" threads: %d, loops: %d", NUM_THREADS, loops);
for (i = 0; i < loops; i++)
xtest_tee_test_6016_loop(c, storage_id);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6016)
static void xtest_tee_test_6017_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
TEE_ObjectInfo obj_info1;
TEE_ObjectInfo obj_info2;
uint32_t obj;
uint32_t orig;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE, 0, NULL,
0, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_write(&sess, obj, data_00, sizeof(data_00))))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_get_obj_info(&sess, obj, &obj_info1,
sizeof(TEE_ObjectInfo))))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_get_obj_info(&sess, obj, &obj_info2,
sizeof(TEE_ObjectInfo))))
goto exit;
if (!ADBG_EXPECT_COMPARE_UNSIGNED(c,
obj_info1.dataSize, ==, obj_info2.dataSize))
goto exit;
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6017)
static void xtest_tee_test_6018_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
TEE_ObjectInfo obj_info1;
TEE_ObjectInfo obj_info2;
uint32_t obj;
uint32_t orig;
uint8_t block[32 * 1024];
size_t num_blocks;
size_t block_size;
size_t n;
if (storage_is(storage_id, TEE_STORAGE_PRIVATE_RPMB)) {
/* RPMB FS is a bit resource constrained */
num_blocks = 10;
block_size = 1024;
} else {
num_blocks = 20;
block_size = sizeof(block);
}
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE, 0, NULL,
0, &obj, storage_id)))
goto exit;
for (n = 0; n < num_blocks; n++) {
memset(block, n, block_size);
Do_ADBG_Log("writing %zu", n);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_write(&sess, obj, block, block_size)))
goto exit;
}
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_get_obj_info(&sess, obj, &obj_info1,
sizeof(TEE_ObjectInfo))))
goto exit;
if (!ADBG_EXPECT_COMPARE_UNSIGNED(c,
obj_info1.dataSize, ==, block_size * num_blocks))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_get_obj_info(&sess, obj, &obj_info2,
sizeof(TEE_ObjectInfo))))
goto exit;
if (!ADBG_EXPECT_COMPARE_UNSIGNED(c,
obj_info1.dataSize, ==, obj_info2.dataSize))
goto exit;
for (n = 0; n < num_blocks; n++) {
uint8_t br[block_size];
uint32_t count;
memset(block, n, block_size);
Do_ADBG_Log("reading %zu", n);
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_read(&sess, obj, br, sizeof(br), &count)))
goto exit;
if (!ADBG_EXPECT_BUFFER(c, block, block_size, br, count))
goto exit;
}
/* clean */
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj)))
goto exit;
exit:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6018)
static void xtest_tee_test_6019_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Session sess;
TEEC_Session sess2;
uint32_t orig;
uint32_t obj;
uint32_t obj2;
uint8_t out[10] = { 0 };
uint32_t count;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
return;
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
xtest_teec_open_session(&sess2, &storage2_ta_uuid, NULL,
&orig)))
goto exit3;
/* TA #1 creates a persistent object */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE, 0, data_00,
sizeof(data_00), &obj, storage_id)))
goto exit2;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit1;
/* TA #2 creates a persistent object */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_create(&sess2, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE, 0, data_01,
sizeof(data_01), &obj2, storage_id)))
goto exit1;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess2, obj2)))
goto exit;
/* TA #1 open and read */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess, obj, out, 10, &count)))
goto exit;
/* verify */
(void)ADBG_EXPECT_BUFFER(c, data_00, 10, out, count);
/* TA #2 open and read */
if (!ADBG_EXPECT_TEEC_SUCCESS(c,
fs_open(&sess2, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_READ |
TEE_DATA_FLAG_ACCESS_WRITE_META, &obj2, storage_id)))
goto exit;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_read(&sess2, obj2, out, 10, &count)))
goto exit;
/* verify */
(void)ADBG_EXPECT_BUFFER(c, data_01, 10, out, count);
exit:
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess2, obj2));
exit1:
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj));
exit2:
TEEC_CloseSession(&sess2);
exit3:
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6019)
/*
* According to the GP spec V1.1, the object_id in create/open/rename
* functions is not allowed to reside in the shared memory.
*
* The function below replicates fs_open/fs_create/fs_rename but using
* specific commands to ask the TA to use the client object ID buffer
* from the shared memory when accessing the object through target APIs.
* The TA is not expected to use such references and gets killed by the TEE.
*/
static TEEC_Result fs_access_with_bad_object_id_ref(TEEC_Session *sess,
uint32_t command,
void *id, uint32_t id_size,
uint32_t flags,
uint32_t attr,
void *data, uint32_t data_size,
uint32_t *obj,
uint32_t storage_id)
{
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
TEEC_Result res;
uint32_t org;
switch (command) {
case TA_STORAGE_CMD_OPEN_ID_IN_SHM:
op.params[0].tmpref.buffer = id;
op.params[0].tmpref.size = id_size;
op.params[1].value.a = flags;
op.params[1].value.b = 0;
op.params[2].value.a = storage_id;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_VALUE_INOUT,
TEEC_VALUE_INPUT,
TEEC_NONE);
break;
case TA_STORAGE_CMD_CREATE_ID_IN_SHM:
op.params[0].tmpref.buffer = id;
op.params[0].tmpref.size = id_size;
op.params[1].value.a = flags;
op.params[1].value.b = 0;
op.params[2].value.a = attr;
op.params[2].value.b = storage_id;
op.params[3].tmpref.buffer = data;
op.params[3].tmpref.size = data_size;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_VALUE_INOUT,
TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT);
break;
case TA_STORAGE_CMD_CREATEOVER_ID_IN_SHM:
op.params[0].tmpref.buffer = id;
op.params[0].tmpref.size = id_size;
op.params[1].value.a = storage_id;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
TEEC_VALUE_INPUT,
TEEC_NONE, TEEC_NONE);
break;
case TA_STORAGE_CMD_RENAME_ID_IN_SHM:
op.params[0].value.a = *obj;
op.params[1].tmpref.buffer = id;
op.params[1].tmpref.size = id_size;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_NONE, TEEC_NONE);
break;
default:
return TEE_ERROR_GENERIC;
}
res = TEEC_InvokeCommand(sess, command, &op, &org);
switch (command) {
case TA_STORAGE_CMD_OPEN_ID_IN_SHM:
case TA_STORAGE_CMD_CREATE_ID_IN_SHM:
if (res == TEEC_SUCCESS)
*obj = op.params[1].value.b;
break;
default:
break;
}
return res;
}
static void xtest_tee_test_6020_single(ADBG_Case_t *c, uint32_t storage_id)
{
TEEC_Result res;
TEEC_Session sess;
uint32_t orig;
uint32_t obj;
/*
* Invalid open request from the TA (object ID reference in SHM)
*/
res = xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig);
if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
return;
res = fs_create(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE,
0,
data_00, sizeof(data_00),
&obj,
storage_id);
if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
goto exit1;
if (!ADBG_EXPECT_TEEC_SUCCESS(c, fs_close(&sess, obj)))
goto exit1;
res = fs_access_with_bad_object_id_ref(&sess,
TA_STORAGE_CMD_OPEN_ID_IN_SHM,
file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE,
0,
NULL, 0,
&obj,
storage_id);
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_TARGET_DEAD, res);
/*
* Invalid create-overwrite request from the TA (object ID reference in SHM)
*/
TEEC_CloseSession(&sess);
res = xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig);
if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
return;
res = fs_access_with_bad_object_id_ref(&sess,
TA_STORAGE_CMD_CREATEOVER_ID_IN_SHM,
file_01, sizeof(file_01),
0,
0,
NULL, 0,
NULL,
storage_id);
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_TARGET_DEAD, res);
/*
* Invalid rename request from the TA (object ID reference in SHM)
*/
TEEC_CloseSession(&sess);
res = xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig);
if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
return;
res = fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE,
&obj,
storage_id);
if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
goto exit1;
res = fs_access_with_bad_object_id_ref(&sess,
TA_STORAGE_CMD_RENAME_ID_IN_SHM,
file_01, sizeof(file_01) - 1,
0,
0,
NULL, 0,
&obj,
0);
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_TARGET_DEAD, res);
/*
* Invalid creation request from the TA (object ID reference in SHM)
*/
TEEC_CloseSession(&sess);
res = xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig);
if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
return;
res = fs_open(&sess, file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE,
&obj,
storage_id);
if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
goto exit1;
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj));
res = fs_access_with_bad_object_id_ref(&sess,
TA_STORAGE_CMD_CREATE_ID_IN_SHM,
file_01, sizeof(file_01),
TEE_DATA_FLAG_ACCESS_WRITE |
TEE_DATA_FLAG_ACCESS_WRITE_META |
TEE_DATA_FLAG_OVERWRITE,
0,
data_00, sizeof(data_00),
&obj,
storage_id);
ADBG_EXPECT_TEEC_RESULT(c, TEE_ERROR_TARGET_DEAD, res);
return;
exit1:
ADBG_EXPECT_TEEC_SUCCESS(c, fs_unlink(&sess, obj));
TEEC_CloseSession(&sess);
}
DEFINE_TEST_MULTIPLE_STORAGE_IDS(xtest_tee_test_6020)
ADBG_CASE_DEFINE(regression, 6001, xtest_tee_test_6001,
"Test TEE_CreatePersistentObject");
ADBG_CASE_DEFINE(regression, 6002, xtest_tee_test_6002,
"Test TEE_OpenPersistentObject");
ADBG_CASE_DEFINE(regression, 6003, xtest_tee_test_6003,
"Test TEE_ReadObjectData");
ADBG_CASE_DEFINE(regression, 6004, xtest_tee_test_6004,
"Test TEE_WriteObjectData");
ADBG_CASE_DEFINE(regression, 6005, xtest_tee_test_6005,
"Test TEE_SeekObjectData");
ADBG_CASE_DEFINE(regression, 6006, xtest_tee_test_6006,
"Test TEE_CloseAndDeletePersistentObject");
ADBG_CASE_DEFINE(regression, 6007, xtest_tee_test_6007,
"Test TEE_TruncateObjectData");
ADBG_CASE_DEFINE(regression, 6008, xtest_tee_test_6008,
"Test TEE_RenamePersistentObject");
ADBG_CASE_DEFINE(regression, 6009, xtest_tee_test_6009,
"Test TEE Internal API Persistent Object Enumeration Functions");
ADBG_CASE_DEFINE(regression, 6010, xtest_tee_test_6010, "Test Storage");
#ifdef WITH_GP_TESTS
ADBG_CASE_DEFINE(regression, 6011, xtest_tee_test_6011,
"Test TEE GP TTA DS init objects");
#endif
ADBG_CASE_DEFINE(regression, 6012, xtest_tee_test_6012,
"Test TEE GP TTA DS init objects");
ADBG_CASE_DEFINE(regression, 6013, xtest_tee_test_6013,
"Key usage in Persistent objects");
ADBG_CASE_DEFINE(regression, 6014, xtest_tee_test_6014,
"Loop on Persistent objects");
ADBG_CASE_DEFINE(regression, 6015, xtest_tee_test_6015, "Storage isolation");
ADBG_CASE_DEFINE(regression, 6016, xtest_tee_test_6016, "Storage concurency");
ADBG_CASE_DEFINE(regression, 6017, xtest_tee_test_6017,
"Test Persistent objects info");
ADBG_CASE_DEFINE(regression, 6018, xtest_tee_test_6018, "Large object");
ADBG_CASE_DEFINE(regression, 6019, xtest_tee_test_6019, "Storage independence");
ADBG_CASE_DEFINE(regression, 6020, xtest_tee_test_6020,
"Object IDs in SHM (negative)");