From d079c1a5ed50ce9f1e3b37be5ce4e13edec90bd0 Mon Sep 17 00:00:00 2001 From: Hisping Lin Date: Tue, 9 Jun 2020 10:30:20 +0800 Subject: [PATCH] lib: optee_client v1: support RKFS version 2 1.use get_rkss_version function to get rkss version, if security partition have data with rkss version 1, then we choice rkss version 1, if security partition is empty, then we choice rkss version 2 2.rkss version 2 support dual backup mechanism, security partition total use 1M 3.rkss version 2 R&W 256k data one time Change-Id: I4103b6600666dffccf473ec4ed8854776a46da31 Signed-off-by: Hisping Lin --- include/optee_include/OpteeClientRkFs.h | 91 +- lib/optee_clientApi/Makefile | 4 +- lib/optee_clientApi/OpteeClientRPC.c | 7 +- lib/optee_clientApi/OpteeClientRkFs_common.c | 94 ++ ...OpteeClientRkFs.c => OpteeClientRkFs_v1.c} | 506 ++---- lib/optee_clientApi/OpteeClientRkFs_v2.c | 1451 +++++++++++++++++ 6 files changed, 1798 insertions(+), 355 deletions(-) create mode 100644 lib/optee_clientApi/OpteeClientRkFs_common.c rename lib/optee_clientApi/{OpteeClientRkFs.c => OpteeClientRkFs_v1.c} (78%) create mode 100644 lib/optee_clientApi/OpteeClientRkFs_v2.c diff --git a/include/optee_include/OpteeClientRkFs.h b/include/optee_include/OpteeClientRkFs.h index d70c118c75..5d56e0ac42 100644 --- a/include/optee_include/OpteeClientRkFs.h +++ b/include/optee_include/OpteeClientRkFs.h @@ -29,12 +29,97 @@ #include -int tee_supp_rk_fs_init(void); +/* + * Operations and defines shared with TEE. + */ +#define TEE_FS_OPEN 1 +#define TEE_FS_CLOSE 2 +#define TEE_FS_READ 3 +#define TEE_FS_WRITE 4 +#define TEE_FS_SEEK 5 +#define TEE_FS_UNLINK 6 +#define TEE_FS_RENAME 7 +#define TEE_FS_TRUNC 8 +#define TEE_FS_MKDIR 9 +#define TEE_FS_OPENDIR 10 +#define TEE_FS_CLOSEDIR 11 +#define TEE_FS_READDIR 12 +#define TEE_FS_RMDIR 13 +#define TEE_FS_ACCESS 14 +#define TEE_FS_LINK 15 -int tee_supp_rk_fs_process(void *cmd, uint32_t cmd_size); +/* + * Open flags, defines shared with TEE. + */ +#define TEE_FS_O_RDONLY 0x1 +#define TEE_FS_O_WRONLY 0x2 +#define TEE_FS_O_RDWR 0x4 +#define TEE_FS_O_CREAT 0x8 +#define TEE_FS_O_EXCL 0x10 +#define TEE_FS_O_APPEND 0x20 + +/* + * Seek flags, defines shared with TEE. + */ +#define TEE_FS_SEEK_SET 0x1 +#define TEE_FS_SEEK_END 0x2 +#define TEE_FS_SEEK_CUR 0x4 + +/* + * Mkdir flags, defines shared with TEE. + */ +#define TEE_FS_S_IWUSR 0x1 +#define TEE_FS_S_IRUSR 0x2 + +/* + * Access flags, X_OK not supported, defines shared with TEE. + */ +#define TEE_FS_R_OK 0x1 +#define TEE_FS_W_OK 0x2 +#define TEE_FS_F_OK 0x4 + +#define RK_FS_R 0x1 +#define RK_FS_W 0x2 +#define RK_FS_D 0x8 + +/* Function Defines */ +#define UNREFERENCED_PARAMETER(P) (P = P) +#define CHECKFLAG(flags, flag) (flags & flag) +#define ADDFLAG(flags, flag) (flags | flag) + +#define RKSS_VERSION_V1 1 +#define RKSS_VERSION_V2 2 +#define RKSS_VERSION_ERR 100 + +/* + * Structure for file related RPC calls + * + * @op The operation like open, close, read, write etc + * @flags Flags to the operation shared with secure world + * @arg Argument to operation + * @fd NW file descriptor + * @len Length of buffer at the end of this struct + * @res Result of the operation + */ +struct tee_fs_rpc { + int op; + int flags; + int arg; + int fd; + uint32_t len; + int res; +}; + +int tee_supp_rk_fs_init_v1(void); + +int tee_supp_rk_fs_process_v1(void *cmd, size_t cmd_size); + +int tee_supp_rk_fs_init_v2(void); + +int tee_supp_rk_fs_process_v2(void *cmd, size_t cmd_size); int OpteeClientRkFsInit(void); -int check_security_exist(int print_flag); +int OpteeClientRkFsProcess(void *cmd, size_t cmd_size); #endif diff --git a/lib/optee_clientApi/Makefile b/lib/optee_clientApi/Makefile index e039115f98..2ecb905e4e 100644 --- a/lib/optee_clientApi/Makefile +++ b/lib/optee_clientApi/Makefile @@ -11,7 +11,9 @@ obj-y += OpteeClientRPC.o obj-y += tee_smc-arm64.o ifdef CONFIG_OPTEE_V1 -obj-y += OpteeClientRkFs.o +obj-y += OpteeClientRkFs_common.o +obj-y += OpteeClientRkFs_v1.o +obj-y += OpteeClientRkFs_v2.o endif ifdef CONFIG_OPTEE_V2 diff --git a/lib/optee_clientApi/OpteeClientRPC.c b/lib/optee_clientApi/OpteeClientRPC.c index 948c88f501..3938f63a5c 100644 --- a/lib/optee_clientApi/OpteeClientRPC.c +++ b/lib/optee_clientApi/OpteeClientRPC.c @@ -518,14 +518,9 @@ TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg) TEEC_Result TeecResult = TEEC_SUCCESS; t_teesmc32_param *TeeSmc32Param; - if (check_security_exist(0) < 0) { - printf("TEEC: security partition not exist! unable to use RK FS!\n"); - return TEEC_ERROR_GENERIC; - } - TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); #ifdef CONFIG_OPTEE_V1 - TeecResult = tee_supp_rk_fs_process((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr, + TeecResult = OpteeClientRkFsProcess((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr, TeeSmc32Param[0].u.memref.size); #endif #ifdef CONFIG_OPTEE_V2 diff --git a/lib/optee_clientApi/OpteeClientRkFs_common.c b/lib/optee_clientApi/OpteeClientRkFs_common.c new file mode 100644 index 0000000000..f3d95f8fba --- /dev/null +++ b/lib/optee_clientApi/OpteeClientRkFs_common.c @@ -0,0 +1,94 @@ +/* + * Copyright 2020, Rockchip Electronics Co., Ltd + * hisping lin, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +static int rkss_version; +static int get_rkss_version(void) +{ + struct blk_desc *dev_desc = NULL; + disk_partition_t part_info; + uint8_t *read_buff; + unsigned long ret = 0; + uint32_t *version; + uint32_t *checkstr; + + if (rkss_version != 0) + return rkss_version; + + dev_desc = rockchip_get_bootdev(); + if (!dev_desc) { + printf("TEEC: %s: Could not find device\n", __func__); + return -1; + } + + if (part_get_info_by_name(dev_desc, + "security", &part_info) < 0) { + printf("TEEC: Waring: Could not find security partition\n"); + rkss_version = RKSS_VERSION_ERR; + return rkss_version; + } + + read_buff = (uint8_t *)malloc(512); + if (!read_buff) { + printf("TEEC: Malloc failed!\n"); + return -1; + } + + ret = blk_dread(dev_desc, part_info.start, 1, read_buff); + if (ret != 1) { + printf("TEEC: blk_dread fail\n"); + free(read_buff); + return -1; + } + + version = (uint32_t *)(read_buff + 512 - 8); + checkstr = (uint32_t *)(read_buff + 512 - 4); + + if (*version == 1 && *checkstr == 0x12345678) + rkss_version = RKSS_VERSION_V1; + else + rkss_version = RKSS_VERSION_V2; + + free(read_buff); + return rkss_version; +} + +int OpteeClientRkFsInit(void) +{ + int version; + + version = get_rkss_version(); + debug("TEEC: OpteeClientRkFsInit version=%d\n", version); + if (version == RKSS_VERSION_V1) + return tee_supp_rk_fs_init_v1(); + else if (version == RKSS_VERSION_V2) + return tee_supp_rk_fs_init_v2(); + else if (version == RKSS_VERSION_ERR) + return 0; + else + return -1; +} + +int OpteeClientRkFsProcess(void *cmd, size_t cmd_size) +{ + int version; + + version = get_rkss_version(); + debug("TEEC: OpteeClientRkFsProcess version=%d\n", version); + if (version == RKSS_VERSION_V1) + return tee_supp_rk_fs_process_v1(cmd, cmd_size); + else if (version == RKSS_VERSION_V2) + return tee_supp_rk_fs_process_v2(cmd, cmd_size); + else + return -1; +} diff --git a/lib/optee_clientApi/OpteeClientRkFs.c b/lib/optee_clientApi/OpteeClientRkFs_v1.c similarity index 78% rename from lib/optee_clientApi/OpteeClientRkFs.c rename to lib/optee_clientApi/OpteeClientRkFs_v1.c index d38bcfc2df..3f21f00cfe 100644 --- a/lib/optee_clientApi/OpteeClientRkFs.c +++ b/lib/optee_clientApi/OpteeClientRkFs_v1.c @@ -1,86 +1,20 @@ /* - * Copyright (c) 2016, Fuzhou Rockchip Electronics Co.,Ltd. - * All rights reserved. + * Copyright 2020, Rockchip Electronics Co., Ltd + * hisping lin, * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * Created by jeffry.zhang@rock-chips.com + * SPDX-License-Identifier: GPL-2.0+ */ + #include #include #include +#include +#include +#include -//#define DEBUG_RKFSS +//#define DEBUG_RKSS //#define DEBUG_CLEAN_RKSS -/* - * Operations and defines shared with TEE. - */ -#define TEE_FS_OPEN 1 -#define TEE_FS_CLOSE 2 -#define TEE_FS_READ 3 -#define TEE_FS_WRITE 4 -#define TEE_FS_SEEK 5 -#define TEE_FS_UNLINK 6 -#define TEE_FS_RENAME 7 -#define TEE_FS_TRUNC 8 -#define TEE_FS_MKDIR 9 -#define TEE_FS_OPENDIR 10 -#define TEE_FS_CLOSEDIR 11 -#define TEE_FS_READDIR 12 -#define TEE_FS_RMDIR 13 -#define TEE_FS_ACCESS 14 -#define TEE_FS_LINK 15 - -/* - * Open flags, defines shared with TEE. - */ -#define TEE_FS_O_RDONLY 0x1 -#define TEE_FS_O_WRONLY 0x2 -#define TEE_FS_O_RDWR 0x4 -#define TEE_FS_O_CREAT 0x8 -#define TEE_FS_O_EXCL 0x10 -#define TEE_FS_O_APPEND 0x20 - -/* - * Seek flags, defines shared with TEE. - */ -#define TEE_FS_SEEK_SET 0x1 -#define TEE_FS_SEEK_END 0x2 -#define TEE_FS_SEEK_CUR 0x4 - -/* - * Mkdir flags, defines shared with TEE. - */ -#define TEE_FS_S_IWUSR 0x1 -#define TEE_FS_S_IRUSR 0x2 - -/* - * Access flags, X_OK not supported, defines shared with TEE. - */ -#define TEE_FS_R_OK 0x1 -#define TEE_FS_W_OK 0x2 -#define TEE_FS_F_OK 0x4 - /* * RK Secure Storage Ctrl * Storage Size : 512 kb @@ -106,11 +40,11 @@ * */ #define RKSS_DATA_SECTION_COUNT 1024 -#define RKSS_DATA_LEN 512 +#define RKSS_DATA_SECTION_LEN 512 #define RKSS_PARTITION_TABLE_COUNT 128 // total size 512 * 128 -#define RKSS_EACH_FILEFOLDER_COUNT 4 // 504 / 126 = 4 -#define RKSS_NAME_MAX_LENGTH 117 // 116 char + "\0" -#define RKSS_USEDFLAGS_INDEX RKSS_PARTITION_TABLE_COUNT +#define RKSS_EACH_SECTION_FILECOUNT 4 // 504 / 126 = 4 +#define RKSS_MAX_NAME_LENGTH 117 // 116 char + "\0" +#define RKSS_USED_FLAGS_INDEX RKSS_PARTITION_TABLE_COUNT #define RKSS_BACKUP_INDEX RKSS_DATA_SECTION_COUNT #define RKSS_BACKUP_COUNT 256 @@ -132,62 +66,38 @@ struct rkss_backup_info { unsigned int backup_usedflag; }; -typedef struct rkss_file_info -{ +typedef struct rkss_file_info { uint8_t used; - char name[RKSS_NAME_MAX_LENGTH]; + char name[RKSS_MAX_NAME_LENGTH]; uint16_t index; // from 129 to 1024 uint16_t size; // size of data uint16_t father; uint8_t id; // file folder count index -#define RK_FS_R 0x1 -#define RK_FS_W 0x2 -#define RK_FS_D 0x8 uint8_t flags; -}rkss_file_info; // 126 byte for each +} rkss_file_info; // 126 byte for each -#define RKSS_VERSION (uint32_t)0x1 #define RKSS_CHECK_STR (uint32_t)0x12345678 #define RKSS_CHECK_PT (uint8_t)0xFC -typedef struct rkss_file_verification -{ +typedef struct rkss_file_verification { uint32_t version; uint32_t checkstr; -}rkss_file_verification; // 8 byte +} rkss_file_verification; // 8 byte -typedef struct rk_secure_storage -{ +typedef struct rk_secure_storage { unsigned long index; - unsigned char data[RKSS_DATA_LEN]; -}rk_secure_storage; - -/* Path to all secure storage dev. */ -#define RKSS_DEV "/dev/block/rknand_security" - -/* Function Defines */ -#define UNREFERENCED_PARAMETER(P) (P=P) -#define CHECKFLAG(flags, flag) (flags & flag) -#define ADDFLAG(flags, flag) (flags | flag) + unsigned char data[RKSS_DATA_SECTION_LEN]; +} rk_secure_storage; /* RK Secure Storage Calls */ -static int file_seek = 0; -static char dir_cache[RKSS_NAME_MAX_LENGTH][12]; -static int dir_num = 0; -static int dir_seek = 0; +static int file_seek; +static char dir_cache[RKSS_MAX_NAME_LENGTH][12]; +static int dir_num; +static int dir_seek; -extern struct blk_desc *rockchip_get_bootdev(void); -extern int part_get_info_by_name(struct blk_desc *dev_desc, const char *name, - disk_partition_t *info); -extern unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start, - lbaint_t blkcnt, void *buffer); - -extern unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start, - lbaint_t blkcnt, const void *buffer); - -static struct blk_desc *dev_desc = NULL; +static struct blk_desc *dev_desc; static disk_partition_t part_info; -int check_security_exist(int print_flag) +static int check_security_exist(int print_flag) { if (!dev_desc) { dev_desc = rockchip_get_bootdev(); @@ -226,7 +136,7 @@ int check_security_exist(int print_flag) */ static int rkss_begin_commit(void) { - unsigned char data[RKSS_DATA_LEN]; + unsigned char data[RKSS_DATA_SECTION_LEN]; struct rkss_backup_verification p; unsigned long ret; @@ -251,7 +161,7 @@ static int rkss_begin_commit(void) static int rkss_finish_commit(void) { - unsigned char data[RKSS_DATA_LEN]; + unsigned char data[RKSS_DATA_SECTION_LEN]; unsigned long ret; if (check_security_exist(1) < 0) @@ -270,7 +180,7 @@ static int rkss_finish_commit(void) static int rkss_backup_sections(unsigned long index, unsigned int num) { - unsigned char data[RKSS_DATA_LEN]; + unsigned char data[RKSS_DATA_SECTION_LEN]; unsigned char *backup_data = NULL; struct rkss_backup_verification p; struct rkss_backup_info info_last, info_current; @@ -312,7 +222,7 @@ static int rkss_backup_sections(unsigned long index, unsigned int num) debug("TEEC: %s index=0x%lx num=0x%x backup_data_index=0x%x\n", __func__, index, num, info_current.backup_data_index); - backup_data = malloc(num * RKSS_DATA_LEN); + backup_data = malloc(num * RKSS_DATA_SECTION_LEN); if (!backup_data) { printf("TEEC: malloc backup_data fail\n"); goto error; @@ -356,7 +266,7 @@ error: static int rkss_resume(void) { - unsigned char data[RKSS_DATA_LEN]; + unsigned char data[RKSS_DATA_SECTION_LEN]; unsigned char *backup_data = NULL; struct rkss_backup_verification p; struct rkss_backup_info info_current; @@ -400,7 +310,7 @@ static int rkss_resume(void) goto error; } backup_data = malloc(info_current.backup_num * - RKSS_DATA_LEN); + RKSS_DATA_SECTION_LEN); if (!backup_data) { printf("TEEC: malloc backup_data fail\n"); goto error; @@ -503,14 +413,13 @@ static int rkss_read_patition_tables(unsigned char *data) return 0; } -#ifdef DEBUG_RKFSS -static void rkss_dump(void* data, unsigned int len) +#ifdef DEBUG_RKSS +static void rkss_dump(void *data, unsigned int len) { char *p = (char *)data; unsigned int i = 0; printf("-------------- DUMP %d --------------\n", len); - for (i = 0; i < len; i++) - { + for (i = 0; i < len; i++) { printf("%02x ", *(p + i)); } printf("\n"); @@ -523,7 +432,7 @@ static void rkss_dump_ptable(void) int i = 0, ret; unsigned char *table_data; - table_data = malloc(RKSS_DATA_LEN * RKSS_PARTITION_TABLE_COUNT); + table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); if (table_data == NULL) { printf("TEEC: malloc table_data fail\n"); return; @@ -535,21 +444,19 @@ static void rkss_dump_ptable(void) return; } - for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) - { + for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { struct rk_secure_storage rkss = {0}; rkss.index = i; - memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_LEN, RKSS_DATA_LEN); + memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); int n ; - for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) - { + for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { void *pdata = rkss.data; struct rkss_file_info *p = (struct rkss_file_info *)pdata; p += n; printf("[%02d][%c] %s , inx:%d, size:%d", - i*RKSS_EACH_FILEFOLDER_COUNT+n, p->used == 0 ? 'F':'T' ,p->name, + i*RKSS_EACH_SECTION_FILECOUNT+n, p->used == 0 ? 'F':'T', p->name, p->index, p->size); } } @@ -560,14 +467,13 @@ static void rkss_dump_ptable(void) static void rkss_dump_usedflags(void) { struct rk_secure_storage rkss = {0}; - rkss.index = RKSS_USEDFLAGS_INDEX; + rkss.index = RKSS_USED_FLAGS_INDEX; int ret = rkss_read_section(&rkss); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: rkss_read_section fail ! ret: %d.\n", ret); return; } - rkss_dump(rkss.data, RKSS_DATA_LEN); + rkss_dump(rkss.data, RKSS_DATA_SECTION_LEN); } #endif @@ -578,16 +484,16 @@ static int rkss_verify_ptable(unsigned char *table_data) int ret, i, write_table_flag = 0; for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { - cp = table_data + (i * RKSS_DATA_LEN); - vp = cp + RKSS_DATA_LEN - sizeof(struct rkss_file_verification); + cp = table_data + (i * RKSS_DATA_SECTION_LEN); + vp = cp + RKSS_DATA_SECTION_LEN - sizeof(struct rkss_file_verification); verify = (struct rkss_file_verification *)(void *)vp; - if (verify->version != RKSS_VERSION + if (verify->version != RKSS_VERSION_V1 || verify->checkstr != RKSS_CHECK_STR) { printf("TEEC: verify [%d] fail, cleanning ....", i); - memset(cp, 0, RKSS_DATA_LEN); + memset(cp, 0, RKSS_DATA_SECTION_LEN); verify->checkstr = RKSS_CHECK_STR; - verify->version = RKSS_VERSION; + verify->version = RKSS_VERSION_V1; write_table_flag = 1; } } @@ -613,7 +519,7 @@ static int rkss_verify_usedflags(struct rk_secure_storage *rkss) flag = i & 0x1 ? duel & 0x0F : (duel & 0xF0) >> 4; if (flag != 0x1) { debug("TEEC: init usedflags section ...\n"); - memset(rkss->data, 0x00, RKSS_DATA_LEN); + memset(rkss->data, 0x00, RKSS_DATA_SECTION_LEN); for (n = 0; n < RKSS_PARTITION_TABLE_COUNT + 1; n++) { flagw = (uint8_t *)rkss->data + (int)n/2; value = 0x1; @@ -635,8 +541,8 @@ static int rkss_verify_usedflags(struct rk_secure_storage *rkss) static int rkss_get_fileinfo_by_index(int fd, struct rkss_file_info *pfileinfo) { - int i = fd / RKSS_EACH_FILEFOLDER_COUNT; - int n = fd - (RKSS_EACH_FILEFOLDER_COUNT * i); + int i = fd / RKSS_EACH_SECTION_FILECOUNT; + int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i); struct rk_secure_storage rkss = {0}; int ret; void *pdata; @@ -665,7 +571,7 @@ static int rkss_get_fileinfo_by_index(int fd, struct rkss_file_info *pfileinfo) } static int rkss_get_fileinfo_by_name( - char* filename, struct rkss_file_info *pfileinfo) + char *filename, struct rkss_file_info *pfileinfo) { int i = 0, ret; uint8_t n = 0; @@ -673,13 +579,12 @@ static int rkss_get_fileinfo_by_name( unsigned char *table_data; len = strlen(filename); - if (len > RKSS_NAME_MAX_LENGTH - 1) - { + if (len > RKSS_MAX_NAME_LENGTH - 1) { printf("TEEC: filename is too long. length:%u\n", len); return -1; } - table_data = malloc(RKSS_DATA_LEN * RKSS_PARTITION_TABLE_COUNT); + table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); if (table_data == NULL) { printf("TEEC: malloc table_data fail\n"); return -1; @@ -691,14 +596,12 @@ static int rkss_get_fileinfo_by_name( return -1; } - for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) - { + for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { struct rk_secure_storage rkss = {0}; rkss.index = i; - memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_LEN, RKSS_DATA_LEN); + memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); - for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) - { + for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { void *pdata = rkss.data; struct rkss_file_info *p = (struct rkss_file_info *)pdata; p += n; @@ -706,13 +609,12 @@ static int rkss_get_fileinfo_by_name( if (p->used == 0) continue; - if (!strcmp(p->name, filename)) - { + if (!strcmp(p->name, filename)) { debug("TEEC: rkss_get_fileinfo_by_name: hit table[%d/%d], index[%d/%d]\n", - i, RKSS_PARTITION_TABLE_COUNT, n, RKSS_EACH_FILEFOLDER_COUNT); + i, RKSS_PARTITION_TABLE_COUNT, n, RKSS_EACH_SECTION_FILECOUNT); memcpy(pfileinfo, p, sizeof(struct rkss_file_info)); free(table_data); - return i * RKSS_EACH_FILEFOLDER_COUNT + n; + return i * RKSS_EACH_SECTION_FILECOUNT + n; } // Folder Matching @@ -737,7 +639,7 @@ static int rkss_get_fileinfo_by_name( if (size_in != size_sv || ret) goto UNMATCHFOLDER; - } while(cur_inpos && cur_svpos); + } while (cur_inpos && cur_svpos); debug("TEEC: Matched folder: %s\n", p->name); free(table_data); @@ -751,7 +653,7 @@ UNMATCHFOLDER: return -1; } -static int rkss_get_dirs_by_name(char* filename) +static int rkss_get_dirs_by_name(char *filename) { int i = 0, ret; uint8_t n = 0; @@ -759,13 +661,12 @@ static int rkss_get_dirs_by_name(char* filename) unsigned char *table_data; len = strlen(filename); - if (len > RKSS_NAME_MAX_LENGTH - 1) - { + if (len > RKSS_MAX_NAME_LENGTH - 1) { printf("TEEC: filename is too long. length:%u\n", len); return -1; } - table_data = malloc(RKSS_DATA_LEN * RKSS_PARTITION_TABLE_COUNT); + table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); if (table_data == NULL) { printf("TEEC: malloc table_data fail\n"); return -1; @@ -778,14 +679,12 @@ static int rkss_get_dirs_by_name(char* filename) } dir_num = 0; - for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) - { + for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { struct rk_secure_storage rkss = {0}; rkss.index = i; - memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_LEN, RKSS_DATA_LEN); + memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); - for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) - { + for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { void *pdata = rkss.data; struct rkss_file_info *p = (struct rkss_file_info *)pdata; p += n; @@ -796,12 +695,10 @@ static int rkss_get_dirs_by_name(char* filename) // Full Matching ret = memcmp(p->name, filename, strlen(filename)); debug("TEEC: comparing [fd:%d] : %s ?= %s , ret:%d\n", - i*RKSS_EACH_FILEFOLDER_COUNT+n, p->name, filename, ret); - if (!ret && strlen(p->name) > strlen(filename)) - { + i*RKSS_EACH_SECTION_FILECOUNT+n, p->name, filename, ret); + if (!ret && strlen(p->name) > strlen(filename)) { char *chk = p->name + strlen(filename); - if (*chk == '/') - { + if (*chk == '/') { char *file = p->name + strlen(filename) + 1; char *subdir = strtok(file, "/"); debug("TEEC: found: %s\n", subdir); @@ -818,30 +715,23 @@ static int rkss_get_dirs_by_name(char* filename) static int rkss_get_empty_section_from_usedflags(int section_size) { struct rk_secure_storage rkss = {0}; - rkss.index = RKSS_USEDFLAGS_INDEX; + rkss.index = RKSS_USED_FLAGS_INDEX; int ret = rkss_read_section(&rkss); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: rkss_read_section fail ! ret: %d.\n", ret); return -1; } int i = 0; int count0 = 0; - for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) - { + for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) { uint8_t *flag = (uint8_t *)rkss.data + (int)i/2; uint8_t value = i & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; - if (value == 0x0) - { + if (value == 0x0) { if (++count0 == section_size) - { return (i + 1 - section_size); - } - } - else - { + } else { count0 = 0; } } @@ -861,7 +751,7 @@ static int rkss_incref_multi_usedflags_sections(unsigned int index, unsigned int return -1; } - rkss.index = RKSS_USEDFLAGS_INDEX; + rkss.index = RKSS_USED_FLAGS_INDEX; ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); if (ret < 0) { printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); @@ -897,7 +787,7 @@ static int rkss_decref_multi_usedflags_sections(unsigned int index, unsigned int return -1; } - rkss.index = RKSS_USEDFLAGS_INDEX; + rkss.index = RKSS_USED_FLAGS_INDEX; ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); if (ret < 0) { printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); @@ -926,7 +816,7 @@ static int rkss_write_empty_ptable(struct rkss_file_info *pfileinfo) int i = 0, ret; unsigned char *table_data; - table_data = malloc(RKSS_DATA_LEN * RKSS_PARTITION_TABLE_COUNT); + table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); if (table_data == NULL) { printf("TEEC: malloc table_data fail\n"); return -1; @@ -939,35 +829,31 @@ static int rkss_write_empty_ptable(struct rkss_file_info *pfileinfo) return -1; } - for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) - { + for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { struct rk_secure_storage rkss = {0}; rkss.index = i; - memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_LEN, RKSS_DATA_LEN); + memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); int n = 0; - for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) - { + for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { void *pdata = rkss.data; struct rkss_file_info *p = (struct rkss_file_info *)pdata; p += n; - if (p->used == 0) - { + if (p->used == 0) { debug("TEEC: write ptable in [%d][%d] .\n", i, n); memcpy(p, pfileinfo, sizeof(struct rkss_file_info)); p->used = 1; p->id = n; debug("TEEC: write emt ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n", - i,n,p->name,p->index,p->size,p->used); + i, n, p->name, p->index, p->size, p->used); ret = rkss_write_section(&rkss); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: rkss_write_section fail ! ret: %d.\n", ret); free(table_data); return -1; } free(table_data); - return i * RKSS_EACH_FILEFOLDER_COUNT + n; + return i * RKSS_EACH_SECTION_FILECOUNT + n; } } } @@ -978,14 +864,13 @@ static int rkss_write_empty_ptable(struct rkss_file_info *pfileinfo) static int rkss_write_back_ptable(int fd, struct rkss_file_info *pfileinfo) { - int i = fd / RKSS_EACH_FILEFOLDER_COUNT; - int n = fd - (RKSS_EACH_FILEFOLDER_COUNT * i); + int i = fd / RKSS_EACH_SECTION_FILECOUNT; + int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i); struct rk_secure_storage rkss = {0}; rkss.index = i; int ret = rkss_read_section(&rkss); - if (ret < 0) - { + if (ret < 0) { debug("TEEC: rkss_read_section fail ! ret: %d.\n", ret); return -1; } @@ -996,11 +881,10 @@ static int rkss_write_back_ptable(int fd, struct rkss_file_info *pfileinfo) memcpy(p, pfileinfo, sizeof(struct rkss_file_info)); debug("TEEC: write ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n", - i,n,p->name,p->index,p->size,p->used); + i, n, p->name, p->index, p->size, p->used); ret = rkss_write_section(&rkss); - if (ret < 0) - { + if (ret < 0) { debug("TEEC: rkss_write_section fail ! ret: %d.\n", ret); return -1; } @@ -1008,32 +892,12 @@ static int rkss_write_back_ptable(int fd, struct rkss_file_info *pfileinfo) return 0; } -/* - * Structure for file related RPC calls - * - * @op The operation like open, close, read, write etc - * @flags Flags to the operation shared with secure world - * @arg Argument to operation - * @fd NW file descriptor - * @len Length of buffer at the end of this struct - * @res Result of the operation - */ -struct tee_fs_rpc { - int op; - int flags; - int arg; - int fd; - uint32_t len; - int res; -}; - static int tee_fs_open(struct tee_fs_rpc *fsrpc) { int make_newfile = 0; char *filename = (char *)(fsrpc + 1); - if (strlen(filename) > RKSS_NAME_MAX_LENGTH) - { + if (strlen(filename) > RKSS_MAX_NAME_LENGTH) { debug("TEEC: tee_fs_open: file name too long. %s\n", filename); return -1; } @@ -1041,17 +905,13 @@ static int tee_fs_open(struct tee_fs_rpc *fsrpc) debug("TEEC: tee_fs_open open file: %s, len: %zu\n", filename, strlen(filename)); struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_name(filename, &p); - if (ret < 0) - { + if (ret < 0) { debug("TEEC: tee_fs_open : no such file. %s\n", filename); make_newfile = 1; - } - else - { + } else { fsrpc->fd = ret; file_seek = 0; - if (CHECKFLAG(fsrpc->flags, TEE_FS_O_APPEND)) - { + if (CHECKFLAG(fsrpc->flags, TEE_FS_O_APPEND)) { file_seek = p.size; } } @@ -1062,10 +922,8 @@ static int tee_fs_open(struct tee_fs_rpc *fsrpc) return -1; } - if (make_newfile) - { - if (CHECKFLAG(fsrpc->flags, TEE_FS_O_CREAT)) - { + if (make_newfile) { + if (CHECKFLAG(fsrpc->flags, TEE_FS_O_CREAT)) { debug("TEEC: tee_fs_open create new file: %s\n", filename); strcpy(p.name, filename); p.index = 0; @@ -1073,16 +931,13 @@ static int tee_fs_open(struct tee_fs_rpc *fsrpc) p.used = 1; p.flags = RK_FS_R | RK_FS_W; ret = rkss_write_empty_ptable(&p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: tee_fs_open : error. %s\n", filename); return -1; } fsrpc->fd = ret; file_seek = 0; - } - else - { + } else { debug("TEEC: and no create flag found.\n"); return -1; } @@ -1114,23 +969,21 @@ static int tee_fs_read(struct tee_fs_rpc *fsrpc) struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: unavailable fd !\n"); return -1; } - if (file_seek != 0) - { + if (file_seek != 0) { printf("TEEC: warning !!! file_seek != 0. unsupported now.\n"); } - int num = fsrpc->len / RKSS_DATA_LEN + 1; + int num = fsrpc->len / RKSS_DATA_SECTION_LEN + 1; int di = 0; debug("TEEC: reading section[%d], fd:%d, len:%d, filesize:%d\n", p.index, fsrpc->fd, fsrpc->len, p.size); - uint8_t *temp_file_data = malloc(num * RKSS_DATA_LEN); + uint8_t *temp_file_data = malloc(num * RKSS_DATA_SECTION_LEN); ret = rkss_read_multi_sections(temp_file_data, p.index, num); if (ret < 0) { printf("TEEC: unavailable file index\n"); @@ -1149,21 +1002,18 @@ static int tee_fs_write(struct tee_fs_rpc *fsrpc) debug("TEEC: tee_fs_write ! fd:%d, lenth:%d\n", fsrpc->fd, fsrpc->len); void *data = (void *)(fsrpc + 1); - if (fsrpc->fd < 0) - { + if (fsrpc->fd < 0) { printf("TEEC: tee_fs_write error ! wrong fd : %d\n", fsrpc->fd); return -1; } - if (file_seek != 0) - { + if (file_seek != 0) { printf("TEEC: warning !!! file_seek != 0. unsupported now.\n"); } struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: tee_fs_write: fd unvailable!\n"); return -1; } @@ -1175,7 +1025,7 @@ static int tee_fs_write(struct tee_fs_rpc *fsrpc) } int num; if (p.size != 0) { - num = p.size / RKSS_DATA_LEN + 1; + num = p.size / RKSS_DATA_SECTION_LEN + 1; ret = rkss_decref_multi_usedflags_sections(p.index, num); if (ret < 0) { printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); @@ -1184,7 +1034,7 @@ static int tee_fs_write(struct tee_fs_rpc *fsrpc) } p.size = fsrpc->len; - num = fsrpc->len / RKSS_DATA_LEN + 1; + num = fsrpc->len / RKSS_DATA_SECTION_LEN + 1; p.index = rkss_get_empty_section_from_usedflags(num); debug("TEEC: Get Empty section in %d\n", p.index); p.used = 1; @@ -1196,20 +1046,19 @@ static int tee_fs_write(struct tee_fs_rpc *fsrpc) } ret = rkss_write_back_ptable(fsrpc->fd, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: tee_fs_write: write ptable error!\n"); return -1; } - uint8_t *temp_file_data = malloc(num * RKSS_DATA_LEN); - memset(temp_file_data, 0, num * RKSS_DATA_LEN); + uint8_t *temp_file_data = malloc(num * RKSS_DATA_SECTION_LEN); + memset(temp_file_data, 0, num * RKSS_DATA_SECTION_LEN); memcpy(temp_file_data, data, p.size); rkss_write_multi_sections(temp_file_data, p.index, num); free(temp_file_data); temp_file_data = 0; -#ifdef DEBUG_RKFSS +#ifdef DEBUG_RKSS rkss_dump_usedflags(); #endif @@ -1226,29 +1075,21 @@ static int tee_fs_seek(struct tee_fs_rpc *fsrpc) { debug("TEEC: tee_fs_seek ! fd:%d, seek:%d, flag:%x\n", fsrpc->fd, fsrpc->arg, fsrpc->flags); - if (fsrpc->flags == TEE_FS_SEEK_CUR) - { + if (fsrpc->flags == TEE_FS_SEEK_CUR) { fsrpc->res = file_seek + fsrpc->arg; - } - else if (fsrpc->flags == TEE_FS_SEEK_SET) - { + } else if (fsrpc->flags == TEE_FS_SEEK_SET) { file_seek = fsrpc->arg; fsrpc->res = file_seek; - } - else if (fsrpc->flags == TEE_FS_SEEK_END) - { + } else if (fsrpc->flags == TEE_FS_SEEK_END) { struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: unavilable fd.\n"); return -1; } file_seek = p.size + fsrpc->arg; fsrpc->res = file_seek; - } - else - { + } else { printf("TEEC: tee_fs_seek: unsupport seed mode.\n"); return -1; } @@ -1262,8 +1103,7 @@ static int tee_fs_unlink(struct tee_fs_rpc *fsrpc) struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_name(filename, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: tee_fs_unlink : no such file. %s\n", filename); return 0; } @@ -1278,10 +1118,9 @@ static int tee_fs_unlink(struct tee_fs_rpc *fsrpc) } /* decrease ref from usedflags */ - int num = p.size / RKSS_DATA_LEN + 1; + int num = p.size / RKSS_DATA_SECTION_LEN + 1; ret = rkss_decref_multi_usedflags_sections(p.index, num); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); return -1; } @@ -1289,13 +1128,12 @@ static int tee_fs_unlink(struct tee_fs_rpc *fsrpc) /* rm from ptable */ memset(&p, 0, sizeof(struct rkss_file_info)); ret = rkss_write_back_ptable(fd, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: tee_fs_unlink : write back error %d\n", ret); return -1; } -#ifdef DEBUG_RKFSS +#ifdef DEBUG_RKSS rkss_dump_ptable(); #endif @@ -1317,16 +1155,14 @@ static int tee_fs_link(struct tee_fs_rpc *fsrpc) struct rkss_file_info p_old = {0}; int ret = rkss_get_fileinfo_by_name(filename, &p_old); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: cannot find src file %s.\n", filename); return -1; } struct rkss_file_info p_check = {0}; ret = rkss_get_fileinfo_by_name(newfilename, &p_check); - if (ret >= 0) - { + if (ret >= 0) { printf("TEEC: file exist ! %s.\n", newfilename); return -1; } @@ -1340,21 +1176,19 @@ static int tee_fs_link(struct tee_fs_rpc *fsrpc) memcpy(&p_new, &p_old, sizeof(struct rkss_file_info)); strcpy(p_new.name, newfilename); ret = rkss_write_empty_ptable(&p_new); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: tee_fs_open : error. %s\n", filename); return -1; } - int num = p_new.size / RKSS_DATA_LEN + 1; + int num = p_new.size / RKSS_DATA_SECTION_LEN + 1; ret = rkss_incref_multi_usedflags_sections(p_new.index, num); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: rkss_incref_multi_usedflags_sections error !\n"); return -1; } -#ifdef DEBUG_RKFSS +#ifdef DEBUG_RKSS rkss_dump_ptable(); #endif ret = rkss_finish_commit(); @@ -1374,8 +1208,7 @@ static int tee_fs_rename(struct tee_fs_rpc *fsrpc) struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_name(filenames, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: filename no found .\n"); return -1; } @@ -1389,8 +1222,7 @@ static int tee_fs_rename(struct tee_fs_rpc *fsrpc) strcpy(p.name, newnames); ret = rkss_write_back_ptable(ret, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: write ptable error!\n"); return -1; } @@ -1410,16 +1242,14 @@ static int tee_fs_truncate(struct tee_fs_rpc *fsrpc) uint16_t free_index; debug("TEEC: tee_fs_truncate: fd:%d, lenth:%d\n", fsrpc->fd, fsrpc->arg); - if (fsrpc->fd < 0) - { + if (fsrpc->fd < 0) { printf("TEEC: tee_fs_truncate: fd unavilable !\n"); return -1; } struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: fd unvailable!\n"); return -1; } @@ -1432,8 +1262,8 @@ static int tee_fs_truncate(struct tee_fs_rpc *fsrpc) printf("TEEC: truncate size not support!\n "); return -1; } else { - section_num = p.size / RKSS_DATA_LEN + 1; - new_section_num = fsrpc->arg / RKSS_DATA_LEN + 1; + section_num = p.size / RKSS_DATA_SECTION_LEN + 1; + new_section_num = fsrpc->arg / RKSS_DATA_SECTION_LEN + 1; free_section_num = section_num - new_section_num; free_index = p.index + new_section_num; ret = rkss_decref_multi_usedflags_sections(free_index, free_section_num); @@ -1470,8 +1300,7 @@ static int tee_fs_opendir(struct tee_fs_rpc *fsrpc) char *dirname = (char *)(fsrpc + 1); dir_seek = 0; int ret = rkss_get_dirs_by_name(dirname); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: tee_fs_opendir: error\n"); } debug("TEEC: tee_fs_opendir: %s, seek/num:%d/%d\n", dirname, dir_seek, dir_num); @@ -1492,8 +1321,7 @@ static int tee_fs_readdir(struct tee_fs_rpc *fsrpc) { char *dirname = (char *)(fsrpc + 1); debug("TEEC: seek/num:%d/%d\n", dir_seek, dir_num); - if (dir_seek == dir_num) - { + if (dir_seek == dir_num) { dirname = NULL; fsrpc->len = 0; debug("TEEC: tee_fs_readdir: END\n"); @@ -1515,13 +1343,10 @@ static int tee_fs_rmdir(struct tee_fs_rpc *fsrpc) struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_name(dirname, &p); - if (ret == -100) - { + if (ret == -100) { printf("TEEC: dir is not empty.\n"); return -1; - } - else if (ret >= 0) - { + } else if (ret >= 0) { printf("TEEC: %s is not a dir.\n", p.name); return -1; } @@ -1536,25 +1361,20 @@ static int tee_fs_access(struct tee_fs_rpc *fsrpc) struct rkss_file_info p = {0}; int ret = rkss_get_fileinfo_by_name(filename, &p); - if (ret < 0 && ret != -100) - { + if (ret < 0 && ret != -100) { debug("TEEC: tee_fs_access: %s no such file or directory.\n", filename); return -1; } - if (CHECKFLAG(fsrpc->flags, TEE_FS_R_OK)) - { - if (!CHECKFLAG(p.flags, RK_FS_R)) - { + if (CHECKFLAG(fsrpc->flags, TEE_FS_R_OK)) { + if (!CHECKFLAG(p.flags, RK_FS_R)) { printf("TEEC: tee_fs_access: no permission FS_R_OK in %x.\n", p.flags); return -1; } } - if (CHECKFLAG(fsrpc->flags, TEE_FS_W_OK)) - { - if (!CHECKFLAG(p.flags, RK_FS_W)) - { + if (CHECKFLAG(fsrpc->flags, TEE_FS_W_OK)) { + if (!CHECKFLAG(p.flags, RK_FS_W)) { printf("TEEC: tee_fs_access: no permission FS_W_OK in %x.\n", p.flags); return -1; } @@ -1562,10 +1382,10 @@ static int tee_fs_access(struct tee_fs_rpc *fsrpc) return 0; } -int tee_supp_rk_fs_init(void) +int tee_supp_rk_fs_init_v1(void) { assert(sizeof(struct rkss_file_info) == 126); - assert(512 / sizeof(struct rkss_file_info) == RKSS_EACH_FILEFOLDER_COUNT); + assert(512 / sizeof(struct rkss_file_info) == RKSS_EACH_SECTION_FILECOUNT); __maybe_unused int i = 0; unsigned char *table_data; @@ -1580,10 +1400,9 @@ int tee_supp_rk_fs_init(void) return -1; } #ifdef DEBUG_CLEAN_RKSS // clean secure storage - for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) - { + for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) { struct rk_secure_storage rkss = {0}; - memset(rkss.data, 0, RKSS_DATA_LEN); + memset(rkss.data, 0, RKSS_DATA_SECTION_LEN); rkss.index = i; rkss_write_section(&rkss); printf("TEEC: cleaned [%d]", i); @@ -1597,7 +1416,7 @@ int tee_supp_rk_fs_init(void) } // Verify Partition Table - table_data = malloc(RKSS_DATA_LEN * RKSS_PARTITION_TABLE_COUNT); + table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); if (table_data == NULL) { printf("TEEC: malloc table_data fail\n"); return -1; @@ -1621,21 +1440,19 @@ int tee_supp_rk_fs_init(void) // Verify Usedflags Section struct rk_secure_storage rkss = {0}; - rkss.index = RKSS_USEDFLAGS_INDEX; + rkss.index = RKSS_USED_FLAGS_INDEX; ret = rkss_read_section(&rkss); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: rkss_read_section fail ! ret: %d.\n", ret); return -1; } ret = rkss_verify_usedflags(&rkss); - if (ret < 0) - { + if (ret < 0) { printf("TEEC: rkss_verify_usedflags fail ! ret: %d.\n", ret); return -1; } -#ifdef DEBUG_RKFSS +#ifdef DEBUG_RKSS rkss_dump_ptable(); rkss_dump_usedflags(); #endif @@ -1648,26 +1465,24 @@ int tee_supp_rk_fs_init(void) return 0; } -int OpteeClientRkFsInit(void) -{ - debug("TEEC: OpteeClientRkFsInit\n"); - return tee_supp_rk_fs_init(); -} -static int rkss_step = 0; -int tee_supp_rk_fs_process(void *cmd, size_t cmd_size) +static int rkss_step; +int tee_supp_rk_fs_process_v1(void *cmd, size_t cmd_size) { struct tee_fs_rpc *fsrpc = cmd; int ret = -1; - if (cmd_size < sizeof(struct tee_fs_rpc)) - { + if (check_security_exist(0) < 0) { + printf("TEEC: security partition not exist! unable to use RK FS!\n"); + return ret; + } + + if (cmd_size < sizeof(struct tee_fs_rpc)) { printf(">>>cmd_size < sizeof(struct tee_fs_rpc) !\n"); return ret; } - if (cmd == NULL) - { + if (cmd == NULL) { printf(">>>cmd == NULL !\n"); return ret; } @@ -1744,3 +1559,4 @@ int tee_supp_rk_fs_process(void *cmd, size_t cmd_size) return ret; } + diff --git a/lib/optee_clientApi/OpteeClientRkFs_v2.c b/lib/optee_clientApi/OpteeClientRkFs_v2.c new file mode 100644 index 0000000000..b8d6d45b8a --- /dev/null +++ b/lib/optee_clientApi/OpteeClientRkFs_v2.c @@ -0,0 +1,1451 @@ +/* + * Copyright 2020, Rockchip Electronics Co., Ltd + * hisping lin, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +//#define DEBUG_RKSS +//#define DEBUG_CLEAN_RKSS + +/* + * RK Secure Storage Version 2 + * Area0 Backup 0 Size : 256 kb <----> Area0 Backup 1 Size : 256 kb + * Area1 Backup 0 Size : 256 kb <----> Area1 Backup 1 Size : 256 kb + * + * ------ 1 section is 512 bytes ----- + * ------ Area0 Backup0 section from 0 to 511 -------- + * 1 section for file header [0] + * 1 section for used flags [1] + * - 1 byte = 2 flag + * 62 section for file tables [2-63] + * - size of table 128 bytes + * 447 section for data [64-510] + * 1 section for file footer [511] + * + * ------ Area0 Backup1 section from 512 to 1023 -------- + * 1 section for file header [512] + * 1 section for used flags [513] + * - 1 byte = 2 flag + * 62 section for file tables [514-575] + * - size of table 128 bytes + * 447 section for data [576-1022] + * 1 section for file footer [1023] + * + * ------ Area1 Backup0 section from 1024 to 1535 -------- + * 1 section for file header [1024] + * 1 section for used flags [1025] + * - 1 byte = 2 flag + * 62 section for file tables [1026-1087] + * - size of table 128 bytes + * 447 section for data [1088-1534] + * 1 section for file footer [1535] + * + * ------ Area1 Backup1 section from 1536 to 2047 -------- + * 1 section for file header [1536] + * 1 section for used flags [1537] + * - 1 byte = 2 flag + * 62 section for file tables [1538-1599] + * - size of table 128 bytes + * 447 section for data [1600-2046] + * 1 section for file footer [2047] + */ + +/* define for backup */ +#define RKSS_HEADER_INDEX 0 +#define RKSS_HEADER_COUNT 1 +#define RKSS_USEDFLAGS_INDEX 1 +#define RKSS_USEDFLAGS_COUNT 1 +#define RKSS_TABLE_INDEX 2 +#define RKSS_TABLE_COUNT 62 +#define RKSS_DATA_INDEX 64 +#define RKSS_DATA_COUNT 447 +#define RKSS_FOOTER_INDEX 511 +#define RKSS_FOOTER_COUNT 1 +#define RKSS_SECTION_COUNT 512 + +#define RKSS_MAX_AREA_NUM 8 +#define RKSS_ACTIVE_AREA_NUM 2 +#define RKSS_DATA_LEN 512 +#define RKSS_EACH_FILEFOLDER_COUNT 4 +#define RKSS_TABLE_SIZE 128 +#define RKSS_NAME_MAX_LENGTH 112 +#define RKSS_BACKUP_NUM 2 +#define RKSS_TAG 0x524B5353 + +struct rkss_file_header { + uint32_t tag; + uint32_t version; + uint32_t backup_count; + uint16_t backup_index; + uint16_t backup_dirty; + uint8_t reserve[496]; +}; +struct rkss_file_table { + uint32_t size; + uint16_t index; + uint8_t flags; + uint8_t used; + char name[RKSS_NAME_MAX_LENGTH]; + uint8_t reserve[8]; +}; +struct rkss_file_footer { + uint8_t reserve[508]; + uint32_t backup_count; +}; +struct rkss_file { + struct rkss_file_header *header; + uint8_t *flags; + struct rkss_file_table *table; + uint8_t *data; + struct rkss_file_footer *footer; +}; + +/* RK Secure Storage Calls */ +static int file_seek; +static char dir_cache[RKSS_NAME_MAX_LENGTH][12]; +static int dir_num; +static int dir_seek; +static uint8_t *rkss_buffer[RKSS_MAX_AREA_NUM]; +static struct rkss_file rkss_info[RKSS_MAX_AREA_NUM]; + +static struct blk_desc *dev_desc; +static disk_partition_t part_info; + +static int check_security_exist(int print_flag) +{ + if (!dev_desc) { + dev_desc = rockchip_get_bootdev(); + if (!dev_desc) { + printf("TEEC: %s: Could not find device\n", __func__); + return -1; + } + + if (part_get_info_by_name(dev_desc, + "security", &part_info) < 0) { + dev_desc = NULL; + if (print_flag != 0) + printf("TEEC: Could not find security partition\n"); + return -1; + } + } + return 0; +} + +static int rkss_verify_usedflags(unsigned int area_index) +{ + uint8_t *flags; + int i, duel, flag, n, value; + uint8_t *flagw; + int used_count; + + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: Not support area_index 0x%x\n", area_index); + return -1; + } + + flags = rkss_info[area_index].flags; + if (flags == NULL) { + printf("TEEC: %s flags is null\n", __func__); + return -1; + } + + used_count = RKSS_HEADER_COUNT + + RKSS_USEDFLAGS_COUNT + + RKSS_TABLE_COUNT; + + for (i = 0; i < used_count; i++) { + duel = *(flags + (int)i/2); + flag = i & 0x1 ? duel & 0x0F : (duel & 0xF0) >> 4; + if (flag != 0x1) + goto init; + } + + for (i = RKSS_FOOTER_INDEX; i < RKSS_USEDFLAGS_COUNT * RKSS_DATA_LEN * 2; i++) { + duel = *(flags + (int)i/2); + flag = i & 0x1 ? duel & 0x0F : (duel & 0xF0) >> 4; + if (flag != 0x1) + goto init; + } + + debug("TEEC: %s: success.\n", __func__); + return 0; + +init: + debug("TEEC: init usedflags section ...\n"); + memset(flags, 0, RKSS_USEDFLAGS_COUNT * RKSS_DATA_LEN); + for (n = 0; n < used_count; n++) { + flagw = flags + (int)n/2; + value = 0x1; + *flagw = n & 0x1 ? (*flagw & 0xF0) | (value & 0x0F) : + (*flagw & 0x0F) | (value << 4); + } + + for (n = RKSS_FOOTER_INDEX; n < RKSS_USEDFLAGS_COUNT * RKSS_DATA_LEN * 2; n++) { + flagw = flags + (int)n/2; + value = 0x1; + *flagw = n & 0x1 ? (*flagw & 0xF0) | (value & 0x0F) : + (*flagw & 0x0F) | (value << 4); + } + return 0; +} + +#ifdef DEBUG_CLEAN_RKSS +static int rkss_storage_delete(uint32_t area_index) +{ + int ret; + uint32_t size; + uint8_t *delete_buff; + + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: Not support area_index 0x%x\n", area_index); + return -1; + } + + printf("TEEC: delete area index 0x%x!\n", area_index); + size = RKSS_SECTION_COUNT * RKSS_BACKUP_NUM * RKSS_DATA_LEN; + delete_buff = (uint8_t *)malloc(size); + if (!delete_buff) { + printf("TEEC: Malloc failed!\n"); + return -1; + } + memset(delete_buff, 0, size); + ret = blk_dwrite(dev_desc, + part_info.start + area_index * RKSS_SECTION_COUNT * RKSS_BACKUP_NUM, + RKSS_SECTION_COUNT * RKSS_BACKUP_NUM, delete_buff); + if (ret != RKSS_SECTION_COUNT * RKSS_BACKUP_NUM) { + free(delete_buff); + printf("TEEC: blk_dwrite fail\n"); + return -1; + } + + if (delete_buff) + free(delete_buff); + printf("TEEC: delete area success!\n"); + return 0; +} + +static int rkss_storage_reset(void) +{ + if (rkss_storage_delete(0) < 0) + return -1; + if (rkss_storage_delete(1) < 0) + return -1; + return 0; +} +#endif + +#ifdef DEBUG_RKSS +static void rkss_dump(void *data, unsigned int len) +{ + char *p = (char *)data; + unsigned int i = 0; + + printf("-------------- DUMP %d --------------\n", len); + for (i = 0; i < len; i++) { + if (i % 32 == 0) + printf("\n"); + printf("%02x ", *(p + i)); + } + printf("\n------------- DUMP END -------------\n"); +} + +static void rkss_dump_ptable(void) +{ + int i, j, n; + struct rkss_file_table *ptable; + + printf("-------------- DUMP ptable --------------\n"); + + for (i = 0; i < RKSS_MAX_AREA_NUM; i++) { + ptable = rkss_info[i].table; + if (rkss_info[i].table == NULL) + continue; + printf("--------------- area[%d] tables ------------\n", i); + for (j = 0; j < RKSS_TABLE_COUNT; j++) { + for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) { + printf("[%02d][%c] %s , inx:%d, size:%d\n", + j * RKSS_EACH_FILEFOLDER_COUNT + n, + ptable->used == 0 ? 'F':'T', ptable->name, + ptable->index, ptable->size); + + ptable++; + } + } + } + printf("-------------- DUMP END --------------\n"); +} + +static void rkss_dump_usedflags(void) +{ + int i; + + for (i = 0; i < RKSS_MAX_AREA_NUM; i++) { + if (rkss_info[i].flags == NULL) + continue; + printf("--------------- area[%d] flags ------------\n", i); + rkss_dump(rkss_info[i].flags, RKSS_USEDFLAGS_COUNT * RKSS_DATA_LEN); + } +} +#endif + +static int rkss_read_multi_sections(unsigned int area_index, + unsigned char *data, unsigned long index, unsigned int num) +{ + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: %s area_index invalid\n", __func__); + return -1; + } + if (index >= RKSS_SECTION_COUNT || num > RKSS_SECTION_COUNT || + (index + num) > RKSS_SECTION_COUNT) { + printf("TEEC: %s index num invalid\n", __func__); + return -1; + } + if (rkss_buffer[area_index] == NULL) { + printf("TEEC: %s rkss_buffer is null\n", __func__); + return -1; + } + memcpy(data, rkss_buffer[area_index] + index * RKSS_DATA_LEN, num * RKSS_DATA_LEN); + return 0; +} + +static int rkss_write_multi_sections(unsigned int area_index, + unsigned char *data, unsigned long index, unsigned int num) +{ + if (num == 0) + return 0; + + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: %s area_index invalid\n", __func__); + return -1; + } + + if (index >= RKSS_SECTION_COUNT || num > RKSS_SECTION_COUNT || + (index + num) > RKSS_SECTION_COUNT) { + printf("TEEC: %s index num invalid\n", __func__); + return -1; + } + + if (rkss_buffer[area_index] == NULL) { + printf("TEEC: %s rkss_buffer is null\n", __func__); + return -1; + } + + memcpy(rkss_buffer[area_index] + index * RKSS_DATA_LEN, data, num * RKSS_DATA_LEN); + rkss_info[area_index].header->backup_dirty = 1; + return 0; +} + +static int rkss_get_fileinfo_by_index(int fd, + struct rkss_file_table *ptable, unsigned int *out_area_index) +{ + struct rkss_file_table *p; + unsigned int area_index; + + area_index = fd / (RKSS_TABLE_COUNT * RKSS_EACH_FILEFOLDER_COUNT); + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: %s area_index invalid\n", __func__); + return -1; + } + + p = rkss_info[area_index].table; + if (p == NULL) { + printf("TEEC: %s table is null\n", __func__); + return -1; + } + + p += fd % (RKSS_TABLE_COUNT * RKSS_EACH_FILEFOLDER_COUNT); + if (p->used != 1) { + debug("TEEC: %s unused table!\n", __func__); + return -1; + } + debug("TEEC: %s p->used = %d p->name=%s p->index=%d p->size=%d\n", + __func__, p->used, p->name, p->index, p->size); + memcpy(ptable, p, sizeof(struct rkss_file_table)); + *out_area_index = area_index; + return 0; +} + +static int rkss_get_fileinfo_by_name(char *filename, + struct rkss_file_table *ptable, unsigned int *out_area_index) +{ + int ret; + unsigned int i, j, n, len; + struct rkss_file_table *p; + + len = strlen(filename); + if (len > RKSS_NAME_MAX_LENGTH - 1) { + printf("TEEC: filename is too long. length:%u\n", len); + return -1; + } + + for (i = 0; i < RKSS_MAX_AREA_NUM; i++) { + if (rkss_info[i].table == NULL) + continue; + for (j = 0; j < RKSS_TABLE_COUNT; j++) { + for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) { + p = rkss_info[i].table + j * RKSS_EACH_FILEFOLDER_COUNT + n; + + if (p->used == 0) + continue; + + if (!strcmp(p->name, filename)) { + debug("TEEC: %s: area%d hit table[%d/%d], index[%d/%d]\n", + __func__, i, j, RKSS_TABLE_COUNT, n, RKSS_EACH_FILEFOLDER_COUNT); + memcpy(ptable, p, sizeof(struct rkss_file_table)); + *out_area_index = i; + ret = i * RKSS_TABLE_COUNT * RKSS_EACH_FILEFOLDER_COUNT + + j * RKSS_EACH_FILEFOLDER_COUNT + n; + return ret; + } + + // Folder Matching + const char *split = "/"; + char *last_inpos = filename; + char *last_svpos = p->name; + char *cur_inpos = NULL; + char *cur_svpos = NULL; + + do { + cur_inpos = strstr(last_inpos, split); + cur_svpos = strstr(last_svpos, split); + int size_in = cur_inpos == NULL ? + (int)strlen(last_inpos) : cur_inpos - last_inpos; + int size_sv = cur_svpos == NULL ? + (int)strlen(last_svpos) : cur_svpos - last_svpos; + + ret = memcmp(last_inpos, last_svpos, size_in); + + last_inpos = cur_inpos + 1; + last_svpos = cur_svpos + 1; + + if (size_in != size_sv || ret) + goto UNMATCHFOLDER; + + } while (cur_inpos && cur_svpos); + + debug("TEEC: Matched folder: %s\n", p->name); + return -100; +UNMATCHFOLDER: + debug("TEEC: Unmatched ..."); + } + } + } + debug("TEEC: %s: file or dir no found!\n", __func__); + return -1; +} + +static int rkss_get_dirs_by_name(char *filename) +{ + int ret; + unsigned int i, j, n, len; + struct rkss_file_table *p; + + len = strlen(filename); + if (len > RKSS_NAME_MAX_LENGTH - 1) { + printf("TEEC: filename is too long. length:%u\n", len); + return -1; + } + + dir_num = 0; + for (i = 0; i < RKSS_MAX_AREA_NUM; i++) { + if (rkss_info[i].table == NULL) + continue; + for (j = 0; j < RKSS_TABLE_COUNT; j++) { + for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) { + p = rkss_info[i].table + j * RKSS_EACH_FILEFOLDER_COUNT + n; + + if (p->used == 0) + continue; + + // Full Matching + ret = memcmp(p->name, filename, strlen(filename)); + debug("TEEC: comparing [fd:%d] : %s ?= %s, ret: %d\n", + (i * RKSS_TABLE_COUNT + j) * RKSS_EACH_FILEFOLDER_COUNT + n, + p->name, filename, ret); + if (!ret && strlen(p->name) > strlen(filename)) { + char *chk = p->name + strlen(filename); + if (*chk == '/') { + char *file = p->name + strlen(filename) + 1; + char *subdir = strtok(file, "/"); + debug("TEEC: found: %s\n", subdir); + strcpy(dir_cache[dir_num], subdir); + ++dir_num; + } + } + } + } + } + return dir_num; +} + +static int rkss_get_empty_section_from_usedflags( + unsigned int area_index, int section_size) +{ + int i = 0; + int count0 = 0; + + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: %s area_index invalid\n", __func__); + return -1; + } + if (rkss_info[area_index].flags == NULL) { + printf("TEEC: %s flags is null\n", __func__); + return -1; + } + for (i = 0; i < RKSS_SECTION_COUNT; i++) { + uint8_t *flag = rkss_info[area_index].flags + (int)i/2; + uint8_t value = i & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; + + if (value == 0x0) { + if (++count0 == section_size) + return (i + 1 - section_size); + } else { + count0 = 0; + } + } + + printf("TEEC: Not enough space available in secure storage !\n"); + return -10; +} + +static int rkss_incref_multi_usedflags_sections( + unsigned int area_index, unsigned int index, unsigned int num) +{ + int value, i; + uint8_t *flag; + + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: %s area_index invalid\n", __func__); + return -1; + } + + if (index >= RKSS_SECTION_COUNT || num > RKSS_SECTION_COUNT || + (index + num) > RKSS_SECTION_COUNT) { + printf("TEEC: index[%d] out of range.\n", index); + return -1; + } + if (rkss_info[area_index].flags == NULL) { + printf("TEEC: %s flags is null\n", __func__); + return -1; + } + + for (i = 0; i < num; i++, index++) { + flag = rkss_info[area_index].flags + (int)index / 2; + value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; + if (++value > 0xF) { + printf("TEEC: reference out of data: %d\n", value); + value = 0xF; + } + *flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) : + (*flag & 0x0F) | (value << 4); + } + rkss_info[area_index].header->backup_dirty = 1; + return 0; +} + +static int rkss_decref_multi_usedflags_sections( + unsigned int area_index, unsigned int index, unsigned int num) +{ + int value, i; + uint8_t *flag; + + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: %s area_index invalid\n", __func__); + return -1; + } + + if (index >= RKSS_SECTION_COUNT || num > RKSS_SECTION_COUNT || + (index + num) > RKSS_SECTION_COUNT) { + printf("TEEC: index[%d] out of range.\n", index); + return -1; + } + if (rkss_info[area_index].flags == NULL) { + printf("TEEC: %s flags is null\n", __func__); + return -1; + } + + for (i = 0; i < num; i++, index++) { + flag = rkss_info[area_index].flags + (int)index / 2; + value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; + if (--value < 0) { + printf("TEEC: reference out of data: %d\n", value); + value = 0x0; + } + *flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) : + (*flag & 0x0F) | (value << 4); + } + rkss_info[area_index].header->backup_dirty = 1; + return 0; +} + +static int rkss_get_remain_tables(struct rkss_file_table *p) +{ + unsigned int i, n; + int count = 0; + + if (p == NULL) + return -1; + + for (i = 0; i < RKSS_TABLE_COUNT; i++) { + for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) { + if (p->used == 0) + count++; + p++; + } + } + return count; +} + +static int rkss_get_remain_flags(uint8_t *flags) +{ + unsigned int i, value; + uint8_t *flag; + int count = 0; + + if (flags == NULL) + return -1; + + for (i = 0; i < RKSS_SECTION_COUNT; i++) { + flag = flags + (int)i / 2; + value = i & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; + if (value == 0) + count++; + } + return count; +} + +static int rkss_get_larger_area(void) +{ + int i, tables, flags, max_flags = 0; + int area_index = -1; + + for (i = 0; i < RKSS_MAX_AREA_NUM; i++) { + if (rkss_info[i].table == NULL || + rkss_info[i].flags == NULL) + continue; + tables = rkss_get_remain_tables(rkss_info[i].table); + flags = rkss_get_remain_flags(rkss_info[i].flags); + if (tables > 0 && flags > 0 && flags > max_flags) { + max_flags = flags; + area_index = i; + } + } + return area_index; +} + +static int rkss_write_area_empty_ptable( + unsigned int area_index, struct rkss_file_table *pfile_table) +{ + int i, n, ret; + struct rkss_file_table *p; + + if (rkss_info[area_index].table == NULL) { + printf("TEEC: %s table is null\n", __func__); + return -1; + } + for (i = 0; i < RKSS_TABLE_COUNT; i++) { + for (n = 0; n < RKSS_EACH_FILEFOLDER_COUNT; n++) { + p = rkss_info[area_index].table + i * RKSS_EACH_FILEFOLDER_COUNT + n; + if (p->used == 0) { + memcpy(p, pfile_table, sizeof(struct rkss_file_table)); + p->used = 1; + debug("TEEC: write emt ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n", + i, n, p->name, p->index, p->size, p->used); + rkss_info[area_index].header->backup_dirty = 1; + ret = area_index * RKSS_TABLE_COUNT * RKSS_EACH_FILEFOLDER_COUNT + + i * RKSS_EACH_FILEFOLDER_COUNT + n; + return ret; + } + } + } + printf("TEEC: No enough ptable space available in secure storage.\n"); + return -1; +} + +static int rkss_write_empty_ptable(struct rkss_file_table *pfile_table) +{ + int area_index; + + area_index = rkss_get_larger_area(); + if (area_index < 0) { + printf("TEEC: get area index fail\n"); + return -1; + } + + return rkss_write_area_empty_ptable(area_index, pfile_table); +} + +static int rkss_write_back_ptable( + int fd, struct rkss_file_table *pfile_table) +{ + struct rkss_file_table *p; + unsigned int area_index; + + area_index = fd / (RKSS_TABLE_COUNT * RKSS_EACH_FILEFOLDER_COUNT); + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: %s area_index invalid\n", __func__); + return -1; + } + + p = rkss_info[area_index].table; + if (p == NULL) { + printf("TEEC: %s table is null\n", __func__); + return -1; + } + + p += fd % (RKSS_TABLE_COUNT * RKSS_EACH_FILEFOLDER_COUNT); + + memcpy(p, pfile_table, sizeof(struct rkss_file_table)); + debug("TEEC: write ptable : name:%s, index:%d, size:%d, used:%d\n", + p->name, p->index, p->size, p->used); + + rkss_info[area_index].header->backup_dirty = 1; + return 0; +} + +static int rkss_storage_write(void) +{ + int ret, i; + + for (i = 0; i < RKSS_MAX_AREA_NUM; i++) { + if (rkss_info[i].header != NULL && rkss_info[i].header->backup_dirty == 1) { + rkss_info[i].header->backup_count++; + rkss_info[i].footer->backup_count = rkss_info[i].header->backup_count; + rkss_info[i].header->backup_index++; + if (rkss_info[i].header->backup_index >= RKSS_BACKUP_NUM) + rkss_info[i].header->backup_index = 0; + rkss_info[i].header->backup_dirty = 0; + + if (rkss_info[i].header->backup_count == 0xffffffff) { + rkss_info[i].header->backup_count = 1; + rkss_info[i].footer->backup_count = 1; + ret = blk_dwrite(dev_desc, + part_info.start + i * RKSS_SECTION_COUNT * RKSS_BACKUP_NUM + + rkss_info[i].header->backup_index * RKSS_SECTION_COUNT, + RKSS_SECTION_COUNT, rkss_buffer[i]); + if (ret != RKSS_SECTION_COUNT) { + printf("TEEC: blk_dwrite fail\n"); + return -1; + } + + rkss_info[i].header->backup_count = 2; + rkss_info[i].footer->backup_count = 2; + rkss_info[i].header->backup_index++; + if (rkss_info[i].header->backup_index >= RKSS_BACKUP_NUM) + rkss_info[i].header->backup_index = 0; + ret = blk_dwrite(dev_desc, + part_info.start + i * RKSS_SECTION_COUNT * RKSS_BACKUP_NUM + + rkss_info[i].header->backup_index * RKSS_SECTION_COUNT, + RKSS_SECTION_COUNT, rkss_buffer[i]); + if (ret != RKSS_SECTION_COUNT) { + printf("TEEC: blk_dwrite fail\n"); + return -1; + } + } else { + ret = blk_dwrite(dev_desc, + part_info.start + i * RKSS_SECTION_COUNT * RKSS_BACKUP_NUM + + rkss_info[i].header->backup_index * RKSS_SECTION_COUNT, + RKSS_SECTION_COUNT, rkss_buffer[i]); + if (ret != RKSS_SECTION_COUNT) { + printf("TEEC: blk_dwrite fail\n"); + return -1; + } + } + } + } + return 0; +} + +static int rkss_storage_init(uint32_t area_index) +{ + unsigned long ret = 0; + uint32_t size, i; + uint32_t max_ver = 0; + uint32_t max_index = 0; + uint32_t flags_offset, table_offset, data_offset, footer_offset; + + if (area_index >= RKSS_MAX_AREA_NUM) { + printf("TEEC: Not support index=0x%x\n", area_index); + return -1; + } + + size = RKSS_SECTION_COUNT * RKSS_DATA_LEN; + flags_offset = RKSS_USEDFLAGS_INDEX * RKSS_DATA_LEN; + table_offset = RKSS_TABLE_INDEX * RKSS_DATA_LEN; + data_offset = RKSS_DATA_INDEX * RKSS_DATA_LEN; + footer_offset = RKSS_FOOTER_INDEX * RKSS_DATA_LEN; + + if (rkss_buffer[area_index] == NULL) { + /* Always use, no need to release */ + rkss_buffer[area_index] = (uint8_t *)malloc(size); + if (!(rkss_buffer[area_index])) { + printf("TEEC: Malloc failed!\n"); + return -1; + } + + /* Pointer initialization */ + rkss_info[area_index].header = (struct rkss_file_header *)(rkss_buffer[area_index]); + rkss_info[area_index].flags = (uint8_t *)(rkss_buffer[area_index] + flags_offset); + rkss_info[area_index].table = (struct rkss_file_table *)(rkss_buffer[area_index] + table_offset); + rkss_info[area_index].data = (uint8_t *)(rkss_buffer[area_index] + data_offset); + rkss_info[area_index].footer = (struct rkss_file_footer *)(rkss_buffer[area_index] + footer_offset); + + /* Find valid from (backup0 - backup1) */ + for (i = 0; i < RKSS_BACKUP_NUM; i++) { + ret = blk_dread(dev_desc, + part_info.start + + area_index * RKSS_SECTION_COUNT * RKSS_BACKUP_NUM + + i * RKSS_SECTION_COUNT, + RKSS_SECTION_COUNT, rkss_buffer[area_index]); + if (ret != RKSS_SECTION_COUNT) { + printf("TEEC: blk_dread fail\n"); + return -1; + } + + if ((rkss_info[area_index].header->tag == RKSS_TAG) && + (rkss_info[area_index].footer->backup_count == rkss_info[area_index].header->backup_count)) { + if (max_ver < rkss_info[area_index].header->backup_count) { + max_index = i; + max_ver = rkss_info[area_index].header->backup_count; + } + } + } + + if (max_ver) { + debug("TEEC: max_ver=%d, max_index=%d.\n", + max_ver, max_index); + + if (max_index != (RKSS_BACKUP_NUM - 1)) { + ret = blk_dread(dev_desc, + part_info.start + + area_index * RKSS_SECTION_COUNT * RKSS_BACKUP_NUM + + max_index * RKSS_SECTION_COUNT, + RKSS_SECTION_COUNT, rkss_buffer[area_index]); + if (ret != RKSS_SECTION_COUNT) { + printf("TEEC: blk_dread fail\n"); + return -1; + } + } + + if (rkss_info[area_index].header->version == RKSS_VERSION_V2) { + debug("TEEC: data version equal to image version, do nothing!\n"); + } else if (rkss_info[area_index].header->version < RKSS_VERSION_V2) { + printf("TEEC: data version lower than image version!\n"); + /* convert rkss version 2 to higher rkss version */ + free(rkss_buffer[area_index]); + rkss_buffer[area_index] = NULL; + return -1; + } else { + printf("TEEC: data version higher than image version!\n"); + printf("TEEC: please update image!\n"); + free(rkss_buffer[area_index]); + rkss_buffer[area_index] = NULL; + return -1; + } + } else { + printf("TEEC: Reset area[%d] info...\n", area_index); + memset(rkss_buffer[area_index], 0, size); + rkss_info[area_index].header->tag = RKSS_TAG; + rkss_info[area_index].header->version = RKSS_VERSION_V2; + rkss_info[area_index].header->backup_count = 1; + rkss_info[area_index].footer->backup_count = 1; + /* Verify Usedflags Section */ + if (rkss_verify_usedflags(area_index) < 0) { + printf("TEEC: rkss_verify_usedflags fail !\n"); + return -1; + } + } + } + return 0; +} + +static int tee_fs_open(struct tee_fs_rpc *fsrpc) +{ + int make_newfile = 0; + char *filename = (char *)(fsrpc + 1); + struct rkss_file_table p = {0}; + int ret; + unsigned int area_index; + + if (strlen(filename) > RKSS_NAME_MAX_LENGTH) { + debug("TEEC: %s: file name too long. %s\n", __func__, filename); + return -1; + } + + debug("TEEC: %s open file: %s, len: %zu\n", + __func__, filename, strlen(filename)); + + ret = rkss_get_fileinfo_by_name(filename, &p, &area_index); + if (ret < 0) { + debug("TEEC: %s : no such file. %s\n", __func__, filename); + make_newfile = 1; + } else { + fsrpc->fd = ret; + file_seek = 0; + if (CHECKFLAG(fsrpc->flags, TEE_FS_O_APPEND)) + file_seek = p.size; + } + + if (make_newfile) { + if (CHECKFLAG(fsrpc->flags, TEE_FS_O_CREAT)) { + debug("TEEC: %s create new file: %s\n", + __func__, filename); + strcpy(p.name, filename); + p.index = 0; + p.size = 0; + p.used = 1; + p.flags = RK_FS_R | RK_FS_W; + ret = rkss_write_empty_ptable(&p); + if (ret < 0) { + printf("TEEC: %s : error. %s\n", + __func__, filename); + return -1; + } + fsrpc->fd = ret; + file_seek = 0; + } else { + debug("TEEC: and no create flag found.\n"); + return -1; + } + } + + debug("TEEC: %s ! %s , fd:%d, flag: %x, len: %d\n", + __func__, filename, fsrpc->fd, fsrpc->flags, fsrpc->len); + + return fsrpc->fd; +} + +static int tee_fs_close(struct tee_fs_rpc *fsrpc) +{ + debug("TEEC: %s !\n", __func__); + + UNREFERENCED_PARAMETER(fsrpc); + return 0; +} + +static int tee_fs_read(struct tee_fs_rpc *fsrpc) +{ + void *data = (void *)(fsrpc + 1); + struct rkss_file_table p = {0}; + int ret, num, di; + uint8_t *temp_file_data; + unsigned int area_index; + + debug("TEEC: %s! fd:%d, len:%d\n", __func__, fsrpc->fd, fsrpc->len); + + ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p, &area_index); + if (ret < 0) { + printf("TEEC: unavailable fd !\n"); + return -1; + } + + if (file_seek != 0) + printf("TEEC: warning !!! file_seek != 0. unsupported now.\n"); + + num = fsrpc->len / RKSS_DATA_LEN + 1; + di = 0; + debug("TEEC: reading section[%d], fd:%d, len:%d, filesize:%d\n", + p.index, fsrpc->fd, fsrpc->len, p.size); + + temp_file_data = malloc(num * RKSS_DATA_LEN); + ret = rkss_read_multi_sections(area_index, temp_file_data, p.index, num); + if (ret < 0) { + printf("TEEC: unavailable file index\n"); + free(temp_file_data); + return -1; + } + di = fsrpc->len > p.size ? p.size : fsrpc->len; + memcpy(data, temp_file_data, di); + free(temp_file_data); + temp_file_data = 0; + return di; +} + +static int tee_fs_write(struct tee_fs_rpc *fsrpc) +{ + void *data = (void *)(fsrpc + 1); + struct rkss_file_table p = {0}; + int ret, num; + uint8_t *temp_file_data; + unsigned int area_index; + + debug("TEEC: %s ! fd:%d, lenth:%d\n", __func__, fsrpc->fd, fsrpc->len); + + if (fsrpc->fd < 0) { + printf("TEEC: %s error ! wrong fd : %d\n", __func__, fsrpc->fd); + return -1; + } + + if (file_seek != 0) + printf("TEEC: warning !!! file_seek != 0. unsupported now.\n"); + + ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p, &area_index); + if (ret < 0) { + printf("TEEC: %s: fd unvailable!\n", __func__); + return -1; + } + + if (p.size != 0) { + num = p.size / RKSS_DATA_LEN + 1; + ret = rkss_decref_multi_usedflags_sections(area_index, p.index, num); + if (ret < 0) { + printf("TEEC: rkss decref usedflags error !\n"); + return -1; + } + } + + p.size = fsrpc->len; + num = fsrpc->len / RKSS_DATA_LEN + 1; + p.index = rkss_get_empty_section_from_usedflags(area_index, num); + debug("TEEC: Get Empty section in %d\n", p.index); + p.used = 1; + + ret = rkss_incref_multi_usedflags_sections(area_index, p.index, num); + if (ret < 0) { + printf("TEEC: rkss_incref_multi_usedflags_sections error !\n"); + ret = -1; + } + + ret = rkss_write_back_ptable(fsrpc->fd, &p); + if (ret < 0) { + printf("TEEC: %s: write ptable error!\n", __func__); + return -1; + } + + temp_file_data = malloc(num * RKSS_DATA_LEN); + if (temp_file_data == NULL) { + printf("TEEC: Malloc failed!\n"); + return -1; + } + memset(temp_file_data, 0, num * RKSS_DATA_LEN); + memcpy(temp_file_data, data, p.size); + rkss_write_multi_sections(area_index, temp_file_data, p.index, num); + free(temp_file_data); + temp_file_data = 0; + + return fsrpc->len; +} + +static int tee_fs_seek(struct tee_fs_rpc *fsrpc) +{ + struct rkss_file_table p = {0}; + int ret; + unsigned int area_index; + + debug("TEEC: %s ! fd:%d, seek:%d, flag:%x\n", + __func__, fsrpc->fd, fsrpc->arg, fsrpc->flags); + + if (fsrpc->flags == TEE_FS_SEEK_CUR) { + fsrpc->res = file_seek + fsrpc->arg; + } else if (fsrpc->flags == TEE_FS_SEEK_SET) { + file_seek = fsrpc->arg; + fsrpc->res = file_seek; + } else if (fsrpc->flags == TEE_FS_SEEK_END) { + ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p, &area_index); + if (ret < 0) { + printf("TEEC: unavilable fd.\n"); + return -1; + } + file_seek = p.size + fsrpc->arg; + fsrpc->res = file_seek; + } else { + printf("TEEC: %s: unsupport seed mode.\n", __func__); + return -1; + } + + return fsrpc->res; +} + +static int tee_fs_unlink(struct tee_fs_rpc *fsrpc) +{ + char *filename = (char *)(fsrpc + 1); + struct rkss_file_table p = {0}; + int ret, fd, num; + unsigned int area_index; + + fd = rkss_get_fileinfo_by_name(filename, &p, &area_index); + if (fd < 0) { + printf("TEEC: %s : no such file. %s\n", __func__, filename); + return 0; + } + + debug("TEEC: %s ! %s fd:%d index:%d size:%d\n", + __func__, filename, fd, p.index, p.size); + + /* decrease ref from usedflags */ + num = p.size / RKSS_DATA_LEN + 1; + ret = rkss_decref_multi_usedflags_sections(area_index, p.index, num); + if (ret < 0) { + printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); + return -1; + } + + /* rm from ptable */ + memset(&p, 0, sizeof(struct rkss_file_table)); + ret = rkss_write_back_ptable(fd, &p); + if (ret < 0) { + printf("TEEC: %s : write back error %d\n", __func__, ret); + return -1; + } + + return 0; +} + +static int tee_fs_link(struct tee_fs_rpc *fsrpc) +{ + char *filename = (char *)(fsrpc + 1); + size_t offset_new_fn = strlen(filename) + 1; + char *newfilename = filename + offset_new_fn; + struct rkss_file_table p_old = {0}; + struct rkss_file_table p_check = {0}; + struct rkss_file_table p_new = {0}; + int ret, num; + unsigned int old_area, new_area; + + debug("TEEC: %s ! %s -> %s\n", __func__, filename, newfilename); + + ret = rkss_get_fileinfo_by_name(filename, &p_old, &old_area); + if (ret < 0) { + printf("TEEC: cannot find src file %s.\n", filename); + return -1; + } + + ret = rkss_get_fileinfo_by_name(newfilename, &p_check, &new_area); + if (ret >= 0) { + printf("TEEC: file exist ! %s.\n", newfilename); + return -1; + } + + memcpy(&p_new, &p_old, sizeof(struct rkss_file_table)); + strcpy(p_new.name, newfilename); + ret = rkss_write_area_empty_ptable(old_area, &p_new); + if (ret < 0) { + printf("TEEC: tee_fs_open : error. %s\n", filename); + return -1; + } + + num = p_new.size / RKSS_DATA_LEN + 1; + ret = rkss_incref_multi_usedflags_sections(old_area, p_new.index, num); + if (ret < 0) { + printf("TEEC: rkss_incref_multi_usedflags_sections error !\n"); + return -1; + } + + return 0; +} + +static int tee_fs_rename(struct tee_fs_rpc *fsrpc) +{ + char *filenames = (char *)(fsrpc + 1); + char *newnames = filenames + strlen(filenames) + 1; + struct rkss_file_table p = {0}; + int ret; + unsigned int area_index; + + debug("TEEC: rename: %s -> %s\n", filenames, newnames); + + ret = rkss_get_fileinfo_by_name(filenames, &p, &area_index); + if (ret < 0) { + printf("TEEC: filename no found .\n"); + return -1; + } + + strcpy(p.name, newnames); + + ret = rkss_write_back_ptable(ret, &p); + if (ret < 0) { + printf("TEEC: write ptable error!\n"); + return -1; + } + + return 0; +} + +static int tee_fs_truncate(struct tee_fs_rpc *fsrpc) +{ + int section_num, new_section_num, free_section_num; + uint16_t free_index; + struct rkss_file_table p = {0}; + int ret; + unsigned int area_index; + + debug("TEEC: %s: fd:%d, lenth:%d\n", + __func__, fsrpc->fd, fsrpc->arg); + if (fsrpc->fd < 0) { + printf("TEEC: %s: fd unavilable !\n", __func__); + return -1; + } + + ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p, &area_index); + if (ret < 0) { + printf("TEEC: fd unvailable!\n"); + return -1; + } + + if (p.size < fsrpc->arg) { + printf("TEEC: truncate size not support!\n "); + return -1; + } else { + section_num = p.size / RKSS_DATA_LEN + 1; + new_section_num = fsrpc->arg / RKSS_DATA_LEN + 1; + free_section_num = section_num - new_section_num; + free_index = p.index + new_section_num; + ret = rkss_decref_multi_usedflags_sections(area_index, free_index, free_section_num); + if (ret < 0) { + printf("TEEC: rkss decref usedflags error!\n"); + return -1; + } + p.size = fsrpc->arg; + ret = rkss_write_back_ptable(fsrpc->fd, &p); + if (ret < 0) { + printf("TEEC: rkss_write_back_ptable error!\n"); + return -1; + } + } + + return 0; +} + +static int tee_fs_mkdir(struct tee_fs_rpc *fsrpc) +{ + char *dirname = (char *)(fsrpc + 1); + + UNREFERENCED_PARAMETER(dirname); + debug("TEEC: %s: %s\n", __func__, dirname); + return 0; +} + +static int tee_fs_opendir(struct tee_fs_rpc *fsrpc) +{ + char *dirname = (char *)(fsrpc + 1); + int ret; + + dir_seek = 0; + ret = rkss_get_dirs_by_name(dirname); + if (ret < 0) + printf("TEEC: %s: error\n", __func__); + + debug("TEEC: %s: %s, seek/num:%d/%d\n", __func__, + dirname, dir_seek, dir_num); + return 0; +} + +static int tee_fs_closedir(struct tee_fs_rpc *fsrpc) +{ + char *dirname = (char *)(fsrpc + 1); + + UNREFERENCED_PARAMETER(dirname); + debug("TEEC: %s: %s\n", __func__, dirname); + dir_seek = 0; + dir_num = 0; + return 0; +} + +static int tee_fs_readdir(struct tee_fs_rpc *fsrpc) +{ + char *dirname = (char *)(fsrpc + 1); + + debug("TEEC: seek/num:%d/%d\n", dir_seek, dir_num); + if (dir_seek == dir_num) { + dirname = NULL; + fsrpc->len = 0; + debug("TEEC: %s: END\n", __func__); + return -1; + } + + strcpy(dirname, dir_cache[dir_seek]); + fsrpc->len = strlen(dir_cache[dir_seek]) + 1; + ++dir_seek; + + debug("TEEC: %s: %s\n", __func__, dirname); + return 0; +} + +static int tee_fs_rmdir(struct tee_fs_rpc *fsrpc) +{ + char *dirname = (char *)(fsrpc + 1); + struct rkss_file_table p = {0}; + int ret; + unsigned int area_index; + + debug("TEEC: %s: %s\n", __func__, dirname); + + ret = rkss_get_fileinfo_by_name(dirname, &p, &area_index); + if (ret == -100) { + printf("TEEC: dir is not empty.\n"); + return -1; + } else if (ret >= 0) { + printf("TEEC: %s is not a dir.\n", p.name); + return -1; + } + debug("TEEC: rmdir success.\n"); + return 0; +} + +static int tee_fs_access(struct tee_fs_rpc *fsrpc) +{ + char *filename = (char *)(fsrpc + 1); + struct rkss_file_table p = {0}; + int ret; + unsigned int area_index; + + debug("TEEC: %s: name:%s,flag:%x\n", + __func__, filename, fsrpc->flags); + + ret = rkss_get_fileinfo_by_name(filename, &p, &area_index); + if (ret < 0 && ret != -100) { + debug("TEEC: %s: %s no such file or directory.\n", + __func__, filename); + return -1; + } + + if (CHECKFLAG(fsrpc->flags, TEE_FS_R_OK)) { + if (!CHECKFLAG(p.flags, RK_FS_R)) { + printf("TEEC: %s: no permission FS_R_OK in %x.\n", + __func__, p.flags); + return -1; + } + } + + if (CHECKFLAG(fsrpc->flags, TEE_FS_W_OK)) { + if (!CHECKFLAG(p.flags, RK_FS_W)) { + printf("TEEC: %s: no permission FS_W_OK in %x.\n", + __func__, p.flags); + return -1; + } + } + return 0; +} + +int tee_supp_rk_fs_init_v2(void) +{ + assert(sizeof(struct rkss_file_table) == RKSS_TABLE_SIZE); + assert(RKSS_DATA_LEN / sizeof(struct rkss_file_table) == + RKSS_EACH_FILEFOLDER_COUNT); + + if (check_security_exist(0) < 0) + return 0; + + /* clean secure storage */ +#ifdef DEBUG_CLEAN_RKSS + if (rkss_storage_reset() < 0) + return -1; +#endif + + for (uint32_t i = 0; i < RKSS_ACTIVE_AREA_NUM; i++) { + if (rkss_storage_init(i) < 0) + return -1; + } + +#ifdef DEBUG_RKSS + rkss_dump_ptable(); + rkss_dump_usedflags(); +#endif + + return 0; +} + +static int rkss_step; +int tee_supp_rk_fs_process_v2(void *cmd, size_t cmd_size) +{ + struct tee_fs_rpc *fsrpc = cmd; + int ret = -1; + + if (check_security_exist(0) < 0) { + printf("TEEC: security partition not exist! unable to use RK FS!\n"); + return ret; + } + + if (cmd_size < sizeof(struct tee_fs_rpc)) { + printf(">>>cmd_size < sizeof(struct tee_fs_rpc) !\n"); + return ret; + } + + if (cmd == NULL) { + printf(">>>cmd == NULL !\n"); + return ret; + } + + switch (fsrpc->op) { + case TEE_FS_OPEN: + debug(">>>>>>> [%d] TEE_FS_OPEN !\n", rkss_step++); + ret = tee_fs_open(fsrpc); + break; + case TEE_FS_CLOSE: + debug(">>>>>>> [%d] TEE_FS_CLOSE !\n", rkss_step++); + ret = tee_fs_close(fsrpc); + rkss_storage_write(); + break; + case TEE_FS_READ: + debug(">>>>>>> [%d] TEE_FS_READ !\n", rkss_step++); + ret = tee_fs_read(fsrpc); + break; + case TEE_FS_WRITE: + debug(">>>>>>> [%d] TEE_FS_WRITE !\n", rkss_step++); + ret = tee_fs_write(fsrpc); + break; + case TEE_FS_SEEK: + debug(">>>>>>> [%d] TEE_FS_SEEK !\n", rkss_step++); + ret = tee_fs_seek(fsrpc); + break; + case TEE_FS_UNLINK: + debug(">>>>>>> [%d] TEE_FS_UNLINK !\n", rkss_step++); + ret = tee_fs_unlink(fsrpc); + rkss_storage_write(); + break; + case TEE_FS_RENAME: + debug(">>>>>>> [%d] TEE_FS_RENAME !\n", rkss_step++); + ret = tee_fs_rename(fsrpc); + rkss_storage_write(); + break; + case TEE_FS_TRUNC: + debug(">>>>>>> [%d] TEE_FS_TRUNC !\n", rkss_step++); + ret = tee_fs_truncate(fsrpc); + break; + case TEE_FS_MKDIR: + debug(">>>>>>> [%d] TEE_FS_MKDIR !\n", rkss_step++); + ret = tee_fs_mkdir(fsrpc); + break; + case TEE_FS_OPENDIR: + debug(">>>>>>> [%d] TEE_FS_OPENDIR !\n", rkss_step++); + ret = tee_fs_opendir(fsrpc); + break; + case TEE_FS_CLOSEDIR: + debug(">>>>>>> [%d] TEE_FS_CLOSEDIR !\n", rkss_step++); + ret = tee_fs_closedir(fsrpc); + break; + case TEE_FS_READDIR: + debug(">>>>>>> [%d] TEE_FS_READDIR !\n", rkss_step++); + ret = tee_fs_readdir(fsrpc); + break; + case TEE_FS_RMDIR: + debug(">>>>>>> [%d] TEE_FS_RMDIR !\n", rkss_step++); + ret = tee_fs_rmdir(fsrpc); + break; + case TEE_FS_ACCESS: + debug(">>>>>>> [%d] TEE_FS_ACCESS !\n", rkss_step++); + ret = tee_fs_access(fsrpc); + break; + case TEE_FS_LINK: + debug(">>>>>>> [%d] TEE_FS_LINK !\n", rkss_step++); + ret = tee_fs_link(fsrpc); + rkss_storage_write(); + break; + default: + printf(">>>>> DEFAULT !! %d\n", fsrpc->op); + break; + } + + fsrpc->res = ret; + debug(">>>>>>> fsrpc->res = [%d] !\n", fsrpc->res); + + return ret; +}