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