1*d079c1a5SHisping Lin /* 2*d079c1a5SHisping Lin * Copyright 2020, Rockchip Electronics Co., Ltd 3*d079c1a5SHisping Lin * hisping lin, <hisping.lin@rock-chips.com> 4*d079c1a5SHisping Lin * 5*d079c1a5SHisping Lin * SPDX-License-Identifier: GPL-2.0+ 6*d079c1a5SHisping Lin */ 7*d079c1a5SHisping Lin 8*d079c1a5SHisping Lin #include <common.h> 9*d079c1a5SHisping Lin #include <stdlib.h> 10*d079c1a5SHisping Lin #include <command.h> 11*d079c1a5SHisping Lin #include <boot_rkimg.h> 12*d079c1a5SHisping Lin #include <part.h> 13*d079c1a5SHisping Lin #include <optee_include/OpteeClientRkFs.h> 14*d079c1a5SHisping Lin 15*d079c1a5SHisping Lin //#define DEBUG_RKSS 16*d079c1a5SHisping Lin //#define DEBUG_CLEAN_RKSS 17*d079c1a5SHisping Lin 18*d079c1a5SHisping Lin /* 19*d079c1a5SHisping Lin * RK Secure Storage Ctrl 20*d079c1a5SHisping Lin * Storage Size : 512 kb 21*d079c1a5SHisping Lin * Header Size : 8 byte * 2 for each top of 512 byte 22*d079c1a5SHisping Lin * Partision Table Size : 128 * 512 b (24 Files And Folder) 23*d079c1a5SHisping Lin * File number: 128 * 4 = 512 24*d079c1a5SHisping Lin * Data Size : 895 * 512 b 25*d079c1a5SHisping Lin * 26*d079c1a5SHisping Lin * ------ RKSS Structure -------- 27*d079c1a5SHisping Lin * - 512 byte patition table1 [0] 28*d079c1a5SHisping Lin * - 126 * 4 = 504 byte table info 29*d079c1a5SHisping Lin * - 8 byte verification 30*d079c1a5SHisping Lin * - 512 byte patition table2 [1] 31*d079c1a5SHisping Lin * ... 32*d079c1a5SHisping Lin * - 512 byte patition table128 [127] 33*d079c1a5SHisping Lin * - 512 byte section used refs [128] 34*d079c1a5SHisping Lin * - 1 byte = 2 flag 35*d079c1a5SHisping Lin * - 895 * 512 byte data [129 - 1023] 36*d079c1a5SHisping Lin * ------ RKSS Backup Structure -------- 37*d079c1a5SHisping Lin * - 512 byte backup header [1024] 38*d079c1a5SHisping Lin * - 1 * rkss_backup_verification + 31 * rkss_backup_info 39*d079c1a5SHisping Lin * - 255 * 512 byte backup data [1025 - 1279] 40*d079c1a5SHisping Lin * 41*d079c1a5SHisping Lin */ 42*d079c1a5SHisping Lin #define RKSS_DATA_SECTION_COUNT 1024 43*d079c1a5SHisping Lin #define RKSS_DATA_SECTION_LEN 512 44*d079c1a5SHisping Lin #define RKSS_PARTITION_TABLE_COUNT 128 // total size 512 * 128 45*d079c1a5SHisping Lin #define RKSS_EACH_SECTION_FILECOUNT 4 // 504 / 126 = 4 46*d079c1a5SHisping Lin #define RKSS_MAX_NAME_LENGTH 117 // 116 char + "\0" 47*d079c1a5SHisping Lin #define RKSS_USED_FLAGS_INDEX RKSS_PARTITION_TABLE_COUNT 48*d079c1a5SHisping Lin #define RKSS_BACKUP_INDEX RKSS_DATA_SECTION_COUNT 49*d079c1a5SHisping Lin #define RKSS_BACKUP_COUNT 256 50*d079c1a5SHisping Lin 51*d079c1a5SHisping Lin #define RKSS_BACKUP_VERSION (unsigned int)0x1 52*d079c1a5SHisping Lin #define RKSS_BACKUP_ENABLE (unsigned int)0x55667788 53*d079c1a5SHisping Lin #define RKSS_BACKUP_USEDFLAG (unsigned int)0xAABBCCDD 54*d079c1a5SHisping Lin 55*d079c1a5SHisping Lin struct rkss_backup_verification { 56*d079c1a5SHisping Lin unsigned int backup_version; 57*d079c1a5SHisping Lin unsigned int backup_count; 58*d079c1a5SHisping Lin unsigned int reserve; 59*d079c1a5SHisping Lin unsigned int backup_enable; 60*d079c1a5SHisping Lin }; 61*d079c1a5SHisping Lin 62*d079c1a5SHisping Lin struct rkss_backup_info { 63*d079c1a5SHisping Lin unsigned int backup_index; 64*d079c1a5SHisping Lin unsigned int backup_num; 65*d079c1a5SHisping Lin unsigned int backup_data_index; 66*d079c1a5SHisping Lin unsigned int backup_usedflag; 67*d079c1a5SHisping Lin }; 68*d079c1a5SHisping Lin 69*d079c1a5SHisping Lin typedef struct rkss_file_info { 70*d079c1a5SHisping Lin uint8_t used; 71*d079c1a5SHisping Lin char name[RKSS_MAX_NAME_LENGTH]; 72*d079c1a5SHisping Lin uint16_t index; // from 129 to 1024 73*d079c1a5SHisping Lin uint16_t size; // size of data 74*d079c1a5SHisping Lin uint16_t father; 75*d079c1a5SHisping Lin uint8_t id; // file folder count index 76*d079c1a5SHisping Lin uint8_t flags; 77*d079c1a5SHisping Lin } rkss_file_info; // 126 byte for each 78*d079c1a5SHisping Lin 79*d079c1a5SHisping Lin #define RKSS_CHECK_STR (uint32_t)0x12345678 80*d079c1a5SHisping Lin #define RKSS_CHECK_PT (uint8_t)0xFC 81*d079c1a5SHisping Lin typedef struct rkss_file_verification { 82*d079c1a5SHisping Lin uint32_t version; 83*d079c1a5SHisping Lin uint32_t checkstr; 84*d079c1a5SHisping Lin } rkss_file_verification; // 8 byte 85*d079c1a5SHisping Lin 86*d079c1a5SHisping Lin typedef struct rk_secure_storage { 87*d079c1a5SHisping Lin unsigned long index; 88*d079c1a5SHisping Lin unsigned char data[RKSS_DATA_SECTION_LEN]; 89*d079c1a5SHisping Lin } rk_secure_storage; 90*d079c1a5SHisping Lin 91*d079c1a5SHisping Lin /* RK Secure Storage Calls */ 92*d079c1a5SHisping Lin static int file_seek; 93*d079c1a5SHisping Lin static char dir_cache[RKSS_MAX_NAME_LENGTH][12]; 94*d079c1a5SHisping Lin static int dir_num; 95*d079c1a5SHisping Lin static int dir_seek; 96*d079c1a5SHisping Lin 97*d079c1a5SHisping Lin static struct blk_desc *dev_desc; 98*d079c1a5SHisping Lin static disk_partition_t part_info; 99*d079c1a5SHisping Lin 100*d079c1a5SHisping Lin static int check_security_exist(int print_flag) 101*d079c1a5SHisping Lin { 102*d079c1a5SHisping Lin if (!dev_desc) { 103*d079c1a5SHisping Lin dev_desc = rockchip_get_bootdev(); 104*d079c1a5SHisping Lin if (!dev_desc) { 105*d079c1a5SHisping Lin printf("TEEC: %s: Could not find device\n", __func__); 106*d079c1a5SHisping Lin return -1; 107*d079c1a5SHisping Lin } 108*d079c1a5SHisping Lin 109*d079c1a5SHisping Lin if (part_get_info_by_name(dev_desc, 110*d079c1a5SHisping Lin "security", &part_info) < 0) { 111*d079c1a5SHisping Lin dev_desc = NULL; 112*d079c1a5SHisping Lin if (print_flag != 0) 113*d079c1a5SHisping Lin printf("TEEC: Could not find security partition\n"); 114*d079c1a5SHisping Lin return -1; 115*d079c1a5SHisping Lin } 116*d079c1a5SHisping Lin } 117*d079c1a5SHisping Lin return 0; 118*d079c1a5SHisping Lin } 119*d079c1a5SHisping Lin 120*d079c1a5SHisping Lin /* 121*d079c1a5SHisping Lin * action1: 122*d079c1a5SHisping Lin * rkss_begin_commit set enable flag 123*d079c1a5SHisping Lin * rkss_backup_sections backup data 124*d079c1a5SHisping Lin * blk_dwrite 125*d079c1a5SHisping Lin * rkss_finish_commit clear enable flag, clear backup data 126*d079c1a5SHisping Lin * reboot 127*d079c1a5SHisping Lin * rkss_resume not find enable flag, do nothing 128*d079c1a5SHisping Lin * 129*d079c1a5SHisping Lin * action2: 130*d079c1a5SHisping Lin * rkss_begin_commit set enable flag 131*d079c1a5SHisping Lin * rkss_backup_sections backup data 132*d079c1a5SHisping Lin * power off when blk_dwrite 133*d079c1a5SHisping Lin * 134*d079c1a5SHisping Lin * power on 135*d079c1a5SHisping Lin * rkss_resume find enable flag, resume all backup data 136*d079c1a5SHisping Lin */ 137*d079c1a5SHisping Lin static int rkss_begin_commit(void) 138*d079c1a5SHisping Lin { 139*d079c1a5SHisping Lin unsigned char data[RKSS_DATA_SECTION_LEN]; 140*d079c1a5SHisping Lin struct rkss_backup_verification p; 141*d079c1a5SHisping Lin unsigned long ret; 142*d079c1a5SHisping Lin 143*d079c1a5SHisping Lin if (check_security_exist(1) < 0) 144*d079c1a5SHisping Lin return -1; 145*d079c1a5SHisping Lin 146*d079c1a5SHisping Lin debug("TEEC: %s\n", __func__); 147*d079c1a5SHisping Lin p.backup_version = RKSS_BACKUP_VERSION; 148*d079c1a5SHisping Lin p.backup_enable = RKSS_BACKUP_ENABLE; 149*d079c1a5SHisping Lin p.backup_count = 0; 150*d079c1a5SHisping Lin 151*d079c1a5SHisping Lin memset(data, 0, sizeof(data)); 152*d079c1a5SHisping Lin memcpy(data, &p, sizeof(p)); 153*d079c1a5SHisping Lin 154*d079c1a5SHisping Lin ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data); 155*d079c1a5SHisping Lin if (ret != 1) { 156*d079c1a5SHisping Lin printf("TEEC: blk_dwrite fail\n"); 157*d079c1a5SHisping Lin return -1; 158*d079c1a5SHisping Lin } 159*d079c1a5SHisping Lin return 0; 160*d079c1a5SHisping Lin } 161*d079c1a5SHisping Lin 162*d079c1a5SHisping Lin static int rkss_finish_commit(void) 163*d079c1a5SHisping Lin { 164*d079c1a5SHisping Lin unsigned char data[RKSS_DATA_SECTION_LEN]; 165*d079c1a5SHisping Lin unsigned long ret; 166*d079c1a5SHisping Lin 167*d079c1a5SHisping Lin if (check_security_exist(1) < 0) 168*d079c1a5SHisping Lin return -1; 169*d079c1a5SHisping Lin 170*d079c1a5SHisping Lin debug("TEEC: %s\n", __func__); 171*d079c1a5SHisping Lin memset(data, 0, sizeof(data)); 172*d079c1a5SHisping Lin 173*d079c1a5SHisping Lin ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data); 174*d079c1a5SHisping Lin if (ret != 1) { 175*d079c1a5SHisping Lin printf("TEEC: blk_dwrite fail\n"); 176*d079c1a5SHisping Lin return -1; 177*d079c1a5SHisping Lin } 178*d079c1a5SHisping Lin return 0; 179*d079c1a5SHisping Lin } 180*d079c1a5SHisping Lin 181*d079c1a5SHisping Lin static int rkss_backup_sections(unsigned long index, unsigned int num) 182*d079c1a5SHisping Lin { 183*d079c1a5SHisping Lin unsigned char data[RKSS_DATA_SECTION_LEN]; 184*d079c1a5SHisping Lin unsigned char *backup_data = NULL; 185*d079c1a5SHisping Lin struct rkss_backup_verification p; 186*d079c1a5SHisping Lin struct rkss_backup_info info_last, info_current; 187*d079c1a5SHisping Lin unsigned long ret; 188*d079c1a5SHisping Lin 189*d079c1a5SHisping Lin if (check_security_exist(1) < 0) 190*d079c1a5SHisping Lin return -1; 191*d079c1a5SHisping Lin 192*d079c1a5SHisping Lin ret = blk_dread(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data); 193*d079c1a5SHisping Lin if (ret != 1) { 194*d079c1a5SHisping Lin printf("TEEC: blk_dread fail\n"); 195*d079c1a5SHisping Lin return -1; 196*d079c1a5SHisping Lin } 197*d079c1a5SHisping Lin 198*d079c1a5SHisping Lin memcpy(&p, data, sizeof(p)); 199*d079c1a5SHisping Lin if (p.backup_version == RKSS_BACKUP_VERSION && 200*d079c1a5SHisping Lin p.backup_enable == RKSS_BACKUP_ENABLE) { 201*d079c1a5SHisping Lin if (p.backup_count == 0) { 202*d079c1a5SHisping Lin info_current.backup_usedflag = RKSS_BACKUP_USEDFLAG; 203*d079c1a5SHisping Lin info_current.backup_index = index; 204*d079c1a5SHisping Lin info_current.backup_num = num; 205*d079c1a5SHisping Lin info_current.backup_data_index = RKSS_BACKUP_INDEX + 1; 206*d079c1a5SHisping Lin } else { 207*d079c1a5SHisping Lin memcpy(&info_last, 208*d079c1a5SHisping Lin data + sizeof(p) + (p.backup_count - 1) * 209*d079c1a5SHisping Lin sizeof(info_last), sizeof(info_last)); 210*d079c1a5SHisping Lin info_current.backup_usedflag = RKSS_BACKUP_USEDFLAG; 211*d079c1a5SHisping Lin info_current.backup_index = index; 212*d079c1a5SHisping Lin info_current.backup_num = num; 213*d079c1a5SHisping Lin info_current.backup_data_index = 214*d079c1a5SHisping Lin info_last.backup_data_index + 215*d079c1a5SHisping Lin info_last.backup_num; 216*d079c1a5SHisping Lin } 217*d079c1a5SHisping Lin if ((info_current.backup_data_index + info_current.backup_num) > 218*d079c1a5SHisping Lin (RKSS_BACKUP_INDEX + RKSS_BACKUP_COUNT)) { 219*d079c1a5SHisping Lin printf("TEEC: Not enough backup sections!"); 220*d079c1a5SHisping Lin goto error; 221*d079c1a5SHisping Lin } 222*d079c1a5SHisping Lin debug("TEEC: %s index=0x%lx num=0x%x backup_data_index=0x%x\n", 223*d079c1a5SHisping Lin __func__, index, num, info_current.backup_data_index); 224*d079c1a5SHisping Lin 225*d079c1a5SHisping Lin backup_data = malloc(num * RKSS_DATA_SECTION_LEN); 226*d079c1a5SHisping Lin if (!backup_data) { 227*d079c1a5SHisping Lin printf("TEEC: malloc backup_data fail\n"); 228*d079c1a5SHisping Lin goto error; 229*d079c1a5SHisping Lin } 230*d079c1a5SHisping Lin 231*d079c1a5SHisping Lin ret = blk_dread(dev_desc, part_info.start + index, num, backup_data); 232*d079c1a5SHisping Lin if (ret != num) { 233*d079c1a5SHisping Lin printf("TEEC: blk_dread fail\n"); 234*d079c1a5SHisping Lin return -1; 235*d079c1a5SHisping Lin } 236*d079c1a5SHisping Lin 237*d079c1a5SHisping Lin ret = blk_dwrite(dev_desc, part_info.start + info_current.backup_data_index, 238*d079c1a5SHisping Lin num, backup_data); 239*d079c1a5SHisping Lin if (ret != num) { 240*d079c1a5SHisping Lin printf("TEEC: blk_dwrite fail\n"); 241*d079c1a5SHisping Lin return -1; 242*d079c1a5SHisping Lin } 243*d079c1a5SHisping Lin free(backup_data); 244*d079c1a5SHisping Lin backup_data = NULL; 245*d079c1a5SHisping Lin 246*d079c1a5SHisping Lin p.backup_count += 1; 247*d079c1a5SHisping Lin 248*d079c1a5SHisping Lin memcpy(data, &p, sizeof(p)); 249*d079c1a5SHisping Lin memcpy(data + sizeof(p) + 250*d079c1a5SHisping Lin (p.backup_count - 1) * sizeof(info_current), 251*d079c1a5SHisping Lin &info_current, sizeof(info_current)); 252*d079c1a5SHisping Lin 253*d079c1a5SHisping Lin ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data); 254*d079c1a5SHisping Lin if (ret != 1) { 255*d079c1a5SHisping Lin printf("TEEC: blk_dwrite fail\n"); 256*d079c1a5SHisping Lin return -1; 257*d079c1a5SHisping Lin } 258*d079c1a5SHisping Lin } 259*d079c1a5SHisping Lin 260*d079c1a5SHisping Lin return 0; 261*d079c1a5SHisping Lin error: 262*d079c1a5SHisping Lin if (backup_data) 263*d079c1a5SHisping Lin free(backup_data); 264*d079c1a5SHisping Lin return -1; 265*d079c1a5SHisping Lin } 266*d079c1a5SHisping Lin 267*d079c1a5SHisping Lin static int rkss_resume(void) 268*d079c1a5SHisping Lin { 269*d079c1a5SHisping Lin unsigned char data[RKSS_DATA_SECTION_LEN]; 270*d079c1a5SHisping Lin unsigned char *backup_data = NULL; 271*d079c1a5SHisping Lin struct rkss_backup_verification p; 272*d079c1a5SHisping Lin struct rkss_backup_info info_current; 273*d079c1a5SHisping Lin unsigned int i; 274*d079c1a5SHisping Lin unsigned long ret; 275*d079c1a5SHisping Lin 276*d079c1a5SHisping Lin if (check_security_exist(1) < 0) 277*d079c1a5SHisping Lin return -1; 278*d079c1a5SHisping Lin 279*d079c1a5SHisping Lin ret = blk_dread(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data); 280*d079c1a5SHisping Lin if (ret != 1) { 281*d079c1a5SHisping Lin printf("TEEC: blk_dread fail\n"); 282*d079c1a5SHisping Lin return -1; 283*d079c1a5SHisping Lin } 284*d079c1a5SHisping Lin 285*d079c1a5SHisping Lin memcpy(&p, data, sizeof(p)); 286*d079c1a5SHisping Lin if (p.backup_version == RKSS_BACKUP_VERSION && 287*d079c1a5SHisping Lin p.backup_enable == RKSS_BACKUP_ENABLE) { 288*d079c1a5SHisping Lin for (i = p.backup_count; i > 0; i--) { 289*d079c1a5SHisping Lin memcpy(&info_current, data + sizeof(p) + (i - 1) * 290*d079c1a5SHisping Lin sizeof(info_current), sizeof(info_current)); 291*d079c1a5SHisping Lin 292*d079c1a5SHisping Lin if (info_current.backup_usedflag == 293*d079c1a5SHisping Lin RKSS_BACKUP_USEDFLAG) { 294*d079c1a5SHisping Lin debug("TEEC: rkss_resume backup_index=0x%x \ 295*d079c1a5SHisping Lin backup_num=0x%x \ 296*d079c1a5SHisping Lin info_current.backup_data_index=0x%x\n", 297*d079c1a5SHisping Lin info_current.backup_index, 298*d079c1a5SHisping Lin info_current.backup_num, 299*d079c1a5SHisping Lin info_current.backup_data_index); 300*d079c1a5SHisping Lin if ((info_current.backup_data_index + 301*d079c1a5SHisping Lin info_current.backup_num) > 302*d079c1a5SHisping Lin (RKSS_BACKUP_INDEX + RKSS_BACKUP_COUNT)) { 303*d079c1a5SHisping Lin printf("TEEC: backup sections error!"); 304*d079c1a5SHisping Lin goto error; 305*d079c1a5SHisping Lin } 306*d079c1a5SHisping Lin if ((info_current.backup_index + 307*d079c1a5SHisping Lin info_current.backup_num) > 308*d079c1a5SHisping Lin RKSS_DATA_SECTION_COUNT) { 309*d079c1a5SHisping Lin printf("TEEC: original sections error!"); 310*d079c1a5SHisping Lin goto error; 311*d079c1a5SHisping Lin } 312*d079c1a5SHisping Lin backup_data = malloc(info_current.backup_num * 313*d079c1a5SHisping Lin RKSS_DATA_SECTION_LEN); 314*d079c1a5SHisping Lin if (!backup_data) { 315*d079c1a5SHisping Lin printf("TEEC: malloc backup_data fail\n"); 316*d079c1a5SHisping Lin goto error; 317*d079c1a5SHisping Lin } 318*d079c1a5SHisping Lin 319*d079c1a5SHisping Lin ret = blk_dread(dev_desc, 320*d079c1a5SHisping Lin part_info.start + info_current.backup_data_index, 321*d079c1a5SHisping Lin info_current.backup_num, 322*d079c1a5SHisping Lin backup_data); 323*d079c1a5SHisping Lin if (ret != info_current.backup_num) { 324*d079c1a5SHisping Lin printf("TEEC: blk_dread fail\n"); 325*d079c1a5SHisping Lin return -1; 326*d079c1a5SHisping Lin } 327*d079c1a5SHisping Lin 328*d079c1a5SHisping Lin ret = blk_dwrite(dev_desc, 329*d079c1a5SHisping Lin part_info.start + info_current.backup_index, 330*d079c1a5SHisping Lin info_current.backup_num, 331*d079c1a5SHisping Lin backup_data); 332*d079c1a5SHisping Lin if (ret != info_current.backup_num) { 333*d079c1a5SHisping Lin printf("TEEC: blk_dwrite fail\n"); 334*d079c1a5SHisping Lin return -1; 335*d079c1a5SHisping Lin } 336*d079c1a5SHisping Lin free(backup_data); 337*d079c1a5SHisping Lin backup_data = NULL; 338*d079c1a5SHisping Lin } 339*d079c1a5SHisping Lin } 340*d079c1a5SHisping Lin } 341*d079c1a5SHisping Lin memset(data, 0, sizeof(data)); 342*d079c1a5SHisping Lin ret = blk_dwrite(dev_desc, part_info.start + RKSS_BACKUP_INDEX, 1, data); 343*d079c1a5SHisping Lin if (ret != 1) { 344*d079c1a5SHisping Lin printf("TEEC: blk_dwrite fail\n"); 345*d079c1a5SHisping Lin return -1; 346*d079c1a5SHisping Lin } 347*d079c1a5SHisping Lin return 0; 348*d079c1a5SHisping Lin error: 349*d079c1a5SHisping Lin if (backup_data) 350*d079c1a5SHisping Lin free(backup_data); 351*d079c1a5SHisping Lin return -1; 352*d079c1a5SHisping Lin } 353*d079c1a5SHisping Lin 354*d079c1a5SHisping Lin static int rkss_read_multi_sections(unsigned char *data, unsigned long index, unsigned int num) 355*d079c1a5SHisping Lin { 356*d079c1a5SHisping Lin unsigned long ret; 357*d079c1a5SHisping Lin 358*d079c1a5SHisping Lin if (check_security_exist(1) < 0) 359*d079c1a5SHisping Lin return -1; 360*d079c1a5SHisping Lin 361*d079c1a5SHisping Lin ret = blk_dread(dev_desc, part_info.start + index, num, data); 362*d079c1a5SHisping Lin if (ret != num) { 363*d079c1a5SHisping Lin printf("TEEC: blk_dread fail\n"); 364*d079c1a5SHisping Lin return -1; 365*d079c1a5SHisping Lin } 366*d079c1a5SHisping Lin return 0; 367*d079c1a5SHisping Lin } 368*d079c1a5SHisping Lin 369*d079c1a5SHisping Lin static int rkss_read_section(struct rk_secure_storage *rkss) 370*d079c1a5SHisping Lin { 371*d079c1a5SHisping Lin return rkss_read_multi_sections(rkss->data, rkss->index, 1); 372*d079c1a5SHisping Lin } 373*d079c1a5SHisping Lin 374*d079c1a5SHisping Lin static int rkss_write_multi_sections(unsigned char *data, unsigned long index, unsigned int num) 375*d079c1a5SHisping Lin { 376*d079c1a5SHisping Lin unsigned long ret; 377*d079c1a5SHisping Lin int result; 378*d079c1a5SHisping Lin 379*d079c1a5SHisping Lin result = rkss_backup_sections(index, num); 380*d079c1a5SHisping Lin if (result < 0) { 381*d079c1a5SHisping Lin printf("TEEC: rkss_backup_sections fail\n"); 382*d079c1a5SHisping Lin return -1; 383*d079c1a5SHisping Lin } 384*d079c1a5SHisping Lin 385*d079c1a5SHisping Lin if (check_security_exist(1) < 0) 386*d079c1a5SHisping Lin return -1; 387*d079c1a5SHisping Lin 388*d079c1a5SHisping Lin ret = blk_dwrite(dev_desc, part_info.start + index, num, data); 389*d079c1a5SHisping Lin if (ret != num) { 390*d079c1a5SHisping Lin printf("TEEC: blk_dwrite fail\n"); 391*d079c1a5SHisping Lin return -1; 392*d079c1a5SHisping Lin } 393*d079c1a5SHisping Lin return 0; 394*d079c1a5SHisping Lin } 395*d079c1a5SHisping Lin 396*d079c1a5SHisping Lin static int rkss_write_section(struct rk_secure_storage *rkss) 397*d079c1a5SHisping Lin { 398*d079c1a5SHisping Lin return rkss_write_multi_sections(rkss->data, rkss->index, 1); 399*d079c1a5SHisping Lin } 400*d079c1a5SHisping Lin 401*d079c1a5SHisping Lin static int rkss_read_patition_tables(unsigned char *data) 402*d079c1a5SHisping Lin { 403*d079c1a5SHisping Lin unsigned long ret; 404*d079c1a5SHisping Lin 405*d079c1a5SHisping Lin if (check_security_exist(1) < 0) 406*d079c1a5SHisping Lin return -1; 407*d079c1a5SHisping Lin 408*d079c1a5SHisping Lin ret = blk_dread(dev_desc, part_info.start, RKSS_PARTITION_TABLE_COUNT, data); 409*d079c1a5SHisping Lin if (ret != RKSS_PARTITION_TABLE_COUNT) { 410*d079c1a5SHisping Lin printf("TEEC: blk_dread fail\n"); 411*d079c1a5SHisping Lin return -1; 412*d079c1a5SHisping Lin } 413*d079c1a5SHisping Lin return 0; 414*d079c1a5SHisping Lin } 415*d079c1a5SHisping Lin 416*d079c1a5SHisping Lin #ifdef DEBUG_RKSS 417*d079c1a5SHisping Lin static void rkss_dump(void *data, unsigned int len) 418*d079c1a5SHisping Lin { 419*d079c1a5SHisping Lin char *p = (char *)data; 420*d079c1a5SHisping Lin unsigned int i = 0; 421*d079c1a5SHisping Lin printf("-------------- DUMP %d --------------\n", len); 422*d079c1a5SHisping Lin for (i = 0; i < len; i++) { 423*d079c1a5SHisping Lin printf("%02x ", *(p + i)); 424*d079c1a5SHisping Lin } 425*d079c1a5SHisping Lin printf("\n"); 426*d079c1a5SHisping Lin printf("------------- DUMP END -------------\n"); 427*d079c1a5SHisping Lin } 428*d079c1a5SHisping Lin 429*d079c1a5SHisping Lin static void rkss_dump_ptable(void) 430*d079c1a5SHisping Lin { 431*d079c1a5SHisping Lin printf("-------------- DUMP ptable --------------\n"); 432*d079c1a5SHisping Lin int i = 0, ret; 433*d079c1a5SHisping Lin unsigned char *table_data; 434*d079c1a5SHisping Lin 435*d079c1a5SHisping Lin table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 436*d079c1a5SHisping Lin if (table_data == NULL) { 437*d079c1a5SHisping Lin printf("TEEC: malloc table_data fail\n"); 438*d079c1a5SHisping Lin return; 439*d079c1a5SHisping Lin } 440*d079c1a5SHisping Lin ret = rkss_read_patition_tables(table_data); 441*d079c1a5SHisping Lin if (ret < 0) { 442*d079c1a5SHisping Lin printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 443*d079c1a5SHisping Lin free(table_data); 444*d079c1a5SHisping Lin return; 445*d079c1a5SHisping Lin } 446*d079c1a5SHisping Lin 447*d079c1a5SHisping Lin for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 448*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 449*d079c1a5SHisping Lin rkss.index = i; 450*d079c1a5SHisping Lin memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); 451*d079c1a5SHisping Lin 452*d079c1a5SHisping Lin int n ; 453*d079c1a5SHisping Lin for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { 454*d079c1a5SHisping Lin void *pdata = rkss.data; 455*d079c1a5SHisping Lin struct rkss_file_info *p = (struct rkss_file_info *)pdata; 456*d079c1a5SHisping Lin p += n; 457*d079c1a5SHisping Lin 458*d079c1a5SHisping Lin printf("[%02d][%c] %s , inx:%d, size:%d", 459*d079c1a5SHisping Lin i*RKSS_EACH_SECTION_FILECOUNT+n, p->used == 0 ? 'F':'T', p->name, 460*d079c1a5SHisping Lin p->index, p->size); 461*d079c1a5SHisping Lin } 462*d079c1a5SHisping Lin } 463*d079c1a5SHisping Lin free(table_data); 464*d079c1a5SHisping Lin printf("-------------- DUMP END --------------\n"); 465*d079c1a5SHisping Lin } 466*d079c1a5SHisping Lin 467*d079c1a5SHisping Lin static void rkss_dump_usedflags(void) 468*d079c1a5SHisping Lin { 469*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 470*d079c1a5SHisping Lin rkss.index = RKSS_USED_FLAGS_INDEX; 471*d079c1a5SHisping Lin int ret = rkss_read_section(&rkss); 472*d079c1a5SHisping Lin if (ret < 0) { 473*d079c1a5SHisping Lin printf("TEEC: rkss_read_section fail ! ret: %d.\n", ret); 474*d079c1a5SHisping Lin return; 475*d079c1a5SHisping Lin } 476*d079c1a5SHisping Lin rkss_dump(rkss.data, RKSS_DATA_SECTION_LEN); 477*d079c1a5SHisping Lin } 478*d079c1a5SHisping Lin #endif 479*d079c1a5SHisping Lin 480*d079c1a5SHisping Lin static int rkss_verify_ptable(unsigned char *table_data) 481*d079c1a5SHisping Lin { 482*d079c1a5SHisping Lin unsigned char *cp, *vp; 483*d079c1a5SHisping Lin struct rkss_file_verification *verify; 484*d079c1a5SHisping Lin int ret, i, write_table_flag = 0; 485*d079c1a5SHisping Lin 486*d079c1a5SHisping Lin for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 487*d079c1a5SHisping Lin cp = table_data + (i * RKSS_DATA_SECTION_LEN); 488*d079c1a5SHisping Lin vp = cp + RKSS_DATA_SECTION_LEN - sizeof(struct rkss_file_verification); 489*d079c1a5SHisping Lin verify = (struct rkss_file_verification *)(void *)vp; 490*d079c1a5SHisping Lin 491*d079c1a5SHisping Lin if (verify->version != RKSS_VERSION_V1 492*d079c1a5SHisping Lin || verify->checkstr != RKSS_CHECK_STR) { 493*d079c1a5SHisping Lin printf("TEEC: verify [%d] fail, cleanning ....", i); 494*d079c1a5SHisping Lin memset(cp, 0, RKSS_DATA_SECTION_LEN); 495*d079c1a5SHisping Lin verify->checkstr = RKSS_CHECK_STR; 496*d079c1a5SHisping Lin verify->version = RKSS_VERSION_V1; 497*d079c1a5SHisping Lin write_table_flag = 1; 498*d079c1a5SHisping Lin } 499*d079c1a5SHisping Lin } 500*d079c1a5SHisping Lin if (write_table_flag == 1) { 501*d079c1a5SHisping Lin ret = rkss_write_multi_sections(table_data, 0, RKSS_PARTITION_TABLE_COUNT); 502*d079c1a5SHisping Lin if (ret < 0) { 503*d079c1a5SHisping Lin printf("TEEC: rkss_write_multi_sections failed!!! ret: %d.\n", ret); 504*d079c1a5SHisping Lin return -1; 505*d079c1a5SHisping Lin } 506*d079c1a5SHisping Lin } 507*d079c1a5SHisping Lin debug("TEEC: verify ptable success.\n"); 508*d079c1a5SHisping Lin return 0; 509*d079c1a5SHisping Lin } 510*d079c1a5SHisping Lin 511*d079c1a5SHisping Lin static int rkss_verify_usedflags(struct rk_secure_storage *rkss) 512*d079c1a5SHisping Lin { 513*d079c1a5SHisping Lin uint8_t *flags = (uint8_t *)rkss->data; 514*d079c1a5SHisping Lin int i, duel, flag, n, value, ret; 515*d079c1a5SHisping Lin uint8_t *flagw; 516*d079c1a5SHisping Lin 517*d079c1a5SHisping Lin for (i = 0; i < RKSS_PARTITION_TABLE_COUNT + 1; i++) { 518*d079c1a5SHisping Lin duel = *(flags + (int)i/2); 519*d079c1a5SHisping Lin flag = i & 0x1 ? duel & 0x0F : (duel & 0xF0) >> 4; 520*d079c1a5SHisping Lin if (flag != 0x1) { 521*d079c1a5SHisping Lin debug("TEEC: init usedflags section ...\n"); 522*d079c1a5SHisping Lin memset(rkss->data, 0x00, RKSS_DATA_SECTION_LEN); 523*d079c1a5SHisping Lin for (n = 0; n < RKSS_PARTITION_TABLE_COUNT + 1; n++) { 524*d079c1a5SHisping Lin flagw = (uint8_t *)rkss->data + (int)n/2; 525*d079c1a5SHisping Lin value = 0x1; 526*d079c1a5SHisping Lin *flagw = n & 0x1 ? (*flagw & 0xF0) | (value & 0x0F) : 527*d079c1a5SHisping Lin (*flagw & 0x0F) | (value << 4); 528*d079c1a5SHisping Lin } 529*d079c1a5SHisping Lin ret = rkss_write_multi_sections(rkss->data, rkss->index, 1); 530*d079c1a5SHisping Lin if (ret < 0) { 531*d079c1a5SHisping Lin printf("TEEC: clean usedflags section failed!!! ret: %d.\n", ret); 532*d079c1a5SHisping Lin return -1; 533*d079c1a5SHisping Lin } 534*d079c1a5SHisping Lin 535*d079c1a5SHisping Lin return 0; 536*d079c1a5SHisping Lin } 537*d079c1a5SHisping Lin } 538*d079c1a5SHisping Lin debug("TEEC: rkss_verify_usedflags: sucess.\n"); 539*d079c1a5SHisping Lin return 0; 540*d079c1a5SHisping Lin } 541*d079c1a5SHisping Lin 542*d079c1a5SHisping Lin static int rkss_get_fileinfo_by_index(int fd, struct rkss_file_info *pfileinfo) 543*d079c1a5SHisping Lin { 544*d079c1a5SHisping Lin int i = fd / RKSS_EACH_SECTION_FILECOUNT; 545*d079c1a5SHisping Lin int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i); 546*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 547*d079c1a5SHisping Lin int ret; 548*d079c1a5SHisping Lin void *pdata; 549*d079c1a5SHisping Lin struct rkss_file_info *p; 550*d079c1a5SHisping Lin 551*d079c1a5SHisping Lin rkss.index = i; 552*d079c1a5SHisping Lin ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 553*d079c1a5SHisping Lin if (ret < 0) { 554*d079c1a5SHisping Lin printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 555*d079c1a5SHisping Lin return -1; 556*d079c1a5SHisping Lin } 557*d079c1a5SHisping Lin 558*d079c1a5SHisping Lin pdata = rkss.data; 559*d079c1a5SHisping Lin p = (struct rkss_file_info *)pdata; 560*d079c1a5SHisping Lin p += n; 561*d079c1a5SHisping Lin 562*d079c1a5SHisping Lin if (p->used != 1) { 563*d079c1a5SHisping Lin debug("TEEC: error: unused section!\n"); 564*d079c1a5SHisping Lin return -1; 565*d079c1a5SHisping Lin } 566*d079c1a5SHisping Lin debug("TEEC: rkss_get_fileinfo_by_index p->used = %d p->name=%s p->index=%d p->size=%d\n", 567*d079c1a5SHisping Lin p->used, p->name, p->index, p->size); 568*d079c1a5SHisping Lin memcpy(pfileinfo, p, sizeof(struct rkss_file_info)); 569*d079c1a5SHisping Lin 570*d079c1a5SHisping Lin return 0; 571*d079c1a5SHisping Lin } 572*d079c1a5SHisping Lin 573*d079c1a5SHisping Lin static int rkss_get_fileinfo_by_name( 574*d079c1a5SHisping Lin char *filename, struct rkss_file_info *pfileinfo) 575*d079c1a5SHisping Lin { 576*d079c1a5SHisping Lin int i = 0, ret; 577*d079c1a5SHisping Lin uint8_t n = 0; 578*d079c1a5SHisping Lin unsigned int len; 579*d079c1a5SHisping Lin unsigned char *table_data; 580*d079c1a5SHisping Lin 581*d079c1a5SHisping Lin len = strlen(filename); 582*d079c1a5SHisping Lin if (len > RKSS_MAX_NAME_LENGTH - 1) { 583*d079c1a5SHisping Lin printf("TEEC: filename is too long. length:%u\n", len); 584*d079c1a5SHisping Lin return -1; 585*d079c1a5SHisping Lin } 586*d079c1a5SHisping Lin 587*d079c1a5SHisping Lin table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 588*d079c1a5SHisping Lin if (table_data == NULL) { 589*d079c1a5SHisping Lin printf("TEEC: malloc table_data fail\n"); 590*d079c1a5SHisping Lin return -1; 591*d079c1a5SHisping Lin } 592*d079c1a5SHisping Lin ret = rkss_read_patition_tables(table_data); 593*d079c1a5SHisping Lin if (ret < 0) { 594*d079c1a5SHisping Lin printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 595*d079c1a5SHisping Lin free(table_data); 596*d079c1a5SHisping Lin return -1; 597*d079c1a5SHisping Lin } 598*d079c1a5SHisping Lin 599*d079c1a5SHisping Lin for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 600*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 601*d079c1a5SHisping Lin rkss.index = i; 602*d079c1a5SHisping Lin memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); 603*d079c1a5SHisping Lin 604*d079c1a5SHisping Lin for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { 605*d079c1a5SHisping Lin void *pdata = rkss.data; 606*d079c1a5SHisping Lin struct rkss_file_info *p = (struct rkss_file_info *)pdata; 607*d079c1a5SHisping Lin p += n; 608*d079c1a5SHisping Lin 609*d079c1a5SHisping Lin if (p->used == 0) 610*d079c1a5SHisping Lin continue; 611*d079c1a5SHisping Lin 612*d079c1a5SHisping Lin if (!strcmp(p->name, filename)) { 613*d079c1a5SHisping Lin debug("TEEC: rkss_get_fileinfo_by_name: hit table[%d/%d], index[%d/%d]\n", 614*d079c1a5SHisping Lin i, RKSS_PARTITION_TABLE_COUNT, n, RKSS_EACH_SECTION_FILECOUNT); 615*d079c1a5SHisping Lin memcpy(pfileinfo, p, sizeof(struct rkss_file_info)); 616*d079c1a5SHisping Lin free(table_data); 617*d079c1a5SHisping Lin return i * RKSS_EACH_SECTION_FILECOUNT + n; 618*d079c1a5SHisping Lin } 619*d079c1a5SHisping Lin 620*d079c1a5SHisping Lin // Folder Matching 621*d079c1a5SHisping Lin const char *split = "/"; 622*d079c1a5SHisping Lin char *last_inpos = filename; 623*d079c1a5SHisping Lin char *last_svpos = p->name; 624*d079c1a5SHisping Lin char *cur_inpos = NULL; 625*d079c1a5SHisping Lin char *cur_svpos = NULL; 626*d079c1a5SHisping Lin do { 627*d079c1a5SHisping Lin cur_inpos = strstr(last_inpos, split); 628*d079c1a5SHisping Lin cur_svpos = strstr(last_svpos, split); 629*d079c1a5SHisping Lin int size_in = cur_inpos == NULL ? 630*d079c1a5SHisping Lin (int)strlen(last_inpos) : cur_inpos - last_inpos; 631*d079c1a5SHisping Lin int size_sv = cur_svpos == NULL ? 632*d079c1a5SHisping Lin (int)strlen(last_svpos) : cur_svpos - last_svpos; 633*d079c1a5SHisping Lin 634*d079c1a5SHisping Lin ret = memcmp(last_inpos, last_svpos, size_in); 635*d079c1a5SHisping Lin 636*d079c1a5SHisping Lin last_inpos = cur_inpos + 1; 637*d079c1a5SHisping Lin last_svpos = cur_svpos + 1; 638*d079c1a5SHisping Lin 639*d079c1a5SHisping Lin if (size_in != size_sv || ret) 640*d079c1a5SHisping Lin goto UNMATCHFOLDER; 641*d079c1a5SHisping Lin 642*d079c1a5SHisping Lin } while (cur_inpos && cur_svpos); 643*d079c1a5SHisping Lin 644*d079c1a5SHisping Lin debug("TEEC: Matched folder: %s\n", p->name); 645*d079c1a5SHisping Lin free(table_data); 646*d079c1a5SHisping Lin return -100; 647*d079c1a5SHisping Lin UNMATCHFOLDER: 648*d079c1a5SHisping Lin debug("TEEC: Unmatched ..."); 649*d079c1a5SHisping Lin } 650*d079c1a5SHisping Lin } 651*d079c1a5SHisping Lin debug("TEEC: rkss_get_fileinfo_by_name: file or dir no found!\n"); 652*d079c1a5SHisping Lin free(table_data); 653*d079c1a5SHisping Lin return -1; 654*d079c1a5SHisping Lin } 655*d079c1a5SHisping Lin 656*d079c1a5SHisping Lin static int rkss_get_dirs_by_name(char *filename) 657*d079c1a5SHisping Lin { 658*d079c1a5SHisping Lin int i = 0, ret; 659*d079c1a5SHisping Lin uint8_t n = 0; 660*d079c1a5SHisping Lin unsigned int len; 661*d079c1a5SHisping Lin unsigned char *table_data; 662*d079c1a5SHisping Lin 663*d079c1a5SHisping Lin len = strlen(filename); 664*d079c1a5SHisping Lin if (len > RKSS_MAX_NAME_LENGTH - 1) { 665*d079c1a5SHisping Lin printf("TEEC: filename is too long. length:%u\n", len); 666*d079c1a5SHisping Lin return -1; 667*d079c1a5SHisping Lin } 668*d079c1a5SHisping Lin 669*d079c1a5SHisping Lin table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 670*d079c1a5SHisping Lin if (table_data == NULL) { 671*d079c1a5SHisping Lin printf("TEEC: malloc table_data fail\n"); 672*d079c1a5SHisping Lin return -1; 673*d079c1a5SHisping Lin } 674*d079c1a5SHisping Lin ret = rkss_read_patition_tables(table_data); 675*d079c1a5SHisping Lin if (ret < 0) { 676*d079c1a5SHisping Lin printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 677*d079c1a5SHisping Lin free(table_data); 678*d079c1a5SHisping Lin return -1; 679*d079c1a5SHisping Lin } 680*d079c1a5SHisping Lin 681*d079c1a5SHisping Lin dir_num = 0; 682*d079c1a5SHisping Lin for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 683*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 684*d079c1a5SHisping Lin rkss.index = i; 685*d079c1a5SHisping Lin memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); 686*d079c1a5SHisping Lin 687*d079c1a5SHisping Lin for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { 688*d079c1a5SHisping Lin void *pdata = rkss.data; 689*d079c1a5SHisping Lin struct rkss_file_info *p = (struct rkss_file_info *)pdata; 690*d079c1a5SHisping Lin p += n; 691*d079c1a5SHisping Lin 692*d079c1a5SHisping Lin if (p->used == 0) 693*d079c1a5SHisping Lin continue; 694*d079c1a5SHisping Lin 695*d079c1a5SHisping Lin // Full Matching 696*d079c1a5SHisping Lin ret = memcmp(p->name, filename, strlen(filename)); 697*d079c1a5SHisping Lin debug("TEEC: comparing [fd:%d] : %s ?= %s , ret:%d\n", 698*d079c1a5SHisping Lin i*RKSS_EACH_SECTION_FILECOUNT+n, p->name, filename, ret); 699*d079c1a5SHisping Lin if (!ret && strlen(p->name) > strlen(filename)) { 700*d079c1a5SHisping Lin char *chk = p->name + strlen(filename); 701*d079c1a5SHisping Lin if (*chk == '/') { 702*d079c1a5SHisping Lin char *file = p->name + strlen(filename) + 1; 703*d079c1a5SHisping Lin char *subdir = strtok(file, "/"); 704*d079c1a5SHisping Lin debug("TEEC: found: %s\n", subdir); 705*d079c1a5SHisping Lin strcpy(dir_cache[dir_num], subdir); 706*d079c1a5SHisping Lin ++dir_num; 707*d079c1a5SHisping Lin } 708*d079c1a5SHisping Lin } 709*d079c1a5SHisping Lin } 710*d079c1a5SHisping Lin } 711*d079c1a5SHisping Lin free(table_data); 712*d079c1a5SHisping Lin return dir_num; 713*d079c1a5SHisping Lin } 714*d079c1a5SHisping Lin 715*d079c1a5SHisping Lin static int rkss_get_empty_section_from_usedflags(int section_size) 716*d079c1a5SHisping Lin { 717*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 718*d079c1a5SHisping Lin rkss.index = RKSS_USED_FLAGS_INDEX; 719*d079c1a5SHisping Lin int ret = rkss_read_section(&rkss); 720*d079c1a5SHisping Lin if (ret < 0) { 721*d079c1a5SHisping Lin printf("TEEC: rkss_read_section fail ! ret: %d.\n", ret); 722*d079c1a5SHisping Lin return -1; 723*d079c1a5SHisping Lin } 724*d079c1a5SHisping Lin 725*d079c1a5SHisping Lin int i = 0; 726*d079c1a5SHisping Lin int count0 = 0; 727*d079c1a5SHisping Lin for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) { 728*d079c1a5SHisping Lin uint8_t *flag = (uint8_t *)rkss.data + (int)i/2; 729*d079c1a5SHisping Lin uint8_t value = i & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; 730*d079c1a5SHisping Lin 731*d079c1a5SHisping Lin if (value == 0x0) { 732*d079c1a5SHisping Lin if (++count0 == section_size) 733*d079c1a5SHisping Lin return (i + 1 - section_size); 734*d079c1a5SHisping Lin } else { 735*d079c1a5SHisping Lin count0 = 0; 736*d079c1a5SHisping Lin } 737*d079c1a5SHisping Lin } 738*d079c1a5SHisping Lin 739*d079c1a5SHisping Lin printf("TEEC: Not enough space available in secure storage !\n"); 740*d079c1a5SHisping Lin return -10; 741*d079c1a5SHisping Lin } 742*d079c1a5SHisping Lin 743*d079c1a5SHisping Lin static int rkss_incref_multi_usedflags_sections(unsigned int index, unsigned int num) 744*d079c1a5SHisping Lin { 745*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 746*d079c1a5SHisping Lin int ret, value, i; 747*d079c1a5SHisping Lin uint8_t *flag; 748*d079c1a5SHisping Lin 749*d079c1a5SHisping Lin if ((index + num) >= RKSS_DATA_SECTION_COUNT) { 750*d079c1a5SHisping Lin printf("TEEC: index[%d] out of range.\n", index); 751*d079c1a5SHisping Lin return -1; 752*d079c1a5SHisping Lin } 753*d079c1a5SHisping Lin 754*d079c1a5SHisping Lin rkss.index = RKSS_USED_FLAGS_INDEX; 755*d079c1a5SHisping Lin ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 756*d079c1a5SHisping Lin if (ret < 0) { 757*d079c1a5SHisping Lin printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 758*d079c1a5SHisping Lin return -1; 759*d079c1a5SHisping Lin } 760*d079c1a5SHisping Lin 761*d079c1a5SHisping Lin for (i = 0; i < num; i++, index++) { 762*d079c1a5SHisping Lin flag = (uint8_t *)rkss.data + (int)index/2; 763*d079c1a5SHisping Lin value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; 764*d079c1a5SHisping Lin if (++value > 0xF) { 765*d079c1a5SHisping Lin printf("TEEC: reference out of data: %d\n", value); 766*d079c1a5SHisping Lin value = 0xF; 767*d079c1a5SHisping Lin } 768*d079c1a5SHisping Lin *flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) : 769*d079c1a5SHisping Lin (*flag & 0x0F) | (value << 4); 770*d079c1a5SHisping Lin } 771*d079c1a5SHisping Lin ret = rkss_write_multi_sections(rkss.data, rkss.index, 1); 772*d079c1a5SHisping Lin if (ret < 0) { 773*d079c1a5SHisping Lin printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret); 774*d079c1a5SHisping Lin return -1; 775*d079c1a5SHisping Lin } 776*d079c1a5SHisping Lin return 0; 777*d079c1a5SHisping Lin } 778*d079c1a5SHisping Lin 779*d079c1a5SHisping Lin static int rkss_decref_multi_usedflags_sections(unsigned int index, unsigned int num) 780*d079c1a5SHisping Lin { 781*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 782*d079c1a5SHisping Lin int ret, value, i; 783*d079c1a5SHisping Lin uint8_t *flag; 784*d079c1a5SHisping Lin 785*d079c1a5SHisping Lin if ((index + num) >= RKSS_DATA_SECTION_COUNT) { 786*d079c1a5SHisping Lin printf("TEEC: index[%d] out of range.\n", index); 787*d079c1a5SHisping Lin return -1; 788*d079c1a5SHisping Lin } 789*d079c1a5SHisping Lin 790*d079c1a5SHisping Lin rkss.index = RKSS_USED_FLAGS_INDEX; 791*d079c1a5SHisping Lin ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 792*d079c1a5SHisping Lin if (ret < 0) { 793*d079c1a5SHisping Lin printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 794*d079c1a5SHisping Lin return -1; 795*d079c1a5SHisping Lin } 796*d079c1a5SHisping Lin for (i = 0; i < num; i++, index++) { 797*d079c1a5SHisping Lin flag = (uint8_t *)rkss.data + (int)index/2; 798*d079c1a5SHisping Lin value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; 799*d079c1a5SHisping Lin if (--value < 0) { 800*d079c1a5SHisping Lin printf("TEEC: reference out of data: %d\n", value); 801*d079c1a5SHisping Lin value = 0x0; 802*d079c1a5SHisping Lin } 803*d079c1a5SHisping Lin *flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) : 804*d079c1a5SHisping Lin (*flag & 0x0F) | (value << 4); 805*d079c1a5SHisping Lin } 806*d079c1a5SHisping Lin ret = rkss_write_multi_sections(rkss.data, rkss.index, 1); 807*d079c1a5SHisping Lin if (ret < 0) { 808*d079c1a5SHisping Lin printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret); 809*d079c1a5SHisping Lin return -1; 810*d079c1a5SHisping Lin } 811*d079c1a5SHisping Lin return 0; 812*d079c1a5SHisping Lin } 813*d079c1a5SHisping Lin 814*d079c1a5SHisping Lin static int rkss_write_empty_ptable(struct rkss_file_info *pfileinfo) 815*d079c1a5SHisping Lin { 816*d079c1a5SHisping Lin int i = 0, ret; 817*d079c1a5SHisping Lin unsigned char *table_data; 818*d079c1a5SHisping Lin 819*d079c1a5SHisping Lin table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 820*d079c1a5SHisping Lin if (table_data == NULL) { 821*d079c1a5SHisping Lin printf("TEEC: malloc table_data fail\n"); 822*d079c1a5SHisping Lin return -1; 823*d079c1a5SHisping Lin } 824*d079c1a5SHisping Lin 825*d079c1a5SHisping Lin ret = rkss_read_patition_tables(table_data); 826*d079c1a5SHisping Lin if (ret < 0) { 827*d079c1a5SHisping Lin printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 828*d079c1a5SHisping Lin free(table_data); 829*d079c1a5SHisping Lin return -1; 830*d079c1a5SHisping Lin } 831*d079c1a5SHisping Lin 832*d079c1a5SHisping Lin for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 833*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 834*d079c1a5SHisping Lin rkss.index = i; 835*d079c1a5SHisping Lin memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); 836*d079c1a5SHisping Lin 837*d079c1a5SHisping Lin int n = 0; 838*d079c1a5SHisping Lin for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { 839*d079c1a5SHisping Lin void *pdata = rkss.data; 840*d079c1a5SHisping Lin struct rkss_file_info *p = (struct rkss_file_info *)pdata; 841*d079c1a5SHisping Lin p += n; 842*d079c1a5SHisping Lin if (p->used == 0) { 843*d079c1a5SHisping Lin debug("TEEC: write ptable in [%d][%d] .\n", i, n); 844*d079c1a5SHisping Lin memcpy(p, pfileinfo, sizeof(struct rkss_file_info)); 845*d079c1a5SHisping Lin p->used = 1; 846*d079c1a5SHisping Lin p->id = n; 847*d079c1a5SHisping Lin debug("TEEC: write emt ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n", 848*d079c1a5SHisping Lin i, n, p->name, p->index, p->size, p->used); 849*d079c1a5SHisping Lin ret = rkss_write_section(&rkss); 850*d079c1a5SHisping Lin if (ret < 0) { 851*d079c1a5SHisping Lin printf("TEEC: rkss_write_section fail ! ret: %d.\n", ret); 852*d079c1a5SHisping Lin free(table_data); 853*d079c1a5SHisping Lin return -1; 854*d079c1a5SHisping Lin } 855*d079c1a5SHisping Lin free(table_data); 856*d079c1a5SHisping Lin return i * RKSS_EACH_SECTION_FILECOUNT + n; 857*d079c1a5SHisping Lin } 858*d079c1a5SHisping Lin } 859*d079c1a5SHisping Lin } 860*d079c1a5SHisping Lin printf("TEEC: No enough ptable space available in secure storage.\n"); 861*d079c1a5SHisping Lin free(table_data); 862*d079c1a5SHisping Lin return -1; 863*d079c1a5SHisping Lin } 864*d079c1a5SHisping Lin 865*d079c1a5SHisping Lin static int rkss_write_back_ptable(int fd, struct rkss_file_info *pfileinfo) 866*d079c1a5SHisping Lin { 867*d079c1a5SHisping Lin int i = fd / RKSS_EACH_SECTION_FILECOUNT; 868*d079c1a5SHisping Lin int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i); 869*d079c1a5SHisping Lin 870*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 871*d079c1a5SHisping Lin rkss.index = i; 872*d079c1a5SHisping Lin int ret = rkss_read_section(&rkss); 873*d079c1a5SHisping Lin if (ret < 0) { 874*d079c1a5SHisping Lin debug("TEEC: rkss_read_section fail ! ret: %d.\n", ret); 875*d079c1a5SHisping Lin return -1; 876*d079c1a5SHisping Lin } 877*d079c1a5SHisping Lin 878*d079c1a5SHisping Lin void *pdata = rkss.data; 879*d079c1a5SHisping Lin struct rkss_file_info *p = (struct rkss_file_info *)pdata; 880*d079c1a5SHisping Lin p += n; 881*d079c1a5SHisping Lin 882*d079c1a5SHisping Lin memcpy(p, pfileinfo, sizeof(struct rkss_file_info)); 883*d079c1a5SHisping Lin debug("TEEC: write ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n", 884*d079c1a5SHisping Lin i, n, p->name, p->index, p->size, p->used); 885*d079c1a5SHisping Lin 886*d079c1a5SHisping Lin ret = rkss_write_section(&rkss); 887*d079c1a5SHisping Lin if (ret < 0) { 888*d079c1a5SHisping Lin debug("TEEC: rkss_write_section fail ! ret: %d.\n", ret); 889*d079c1a5SHisping Lin return -1; 890*d079c1a5SHisping Lin } 891*d079c1a5SHisping Lin 892*d079c1a5SHisping Lin return 0; 893*d079c1a5SHisping Lin } 894*d079c1a5SHisping Lin 895*d079c1a5SHisping Lin static int tee_fs_open(struct tee_fs_rpc *fsrpc) 896*d079c1a5SHisping Lin { 897*d079c1a5SHisping Lin int make_newfile = 0; 898*d079c1a5SHisping Lin char *filename = (char *)(fsrpc + 1); 899*d079c1a5SHisping Lin 900*d079c1a5SHisping Lin if (strlen(filename) > RKSS_MAX_NAME_LENGTH) { 901*d079c1a5SHisping Lin debug("TEEC: tee_fs_open: file name too long. %s\n", filename); 902*d079c1a5SHisping Lin return -1; 903*d079c1a5SHisping Lin } 904*d079c1a5SHisping Lin 905*d079c1a5SHisping Lin debug("TEEC: tee_fs_open open file: %s, len: %zu\n", filename, strlen(filename)); 906*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 907*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_name(filename, &p); 908*d079c1a5SHisping Lin if (ret < 0) { 909*d079c1a5SHisping Lin debug("TEEC: tee_fs_open : no such file. %s\n", filename); 910*d079c1a5SHisping Lin make_newfile = 1; 911*d079c1a5SHisping Lin } else { 912*d079c1a5SHisping Lin fsrpc->fd = ret; 913*d079c1a5SHisping Lin file_seek = 0; 914*d079c1a5SHisping Lin if (CHECKFLAG(fsrpc->flags, TEE_FS_O_APPEND)) { 915*d079c1a5SHisping Lin file_seek = p.size; 916*d079c1a5SHisping Lin } 917*d079c1a5SHisping Lin } 918*d079c1a5SHisping Lin 919*d079c1a5SHisping Lin ret = rkss_begin_commit(); 920*d079c1a5SHisping Lin if (ret < 0) { 921*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!"); 922*d079c1a5SHisping Lin return -1; 923*d079c1a5SHisping Lin } 924*d079c1a5SHisping Lin 925*d079c1a5SHisping Lin if (make_newfile) { 926*d079c1a5SHisping Lin if (CHECKFLAG(fsrpc->flags, TEE_FS_O_CREAT)) { 927*d079c1a5SHisping Lin debug("TEEC: tee_fs_open create new file: %s\n", filename); 928*d079c1a5SHisping Lin strcpy(p.name, filename); 929*d079c1a5SHisping Lin p.index = 0; 930*d079c1a5SHisping Lin p.size = fsrpc->len; 931*d079c1a5SHisping Lin p.used = 1; 932*d079c1a5SHisping Lin p.flags = RK_FS_R | RK_FS_W; 933*d079c1a5SHisping Lin ret = rkss_write_empty_ptable(&p); 934*d079c1a5SHisping Lin if (ret < 0) { 935*d079c1a5SHisping Lin printf("TEEC: tee_fs_open : error. %s\n", filename); 936*d079c1a5SHisping Lin return -1; 937*d079c1a5SHisping Lin } 938*d079c1a5SHisping Lin fsrpc->fd = ret; 939*d079c1a5SHisping Lin file_seek = 0; 940*d079c1a5SHisping Lin } else { 941*d079c1a5SHisping Lin debug("TEEC: and no create flag found.\n"); 942*d079c1a5SHisping Lin return -1; 943*d079c1a5SHisping Lin } 944*d079c1a5SHisping Lin } 945*d079c1a5SHisping Lin 946*d079c1a5SHisping Lin debug("TEEC: tee_fs_open ! %s , fd:%d, flag: %x, len: %d\n", 947*d079c1a5SHisping Lin filename, fsrpc->fd, fsrpc->flags, fsrpc->len); 948*d079c1a5SHisping Lin 949*d079c1a5SHisping Lin ret = rkss_finish_commit(); 950*d079c1a5SHisping Lin if (ret < 0) { 951*d079c1a5SHisping Lin printf("TEEC: rkss_finish_commit failed!"); 952*d079c1a5SHisping Lin return -1; 953*d079c1a5SHisping Lin } 954*d079c1a5SHisping Lin 955*d079c1a5SHisping Lin return fsrpc->fd; 956*d079c1a5SHisping Lin } 957*d079c1a5SHisping Lin 958*d079c1a5SHisping Lin static int tee_fs_close(struct tee_fs_rpc *fsrpc) 959*d079c1a5SHisping Lin { 960*d079c1a5SHisping Lin debug("TEEC: tee_fs_close !\n"); 961*d079c1a5SHisping Lin UNREFERENCED_PARAMETER(fsrpc); 962*d079c1a5SHisping Lin return 0; 963*d079c1a5SHisping Lin } 964*d079c1a5SHisping Lin 965*d079c1a5SHisping Lin static int tee_fs_read(struct tee_fs_rpc *fsrpc) 966*d079c1a5SHisping Lin { 967*d079c1a5SHisping Lin debug("TEEC: tee_fs_read! fd:%d, len:%d\n", fsrpc->fd, fsrpc->len); 968*d079c1a5SHisping Lin void *data = (void *)(fsrpc + 1); 969*d079c1a5SHisping Lin 970*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 971*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); 972*d079c1a5SHisping Lin if (ret < 0) { 973*d079c1a5SHisping Lin printf("TEEC: unavailable fd !\n"); 974*d079c1a5SHisping Lin return -1; 975*d079c1a5SHisping Lin } 976*d079c1a5SHisping Lin 977*d079c1a5SHisping Lin if (file_seek != 0) { 978*d079c1a5SHisping Lin printf("TEEC: warning !!! file_seek != 0. unsupported now.\n"); 979*d079c1a5SHisping Lin } 980*d079c1a5SHisping Lin 981*d079c1a5SHisping Lin int num = fsrpc->len / RKSS_DATA_SECTION_LEN + 1; 982*d079c1a5SHisping Lin int di = 0; 983*d079c1a5SHisping Lin debug("TEEC: reading section[%d], fd:%d, len:%d, filesize:%d\n", 984*d079c1a5SHisping Lin p.index, fsrpc->fd, fsrpc->len, p.size); 985*d079c1a5SHisping Lin 986*d079c1a5SHisping Lin uint8_t *temp_file_data = malloc(num * RKSS_DATA_SECTION_LEN); 987*d079c1a5SHisping Lin ret = rkss_read_multi_sections(temp_file_data, p.index, num); 988*d079c1a5SHisping Lin if (ret < 0) { 989*d079c1a5SHisping Lin printf("TEEC: unavailable file index\n"); 990*d079c1a5SHisping Lin free(temp_file_data); 991*d079c1a5SHisping Lin return -1; 992*d079c1a5SHisping Lin } 993*d079c1a5SHisping Lin di = fsrpc->len > p.size ? p.size : fsrpc->len; 994*d079c1a5SHisping Lin memcpy(data, temp_file_data, di); 995*d079c1a5SHisping Lin free(temp_file_data); 996*d079c1a5SHisping Lin temp_file_data = 0; 997*d079c1a5SHisping Lin return di; 998*d079c1a5SHisping Lin } 999*d079c1a5SHisping Lin 1000*d079c1a5SHisping Lin static int tee_fs_write(struct tee_fs_rpc *fsrpc) 1001*d079c1a5SHisping Lin { 1002*d079c1a5SHisping Lin debug("TEEC: tee_fs_write ! fd:%d, lenth:%d\n", fsrpc->fd, fsrpc->len); 1003*d079c1a5SHisping Lin void *data = (void *)(fsrpc + 1); 1004*d079c1a5SHisping Lin 1005*d079c1a5SHisping Lin if (fsrpc->fd < 0) { 1006*d079c1a5SHisping Lin printf("TEEC: tee_fs_write error ! wrong fd : %d\n", fsrpc->fd); 1007*d079c1a5SHisping Lin return -1; 1008*d079c1a5SHisping Lin } 1009*d079c1a5SHisping Lin 1010*d079c1a5SHisping Lin if (file_seek != 0) { 1011*d079c1a5SHisping Lin printf("TEEC: warning !!! file_seek != 0. unsupported now.\n"); 1012*d079c1a5SHisping Lin } 1013*d079c1a5SHisping Lin 1014*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 1015*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); 1016*d079c1a5SHisping Lin if (ret < 0) { 1017*d079c1a5SHisping Lin printf("TEEC: tee_fs_write: fd unvailable!\n"); 1018*d079c1a5SHisping Lin return -1; 1019*d079c1a5SHisping Lin } 1020*d079c1a5SHisping Lin 1021*d079c1a5SHisping Lin ret = rkss_begin_commit(); 1022*d079c1a5SHisping Lin if (ret < 0) { 1023*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!"); 1024*d079c1a5SHisping Lin return -1; 1025*d079c1a5SHisping Lin } 1026*d079c1a5SHisping Lin int num; 1027*d079c1a5SHisping Lin if (p.size != 0) { 1028*d079c1a5SHisping Lin num = p.size / RKSS_DATA_SECTION_LEN + 1; 1029*d079c1a5SHisping Lin ret = rkss_decref_multi_usedflags_sections(p.index, num); 1030*d079c1a5SHisping Lin if (ret < 0) { 1031*d079c1a5SHisping Lin printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); 1032*d079c1a5SHisping Lin return -1; 1033*d079c1a5SHisping Lin } 1034*d079c1a5SHisping Lin } 1035*d079c1a5SHisping Lin 1036*d079c1a5SHisping Lin p.size = fsrpc->len; 1037*d079c1a5SHisping Lin num = fsrpc->len / RKSS_DATA_SECTION_LEN + 1; 1038*d079c1a5SHisping Lin p.index = rkss_get_empty_section_from_usedflags(num); 1039*d079c1a5SHisping Lin debug("TEEC: Get Empty section in %d\n", p.index); 1040*d079c1a5SHisping Lin p.used = 1; 1041*d079c1a5SHisping Lin 1042*d079c1a5SHisping Lin ret = rkss_incref_multi_usedflags_sections(p.index, num); 1043*d079c1a5SHisping Lin if (ret < 0) { 1044*d079c1a5SHisping Lin printf("TEEC: rkss_incref_multi_usedflags_sections error !\n"); 1045*d079c1a5SHisping Lin ret = -1; 1046*d079c1a5SHisping Lin } 1047*d079c1a5SHisping Lin 1048*d079c1a5SHisping Lin ret = rkss_write_back_ptable(fsrpc->fd, &p); 1049*d079c1a5SHisping Lin if (ret < 0) { 1050*d079c1a5SHisping Lin printf("TEEC: tee_fs_write: write ptable error!\n"); 1051*d079c1a5SHisping Lin return -1; 1052*d079c1a5SHisping Lin } 1053*d079c1a5SHisping Lin 1054*d079c1a5SHisping Lin uint8_t *temp_file_data = malloc(num * RKSS_DATA_SECTION_LEN); 1055*d079c1a5SHisping Lin memset(temp_file_data, 0, num * RKSS_DATA_SECTION_LEN); 1056*d079c1a5SHisping Lin memcpy(temp_file_data, data, p.size); 1057*d079c1a5SHisping Lin rkss_write_multi_sections(temp_file_data, p.index, num); 1058*d079c1a5SHisping Lin free(temp_file_data); 1059*d079c1a5SHisping Lin temp_file_data = 0; 1060*d079c1a5SHisping Lin 1061*d079c1a5SHisping Lin #ifdef DEBUG_RKSS 1062*d079c1a5SHisping Lin rkss_dump_usedflags(); 1063*d079c1a5SHisping Lin #endif 1064*d079c1a5SHisping Lin 1065*d079c1a5SHisping Lin ret = rkss_finish_commit(); 1066*d079c1a5SHisping Lin if (ret < 0) { 1067*d079c1a5SHisping Lin printf("TEEC: rkss_finish_commit failed!"); 1068*d079c1a5SHisping Lin return -1; 1069*d079c1a5SHisping Lin } 1070*d079c1a5SHisping Lin 1071*d079c1a5SHisping Lin return fsrpc->len; 1072*d079c1a5SHisping Lin } 1073*d079c1a5SHisping Lin 1074*d079c1a5SHisping Lin static int tee_fs_seek(struct tee_fs_rpc *fsrpc) 1075*d079c1a5SHisping Lin { 1076*d079c1a5SHisping Lin debug("TEEC: tee_fs_seek ! fd:%d, seek:%d, flag:%x\n", fsrpc->fd, fsrpc->arg, fsrpc->flags); 1077*d079c1a5SHisping Lin 1078*d079c1a5SHisping Lin if (fsrpc->flags == TEE_FS_SEEK_CUR) { 1079*d079c1a5SHisping Lin fsrpc->res = file_seek + fsrpc->arg; 1080*d079c1a5SHisping Lin } else if (fsrpc->flags == TEE_FS_SEEK_SET) { 1081*d079c1a5SHisping Lin file_seek = fsrpc->arg; 1082*d079c1a5SHisping Lin fsrpc->res = file_seek; 1083*d079c1a5SHisping Lin } else if (fsrpc->flags == TEE_FS_SEEK_END) { 1084*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 1085*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); 1086*d079c1a5SHisping Lin if (ret < 0) { 1087*d079c1a5SHisping Lin printf("TEEC: unavilable fd.\n"); 1088*d079c1a5SHisping Lin return -1; 1089*d079c1a5SHisping Lin } 1090*d079c1a5SHisping Lin file_seek = p.size + fsrpc->arg; 1091*d079c1a5SHisping Lin fsrpc->res = file_seek; 1092*d079c1a5SHisping Lin } else { 1093*d079c1a5SHisping Lin printf("TEEC: tee_fs_seek: unsupport seed mode.\n"); 1094*d079c1a5SHisping Lin return -1; 1095*d079c1a5SHisping Lin } 1096*d079c1a5SHisping Lin 1097*d079c1a5SHisping Lin return fsrpc->res; 1098*d079c1a5SHisping Lin } 1099*d079c1a5SHisping Lin 1100*d079c1a5SHisping Lin static int tee_fs_unlink(struct tee_fs_rpc *fsrpc) 1101*d079c1a5SHisping Lin { 1102*d079c1a5SHisping Lin char *filename = (char *)(fsrpc + 1); 1103*d079c1a5SHisping Lin 1104*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 1105*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_name(filename, &p); 1106*d079c1a5SHisping Lin if (ret < 0) { 1107*d079c1a5SHisping Lin printf("TEEC: tee_fs_unlink : no such file. %s\n", filename); 1108*d079c1a5SHisping Lin return 0; 1109*d079c1a5SHisping Lin } 1110*d079c1a5SHisping Lin int fd = ret; 1111*d079c1a5SHisping Lin 1112*d079c1a5SHisping Lin debug("TEEC: tee_fs_unlink ! %s fd:%d index:%d size:%d\n", filename, fd, p.index, p.size); 1113*d079c1a5SHisping Lin 1114*d079c1a5SHisping Lin ret = rkss_begin_commit(); 1115*d079c1a5SHisping Lin if (ret < 0) { 1116*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!"); 1117*d079c1a5SHisping Lin return -1; 1118*d079c1a5SHisping Lin } 1119*d079c1a5SHisping Lin 1120*d079c1a5SHisping Lin /* decrease ref from usedflags */ 1121*d079c1a5SHisping Lin int num = p.size / RKSS_DATA_SECTION_LEN + 1; 1122*d079c1a5SHisping Lin ret = rkss_decref_multi_usedflags_sections(p.index, num); 1123*d079c1a5SHisping Lin if (ret < 0) { 1124*d079c1a5SHisping Lin printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); 1125*d079c1a5SHisping Lin return -1; 1126*d079c1a5SHisping Lin } 1127*d079c1a5SHisping Lin 1128*d079c1a5SHisping Lin /* rm from ptable */ 1129*d079c1a5SHisping Lin memset(&p, 0, sizeof(struct rkss_file_info)); 1130*d079c1a5SHisping Lin ret = rkss_write_back_ptable(fd, &p); 1131*d079c1a5SHisping Lin if (ret < 0) { 1132*d079c1a5SHisping Lin printf("TEEC: tee_fs_unlink : write back error %d\n", ret); 1133*d079c1a5SHisping Lin return -1; 1134*d079c1a5SHisping Lin } 1135*d079c1a5SHisping Lin 1136*d079c1a5SHisping Lin #ifdef DEBUG_RKSS 1137*d079c1a5SHisping Lin rkss_dump_ptable(); 1138*d079c1a5SHisping Lin #endif 1139*d079c1a5SHisping Lin 1140*d079c1a5SHisping Lin ret = rkss_finish_commit(); 1141*d079c1a5SHisping Lin if (ret < 0) { 1142*d079c1a5SHisping Lin printf("TEEC: rkss_finish_commit failed!"); 1143*d079c1a5SHisping Lin return -1; 1144*d079c1a5SHisping Lin } 1145*d079c1a5SHisping Lin 1146*d079c1a5SHisping Lin return 0; 1147*d079c1a5SHisping Lin } 1148*d079c1a5SHisping Lin 1149*d079c1a5SHisping Lin static int tee_fs_link(struct tee_fs_rpc *fsrpc) 1150*d079c1a5SHisping Lin { 1151*d079c1a5SHisping Lin char *filename = (char *)(fsrpc + 1); 1152*d079c1a5SHisping Lin size_t offset_new_fn = strlen(filename) + 1; 1153*d079c1a5SHisping Lin char *newfilename = filename + offset_new_fn; 1154*d079c1a5SHisping Lin debug("TEEC: tee_fs_link ! %s -> %s\n", filename, newfilename); 1155*d079c1a5SHisping Lin 1156*d079c1a5SHisping Lin struct rkss_file_info p_old = {0}; 1157*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_name(filename, &p_old); 1158*d079c1a5SHisping Lin if (ret < 0) { 1159*d079c1a5SHisping Lin printf("TEEC: cannot find src file %s.\n", filename); 1160*d079c1a5SHisping Lin return -1; 1161*d079c1a5SHisping Lin } 1162*d079c1a5SHisping Lin 1163*d079c1a5SHisping Lin struct rkss_file_info p_check = {0}; 1164*d079c1a5SHisping Lin ret = rkss_get_fileinfo_by_name(newfilename, &p_check); 1165*d079c1a5SHisping Lin if (ret >= 0) { 1166*d079c1a5SHisping Lin printf("TEEC: file exist ! %s.\n", newfilename); 1167*d079c1a5SHisping Lin return -1; 1168*d079c1a5SHisping Lin } 1169*d079c1a5SHisping Lin ret = rkss_begin_commit(); 1170*d079c1a5SHisping Lin if (ret < 0) { 1171*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!"); 1172*d079c1a5SHisping Lin return -1; 1173*d079c1a5SHisping Lin } 1174*d079c1a5SHisping Lin 1175*d079c1a5SHisping Lin struct rkss_file_info p_new = {0}; 1176*d079c1a5SHisping Lin memcpy(&p_new, &p_old, sizeof(struct rkss_file_info)); 1177*d079c1a5SHisping Lin strcpy(p_new.name, newfilename); 1178*d079c1a5SHisping Lin ret = rkss_write_empty_ptable(&p_new); 1179*d079c1a5SHisping Lin if (ret < 0) { 1180*d079c1a5SHisping Lin printf("TEEC: tee_fs_open : error. %s\n", filename); 1181*d079c1a5SHisping Lin return -1; 1182*d079c1a5SHisping Lin } 1183*d079c1a5SHisping Lin 1184*d079c1a5SHisping Lin int num = p_new.size / RKSS_DATA_SECTION_LEN + 1; 1185*d079c1a5SHisping Lin ret = rkss_incref_multi_usedflags_sections(p_new.index, num); 1186*d079c1a5SHisping Lin if (ret < 0) { 1187*d079c1a5SHisping Lin printf("TEEC: rkss_incref_multi_usedflags_sections error !\n"); 1188*d079c1a5SHisping Lin return -1; 1189*d079c1a5SHisping Lin } 1190*d079c1a5SHisping Lin 1191*d079c1a5SHisping Lin #ifdef DEBUG_RKSS 1192*d079c1a5SHisping Lin rkss_dump_ptable(); 1193*d079c1a5SHisping Lin #endif 1194*d079c1a5SHisping Lin ret = rkss_finish_commit(); 1195*d079c1a5SHisping Lin if (ret < 0) { 1196*d079c1a5SHisping Lin printf("TEEC: rkss_finish_commit failed!"); 1197*d079c1a5SHisping Lin return -1; 1198*d079c1a5SHisping Lin } 1199*d079c1a5SHisping Lin 1200*d079c1a5SHisping Lin return 0; 1201*d079c1a5SHisping Lin } 1202*d079c1a5SHisping Lin 1203*d079c1a5SHisping Lin static int tee_fs_rename(struct tee_fs_rpc *fsrpc) 1204*d079c1a5SHisping Lin { 1205*d079c1a5SHisping Lin char *filenames = (char *)(fsrpc + 1); 1206*d079c1a5SHisping Lin char *newnames = filenames + strlen(filenames) + 1; 1207*d079c1a5SHisping Lin debug("TEEC: rename: %s -> %s\n", filenames, newnames); 1208*d079c1a5SHisping Lin 1209*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 1210*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_name(filenames, &p); 1211*d079c1a5SHisping Lin if (ret < 0) { 1212*d079c1a5SHisping Lin printf("TEEC: filename no found .\n"); 1213*d079c1a5SHisping Lin return -1; 1214*d079c1a5SHisping Lin } 1215*d079c1a5SHisping Lin 1216*d079c1a5SHisping Lin ret = rkss_begin_commit(); 1217*d079c1a5SHisping Lin if (ret < 0) { 1218*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!"); 1219*d079c1a5SHisping Lin return -1; 1220*d079c1a5SHisping Lin } 1221*d079c1a5SHisping Lin 1222*d079c1a5SHisping Lin strcpy(p.name, newnames); 1223*d079c1a5SHisping Lin 1224*d079c1a5SHisping Lin ret = rkss_write_back_ptable(ret, &p); 1225*d079c1a5SHisping Lin if (ret < 0) { 1226*d079c1a5SHisping Lin printf("TEEC: write ptable error!\n"); 1227*d079c1a5SHisping Lin return -1; 1228*d079c1a5SHisping Lin } 1229*d079c1a5SHisping Lin 1230*d079c1a5SHisping Lin ret = rkss_finish_commit(); 1231*d079c1a5SHisping Lin if (ret < 0) { 1232*d079c1a5SHisping Lin printf("TEEC: rkss_finish_commit failed!"); 1233*d079c1a5SHisping Lin return -1; 1234*d079c1a5SHisping Lin } 1235*d079c1a5SHisping Lin 1236*d079c1a5SHisping Lin return 0; 1237*d079c1a5SHisping Lin } 1238*d079c1a5SHisping Lin 1239*d079c1a5SHisping Lin static int tee_fs_truncate(struct tee_fs_rpc *fsrpc) 1240*d079c1a5SHisping Lin { 1241*d079c1a5SHisping Lin int section_num, new_section_num, free_section_num; 1242*d079c1a5SHisping Lin uint16_t free_index; 1243*d079c1a5SHisping Lin 1244*d079c1a5SHisping Lin debug("TEEC: tee_fs_truncate: fd:%d, lenth:%d\n", fsrpc->fd, fsrpc->arg); 1245*d079c1a5SHisping Lin if (fsrpc->fd < 0) { 1246*d079c1a5SHisping Lin printf("TEEC: tee_fs_truncate: fd unavilable !\n"); 1247*d079c1a5SHisping Lin return -1; 1248*d079c1a5SHisping Lin } 1249*d079c1a5SHisping Lin 1250*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 1251*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_index(fsrpc->fd, &p); 1252*d079c1a5SHisping Lin if (ret < 0) { 1253*d079c1a5SHisping Lin printf("TEEC: fd unvailable!\n"); 1254*d079c1a5SHisping Lin return -1; 1255*d079c1a5SHisping Lin } 1256*d079c1a5SHisping Lin ret = rkss_begin_commit(); 1257*d079c1a5SHisping Lin if (ret < 0) { 1258*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!"); 1259*d079c1a5SHisping Lin return -1; 1260*d079c1a5SHisping Lin } 1261*d079c1a5SHisping Lin if (p.size < fsrpc->arg) { 1262*d079c1a5SHisping Lin printf("TEEC: truncate size not support!\n "); 1263*d079c1a5SHisping Lin return -1; 1264*d079c1a5SHisping Lin } else { 1265*d079c1a5SHisping Lin section_num = p.size / RKSS_DATA_SECTION_LEN + 1; 1266*d079c1a5SHisping Lin new_section_num = fsrpc->arg / RKSS_DATA_SECTION_LEN + 1; 1267*d079c1a5SHisping Lin free_section_num = section_num - new_section_num; 1268*d079c1a5SHisping Lin free_index = p.index + new_section_num; 1269*d079c1a5SHisping Lin ret = rkss_decref_multi_usedflags_sections(free_index, free_section_num); 1270*d079c1a5SHisping Lin if (ret < 0) { 1271*d079c1a5SHisping Lin printf("TEEC: rkss_decref_multi_usedflags_sections error!\n"); 1272*d079c1a5SHisping Lin return -1; 1273*d079c1a5SHisping Lin } 1274*d079c1a5SHisping Lin p.size = fsrpc->arg; 1275*d079c1a5SHisping Lin ret = rkss_write_back_ptable(fsrpc->fd, &p); 1276*d079c1a5SHisping Lin if (ret < 0) { 1277*d079c1a5SHisping Lin printf("TEEC: rkss_write_back_ptable error!\n"); 1278*d079c1a5SHisping Lin return -1; 1279*d079c1a5SHisping Lin } 1280*d079c1a5SHisping Lin } 1281*d079c1a5SHisping Lin 1282*d079c1a5SHisping Lin ret = rkss_finish_commit(); 1283*d079c1a5SHisping Lin if (ret < 0) { 1284*d079c1a5SHisping Lin printf("TEEC: rkss_finish_commit failed!"); 1285*d079c1a5SHisping Lin return -1; 1286*d079c1a5SHisping Lin } 1287*d079c1a5SHisping Lin return 0; 1288*d079c1a5SHisping Lin } 1289*d079c1a5SHisping Lin 1290*d079c1a5SHisping Lin static int tee_fs_mkdir(struct tee_fs_rpc *fsrpc) 1291*d079c1a5SHisping Lin { 1292*d079c1a5SHisping Lin char *dirname = (char *)(fsrpc + 1); 1293*d079c1a5SHisping Lin UNREFERENCED_PARAMETER(dirname); 1294*d079c1a5SHisping Lin debug("TEEC: tee_fs_mkdir: %s\n", dirname); 1295*d079c1a5SHisping Lin return 0; 1296*d079c1a5SHisping Lin } 1297*d079c1a5SHisping Lin 1298*d079c1a5SHisping Lin static int tee_fs_opendir(struct tee_fs_rpc *fsrpc) 1299*d079c1a5SHisping Lin { 1300*d079c1a5SHisping Lin char *dirname = (char *)(fsrpc + 1); 1301*d079c1a5SHisping Lin dir_seek = 0; 1302*d079c1a5SHisping Lin int ret = rkss_get_dirs_by_name(dirname); 1303*d079c1a5SHisping Lin if (ret < 0) { 1304*d079c1a5SHisping Lin printf("TEEC: tee_fs_opendir: error\n"); 1305*d079c1a5SHisping Lin } 1306*d079c1a5SHisping Lin debug("TEEC: tee_fs_opendir: %s, seek/num:%d/%d\n", dirname, dir_seek, dir_num); 1307*d079c1a5SHisping Lin return 0; 1308*d079c1a5SHisping Lin } 1309*d079c1a5SHisping Lin 1310*d079c1a5SHisping Lin static int tee_fs_closedir(struct tee_fs_rpc *fsrpc) 1311*d079c1a5SHisping Lin { 1312*d079c1a5SHisping Lin char *dirname = (char *)(fsrpc + 1); 1313*d079c1a5SHisping Lin UNREFERENCED_PARAMETER(dirname); 1314*d079c1a5SHisping Lin debug("TEEC: tee_fs_closedir: %s\n", dirname); 1315*d079c1a5SHisping Lin dir_seek = 0; 1316*d079c1a5SHisping Lin dir_num = 0; 1317*d079c1a5SHisping Lin return 0; 1318*d079c1a5SHisping Lin } 1319*d079c1a5SHisping Lin 1320*d079c1a5SHisping Lin static int tee_fs_readdir(struct tee_fs_rpc *fsrpc) 1321*d079c1a5SHisping Lin { 1322*d079c1a5SHisping Lin char *dirname = (char *)(fsrpc + 1); 1323*d079c1a5SHisping Lin debug("TEEC: seek/num:%d/%d\n", dir_seek, dir_num); 1324*d079c1a5SHisping Lin if (dir_seek == dir_num) { 1325*d079c1a5SHisping Lin dirname = NULL; 1326*d079c1a5SHisping Lin fsrpc->len = 0; 1327*d079c1a5SHisping Lin debug("TEEC: tee_fs_readdir: END\n"); 1328*d079c1a5SHisping Lin return -1; 1329*d079c1a5SHisping Lin } 1330*d079c1a5SHisping Lin 1331*d079c1a5SHisping Lin strcpy(dirname, dir_cache[dir_seek]); 1332*d079c1a5SHisping Lin fsrpc->len = strlen(dir_cache[dir_seek]) + 1; 1333*d079c1a5SHisping Lin ++dir_seek; 1334*d079c1a5SHisping Lin 1335*d079c1a5SHisping Lin debug("TEEC: tee_fs_readdir: %s\n", dirname); 1336*d079c1a5SHisping Lin return 0; 1337*d079c1a5SHisping Lin } 1338*d079c1a5SHisping Lin 1339*d079c1a5SHisping Lin static int tee_fs_rmdir(struct tee_fs_rpc *fsrpc) 1340*d079c1a5SHisping Lin { 1341*d079c1a5SHisping Lin char *dirname = (char *)(fsrpc + 1); 1342*d079c1a5SHisping Lin debug("TEEC: tee_fs_rmdir: %s\n", dirname); 1343*d079c1a5SHisping Lin 1344*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 1345*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_name(dirname, &p); 1346*d079c1a5SHisping Lin if (ret == -100) { 1347*d079c1a5SHisping Lin printf("TEEC: dir is not empty.\n"); 1348*d079c1a5SHisping Lin return -1; 1349*d079c1a5SHisping Lin } else if (ret >= 0) { 1350*d079c1a5SHisping Lin printf("TEEC: %s is not a dir.\n", p.name); 1351*d079c1a5SHisping Lin return -1; 1352*d079c1a5SHisping Lin } 1353*d079c1a5SHisping Lin debug("TEEC: rmdir success.\n"); 1354*d079c1a5SHisping Lin return 0; 1355*d079c1a5SHisping Lin } 1356*d079c1a5SHisping Lin 1357*d079c1a5SHisping Lin static int tee_fs_access(struct tee_fs_rpc *fsrpc) 1358*d079c1a5SHisping Lin { 1359*d079c1a5SHisping Lin char *filename = (char *)(fsrpc + 1); 1360*d079c1a5SHisping Lin debug("TEEC: tee_fs_access: name:%s,flag:%x\n", filename, fsrpc->flags); 1361*d079c1a5SHisping Lin 1362*d079c1a5SHisping Lin struct rkss_file_info p = {0}; 1363*d079c1a5SHisping Lin int ret = rkss_get_fileinfo_by_name(filename, &p); 1364*d079c1a5SHisping Lin if (ret < 0 && ret != -100) { 1365*d079c1a5SHisping Lin debug("TEEC: tee_fs_access: %s no such file or directory.\n", filename); 1366*d079c1a5SHisping Lin return -1; 1367*d079c1a5SHisping Lin } 1368*d079c1a5SHisping Lin 1369*d079c1a5SHisping Lin if (CHECKFLAG(fsrpc->flags, TEE_FS_R_OK)) { 1370*d079c1a5SHisping Lin if (!CHECKFLAG(p.flags, RK_FS_R)) { 1371*d079c1a5SHisping Lin printf("TEEC: tee_fs_access: no permission FS_R_OK in %x.\n", p.flags); 1372*d079c1a5SHisping Lin return -1; 1373*d079c1a5SHisping Lin } 1374*d079c1a5SHisping Lin } 1375*d079c1a5SHisping Lin 1376*d079c1a5SHisping Lin if (CHECKFLAG(fsrpc->flags, TEE_FS_W_OK)) { 1377*d079c1a5SHisping Lin if (!CHECKFLAG(p.flags, RK_FS_W)) { 1378*d079c1a5SHisping Lin printf("TEEC: tee_fs_access: no permission FS_W_OK in %x.\n", p.flags); 1379*d079c1a5SHisping Lin return -1; 1380*d079c1a5SHisping Lin } 1381*d079c1a5SHisping Lin } 1382*d079c1a5SHisping Lin return 0; 1383*d079c1a5SHisping Lin } 1384*d079c1a5SHisping Lin 1385*d079c1a5SHisping Lin int tee_supp_rk_fs_init_v1(void) 1386*d079c1a5SHisping Lin { 1387*d079c1a5SHisping Lin assert(sizeof(struct rkss_file_info) == 126); 1388*d079c1a5SHisping Lin assert(512 / sizeof(struct rkss_file_info) == RKSS_EACH_SECTION_FILECOUNT); 1389*d079c1a5SHisping Lin 1390*d079c1a5SHisping Lin __maybe_unused int i = 0; 1391*d079c1a5SHisping Lin unsigned char *table_data; 1392*d079c1a5SHisping Lin int ret; 1393*d079c1a5SHisping Lin 1394*d079c1a5SHisping Lin if (check_security_exist(0) < 0) 1395*d079c1a5SHisping Lin return 0; 1396*d079c1a5SHisping Lin 1397*d079c1a5SHisping Lin ret = rkss_resume(); 1398*d079c1a5SHisping Lin if (ret < 0) { 1399*d079c1a5SHisping Lin printf("TEEC: rkss_resume failed!\n"); 1400*d079c1a5SHisping Lin return -1; 1401*d079c1a5SHisping Lin } 1402*d079c1a5SHisping Lin #ifdef DEBUG_CLEAN_RKSS // clean secure storage 1403*d079c1a5SHisping Lin for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) { 1404*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 1405*d079c1a5SHisping Lin memset(rkss.data, 0, RKSS_DATA_SECTION_LEN); 1406*d079c1a5SHisping Lin rkss.index = i; 1407*d079c1a5SHisping Lin rkss_write_section(&rkss); 1408*d079c1a5SHisping Lin printf("TEEC: cleaned [%d]", i); 1409*d079c1a5SHisping Lin } 1410*d079c1a5SHisping Lin #endif 1411*d079c1a5SHisping Lin 1412*d079c1a5SHisping Lin ret = rkss_begin_commit(); 1413*d079c1a5SHisping Lin if (ret < 0) { 1414*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!\n"); 1415*d079c1a5SHisping Lin return -1; 1416*d079c1a5SHisping Lin } 1417*d079c1a5SHisping Lin 1418*d079c1a5SHisping Lin // Verify Partition Table 1419*d079c1a5SHisping Lin table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 1420*d079c1a5SHisping Lin if (table_data == NULL) { 1421*d079c1a5SHisping Lin printf("TEEC: malloc table_data fail\n"); 1422*d079c1a5SHisping Lin return -1; 1423*d079c1a5SHisping Lin } 1424*d079c1a5SHisping Lin ret = rkss_read_patition_tables(table_data); 1425*d079c1a5SHisping Lin if (ret < 0) { 1426*d079c1a5SHisping Lin printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 1427*d079c1a5SHisping Lin free(table_data); 1428*d079c1a5SHisping Lin return -1; 1429*d079c1a5SHisping Lin } 1430*d079c1a5SHisping Lin 1431*d079c1a5SHisping Lin /* Verify Partition Table*/ 1432*d079c1a5SHisping Lin ret = rkss_verify_ptable(table_data); 1433*d079c1a5SHisping Lin if (ret < 0) { 1434*d079c1a5SHisping Lin printf("TEEC: rkss_verify_ptable fail ! ret: %d.\n", ret); 1435*d079c1a5SHisping Lin free(table_data); 1436*d079c1a5SHisping Lin return -1; 1437*d079c1a5SHisping Lin } 1438*d079c1a5SHisping Lin free(table_data); 1439*d079c1a5SHisping Lin table_data = NULL; 1440*d079c1a5SHisping Lin 1441*d079c1a5SHisping Lin // Verify Usedflags Section 1442*d079c1a5SHisping Lin struct rk_secure_storage rkss = {0}; 1443*d079c1a5SHisping Lin rkss.index = RKSS_USED_FLAGS_INDEX; 1444*d079c1a5SHisping Lin ret = rkss_read_section(&rkss); 1445*d079c1a5SHisping Lin if (ret < 0) { 1446*d079c1a5SHisping Lin printf("TEEC: rkss_read_section fail ! ret: %d.\n", ret); 1447*d079c1a5SHisping Lin return -1; 1448*d079c1a5SHisping Lin } 1449*d079c1a5SHisping Lin ret = rkss_verify_usedflags(&rkss); 1450*d079c1a5SHisping Lin if (ret < 0) { 1451*d079c1a5SHisping Lin printf("TEEC: rkss_verify_usedflags fail ! ret: %d.\n", ret); 1452*d079c1a5SHisping Lin return -1; 1453*d079c1a5SHisping Lin } 1454*d079c1a5SHisping Lin 1455*d079c1a5SHisping Lin #ifdef DEBUG_RKSS 1456*d079c1a5SHisping Lin rkss_dump_ptable(); 1457*d079c1a5SHisping Lin rkss_dump_usedflags(); 1458*d079c1a5SHisping Lin #endif 1459*d079c1a5SHisping Lin 1460*d079c1a5SHisping Lin ret = rkss_begin_commit(); 1461*d079c1a5SHisping Lin if (ret < 0) { 1462*d079c1a5SHisping Lin printf("TEEC: rkss_begin_commit failed!\n"); 1463*d079c1a5SHisping Lin return -1; 1464*d079c1a5SHisping Lin } 1465*d079c1a5SHisping Lin 1466*d079c1a5SHisping Lin return 0; 1467*d079c1a5SHisping Lin } 1468*d079c1a5SHisping Lin 1469*d079c1a5SHisping Lin static int rkss_step; 1470*d079c1a5SHisping Lin int tee_supp_rk_fs_process_v1(void *cmd, size_t cmd_size) 1471*d079c1a5SHisping Lin { 1472*d079c1a5SHisping Lin struct tee_fs_rpc *fsrpc = cmd; 1473*d079c1a5SHisping Lin int ret = -1; 1474*d079c1a5SHisping Lin 1475*d079c1a5SHisping Lin if (check_security_exist(0) < 0) { 1476*d079c1a5SHisping Lin printf("TEEC: security partition not exist! unable to use RK FS!\n"); 1477*d079c1a5SHisping Lin return ret; 1478*d079c1a5SHisping Lin } 1479*d079c1a5SHisping Lin 1480*d079c1a5SHisping Lin if (cmd_size < sizeof(struct tee_fs_rpc)) { 1481*d079c1a5SHisping Lin printf(">>>cmd_size < sizeof(struct tee_fs_rpc) !\n"); 1482*d079c1a5SHisping Lin return ret; 1483*d079c1a5SHisping Lin } 1484*d079c1a5SHisping Lin 1485*d079c1a5SHisping Lin if (cmd == NULL) { 1486*d079c1a5SHisping Lin printf(">>>cmd == NULL !\n"); 1487*d079c1a5SHisping Lin return ret; 1488*d079c1a5SHisping Lin } 1489*d079c1a5SHisping Lin 1490*d079c1a5SHisping Lin switch (fsrpc->op) { 1491*d079c1a5SHisping Lin case TEE_FS_OPEN: 1492*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_OPEN !\n", rkss_step++); 1493*d079c1a5SHisping Lin ret = tee_fs_open(fsrpc); 1494*d079c1a5SHisping Lin break; 1495*d079c1a5SHisping Lin case TEE_FS_CLOSE: 1496*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_CLOSE !\n", rkss_step++); 1497*d079c1a5SHisping Lin ret = tee_fs_close(fsrpc); 1498*d079c1a5SHisping Lin break; 1499*d079c1a5SHisping Lin case TEE_FS_READ: 1500*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_READ !\n", rkss_step++); 1501*d079c1a5SHisping Lin ret = tee_fs_read(fsrpc); 1502*d079c1a5SHisping Lin break; 1503*d079c1a5SHisping Lin case TEE_FS_WRITE: 1504*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_WRITE !\n", rkss_step++); 1505*d079c1a5SHisping Lin ret = tee_fs_write(fsrpc); 1506*d079c1a5SHisping Lin break; 1507*d079c1a5SHisping Lin case TEE_FS_SEEK: 1508*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_SEEK !\n", rkss_step++); 1509*d079c1a5SHisping Lin ret = tee_fs_seek(fsrpc); 1510*d079c1a5SHisping Lin break; 1511*d079c1a5SHisping Lin case TEE_FS_UNLINK: 1512*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_UNLINK !\n", rkss_step++); 1513*d079c1a5SHisping Lin ret = tee_fs_unlink(fsrpc); 1514*d079c1a5SHisping Lin break; 1515*d079c1a5SHisping Lin case TEE_FS_RENAME: 1516*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_RENAME !\n", rkss_step++); 1517*d079c1a5SHisping Lin ret = tee_fs_rename(fsrpc); 1518*d079c1a5SHisping Lin break; 1519*d079c1a5SHisping Lin case TEE_FS_TRUNC: 1520*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_TRUNC !\n", rkss_step++); 1521*d079c1a5SHisping Lin ret = tee_fs_truncate(fsrpc); 1522*d079c1a5SHisping Lin break; 1523*d079c1a5SHisping Lin case TEE_FS_MKDIR: 1524*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_MKDIR !\n", rkss_step++); 1525*d079c1a5SHisping Lin ret = tee_fs_mkdir(fsrpc); 1526*d079c1a5SHisping Lin debug(">>>>>>> ret = [%d] ! \n", ret); 1527*d079c1a5SHisping Lin break; 1528*d079c1a5SHisping Lin case TEE_FS_OPENDIR: 1529*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_OPENDIR !\n", rkss_step++); 1530*d079c1a5SHisping Lin ret = tee_fs_opendir(fsrpc); 1531*d079c1a5SHisping Lin break; 1532*d079c1a5SHisping Lin case TEE_FS_CLOSEDIR: 1533*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_CLOSEDIR !\n", rkss_step++); 1534*d079c1a5SHisping Lin ret = tee_fs_closedir(fsrpc); 1535*d079c1a5SHisping Lin break; 1536*d079c1a5SHisping Lin case TEE_FS_READDIR: 1537*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_READDIR !\n", rkss_step++); 1538*d079c1a5SHisping Lin ret = tee_fs_readdir(fsrpc); 1539*d079c1a5SHisping Lin break; 1540*d079c1a5SHisping Lin case TEE_FS_RMDIR: 1541*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_RMDIR !\n", rkss_step++); 1542*d079c1a5SHisping Lin ret = tee_fs_rmdir(fsrpc); 1543*d079c1a5SHisping Lin break; 1544*d079c1a5SHisping Lin case TEE_FS_ACCESS: 1545*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_ACCESS !\n", rkss_step++); 1546*d079c1a5SHisping Lin ret = tee_fs_access(fsrpc); 1547*d079c1a5SHisping Lin break; 1548*d079c1a5SHisping Lin case TEE_FS_LINK: 1549*d079c1a5SHisping Lin debug(">>>>>>> [%d] TEE_FS_LINK !\n", rkss_step++); 1550*d079c1a5SHisping Lin ret = tee_fs_link(fsrpc); 1551*d079c1a5SHisping Lin break; 1552*d079c1a5SHisping Lin default: 1553*d079c1a5SHisping Lin printf(">>>>> DEFAULT !! %d\n", fsrpc->op); 1554*d079c1a5SHisping Lin break; 1555*d079c1a5SHisping Lin } 1556*d079c1a5SHisping Lin 1557*d079c1a5SHisping Lin fsrpc->res = ret; 1558*d079c1a5SHisping Lin debug(">>>>>>> fsrpc->res = [%d] !\n", fsrpc->res); 1559*d079c1a5SHisping Lin 1560*d079c1a5SHisping Lin return ret; 1561*d079c1a5SHisping Lin } 1562*d079c1a5SHisping Lin 1563