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