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