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