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; 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 } 545 } 546 ret = rkss_write_multi_sections(table_data, 0, RKSS_PARTITION_TABLE_COUNT); 547 if (ret < 0) { 548 printf("TEEC: rkss_write_multi_sections failed!!! ret: %d.\n", ret); 549 return TEEC_ERROR_GENERIC; 550 } 551 debug("TEEC: verify ptable success.\n"); 552 return TEEC_SUCCESS; 553 } 554 555 static int rkss_verify_usedflags(struct rk_secure_storage *rkss) 556 { 557 uint8_t *flags = (uint8_t *)rkss->data; 558 int i, duel, flag, n, value, ret; 559 uint8_t *flagw; 560 561 for (i = 0; i < RKSS_PARTITION_TABLE_COUNT + 1; i++) { 562 duel = *(flags + (int)i/2); 563 flag = i & 0x1 ? duel & 0x0F : (duel & 0xF0) >> 4; 564 if (flag != 0x1) { 565 debug("TEEC: init usedflags section ...\n"); 566 memset(rkss->data, 0x00, RKSS_DATA_SECTION_LEN); 567 for (n = 0; n < RKSS_PARTITION_TABLE_COUNT + 1; n++) { 568 flagw = (uint8_t *)rkss->data + (int)n/2; 569 value = 0x1; 570 *flagw = n & 0x1 ? (*flagw & 0xF0) | (value & 0x0F) : 571 (*flagw & 0x0F) | (value << 4); 572 } 573 ret = rkss_write_multi_sections(rkss->data, rkss->index, 1); 574 if (ret < 0) { 575 printf("TEEC: clean usedflags section failed!!! ret: %d.\n", ret); 576 return TEEC_ERROR_GENERIC; 577 } 578 579 return TEEC_SUCCESS; 580 } 581 } 582 debug("TEEC: rkss_verify_usedflags: sucess.\n"); 583 return TEEC_SUCCESS; 584 } 585 586 static int rkss_get_fileinfo_by_index(int fd, struct rkss_file_info *pfileinfo) 587 { 588 int i = fd / RKSS_EACH_SECTION_FILECOUNT; 589 int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i); 590 struct rk_secure_storage rkss = {0}; 591 int ret; 592 void *pdata; 593 struct rkss_file_info *p; 594 595 rkss.index = i; 596 ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 597 if (ret < 0) { 598 printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 599 return TEEC_ERROR_GENERIC; 600 } 601 602 pdata = rkss.data; 603 p = (struct rkss_file_info *)pdata; 604 p += n; 605 606 if (p->used != 1) { 607 debug("TEEC: error: unused section!\n"); 608 return TEEC_ERROR_GENERIC; 609 } 610 debug("TEEC: rkss_get_fileinfo_by_index p->used = %d p->name=%s p->index=%d p->size=%d\n", 611 p->used, p->name, p->index, p->size); 612 memcpy(pfileinfo, p, sizeof(struct rkss_file_info)); 613 614 return TEEC_SUCCESS; 615 } 616 617 static int rkss_get_fileinfo_by_name( 618 char *filename, struct rkss_file_info *pfileinfo) 619 { 620 int i, ret; 621 uint8_t n = 0; 622 unsigned int len; 623 unsigned char *table_data; 624 struct rk_secure_storage rkss = {0}; 625 void *pdata; 626 struct rkss_file_info *p; 627 const char *split = "/"; 628 char *last_inpos; 629 char *last_svpos; 630 char *cur_inpos; 631 char *cur_svpos; 632 int size_in, size_sv; 633 634 len = strlen(filename); 635 if (len > RKSS_MAX_NAME_LENGTH - 1) { 636 printf("TEEC: filename is too long. length:%u\n", len); 637 return TEEC_ERROR_GENERIC; 638 } 639 640 table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 641 if (table_data == NULL) { 642 printf("TEEC: malloc table_data fail\n"); 643 return TEEC_ERROR_GENERIC; 644 } 645 ret = rkss_read_patition_tables(table_data); 646 if (ret < 0) { 647 printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 648 return TEEC_ERROR_GENERIC; 649 } 650 651 for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 652 rkss.index = i; 653 memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); 654 655 for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { 656 pdata = rkss.data; 657 p = (struct rkss_file_info *)pdata; 658 p += n; 659 660 if (p->used == 0) 661 continue; 662 663 /* Full Matching*/ 664 if (!strcmp(p->name, filename)) { 665 debug("TEEC: rkss_get_fileinfo_by_name: hit table[%d/%d], index[%d/%d]\n", 666 i, RKSS_PARTITION_TABLE_COUNT, n, RKSS_EACH_SECTION_FILECOUNT); 667 memcpy(pfileinfo, p, sizeof(struct rkss_file_info)); 668 free(table_data); 669 return i * RKSS_EACH_SECTION_FILECOUNT + n; 670 } 671 672 /* Folder Matching*/ 673 last_inpos = filename; 674 last_svpos = p->name; 675 cur_inpos = NULL; 676 cur_svpos = NULL; 677 do { 678 cur_inpos = strstr(last_inpos, split); 679 cur_svpos = strstr(last_svpos, split); 680 size_in = cur_inpos == NULL ? 681 (int)strlen(last_inpos) : cur_inpos - last_inpos; 682 size_sv = cur_svpos == NULL ? 683 (int)strlen(last_svpos) : cur_svpos - last_svpos; 684 685 ret = memcmp(last_inpos, last_svpos, size_in); 686 last_inpos = cur_inpos + 1; 687 last_svpos = cur_svpos + 1; 688 689 if (size_in != size_sv || ret) 690 goto UNMATCHFOLDER; 691 692 } while (cur_inpos && cur_svpos); 693 694 debug("TEEC: Matched folder: %s\n", p->name); 695 free(table_data); 696 return TEEC_ERROR_GENERIC; 697 UNMATCHFOLDER: 698 debug("TEEC: Unmatched ...\n"); 699 } 700 } 701 debug("TEEC: rkss_get_fileinfo_by_name: file or dir no found!\n"); 702 free(table_data); 703 return TEEC_ERROR_GENERIC; 704 } 705 706 static int rkss_get_dirs_by_name(char *filename) 707 { 708 int i, ret; 709 uint8_t n = 0; 710 unsigned int len; 711 unsigned char *table_data; 712 struct rk_secure_storage rkss = {0}; 713 void *pdata; 714 struct rkss_file_info *p; 715 char *chk, *file, *subdir; 716 717 len = strlen(filename); 718 if (len > RKSS_MAX_NAME_LENGTH - 1) { 719 printf("TEEC: filename is too long. length:%u\n", len); 720 return TEEC_ERROR_GENERIC; 721 } 722 723 table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 724 if (table_data == NULL) { 725 printf("TEEC: malloc table_data fail\n"); 726 return TEEC_ERROR_GENERIC; 727 } 728 ret = rkss_read_patition_tables(table_data); 729 if (ret < 0) { 730 printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 731 return TEEC_ERROR_GENERIC; 732 } 733 734 dir_num = 0; 735 for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 736 rkss.index = i; 737 memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); 738 739 for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { 740 pdata = rkss.data; 741 p = (struct rkss_file_info *)pdata; 742 p += n; 743 744 if (p->used == 0) 745 continue; 746 747 /* Full Matching*/ 748 ret = memcmp(p->name, filename, strlen(filename)); 749 debug("TEEC: comparing [fd:%d] : %s ?= %s , ret:%d\n", 750 i*RKSS_EACH_SECTION_FILECOUNT+n, p->name, filename, ret); 751 if (!ret && strlen(p->name) > strlen(filename)) { 752 chk = p->name + strlen(filename); 753 if (*chk == '/') { 754 file = p->name + strlen(filename) + 1; 755 subdir = strtok(file, "/"); 756 debug("TEEC: found: %s\n", subdir); 757 strcpy(dir_cache[dir_num], subdir); 758 ++dir_num; 759 } 760 } 761 } 762 } 763 free(table_data); 764 return dir_num; 765 } 766 767 static int rkss_get_empty_section_from_usedflags(int section_size) 768 { 769 struct rk_secure_storage rkss = {0}; 770 int i, ret; 771 int count0 = 0; 772 uint8_t *flag; 773 uint8_t value; 774 775 rkss.index = RKSS_USED_FLAGS_INDEX; 776 ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 777 if (ret < 0) { 778 printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 779 return TEEC_ERROR_GENERIC; 780 } 781 782 for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) { 783 flag = (uint8_t *)rkss.data + (int)i/2; 784 value = i & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; 785 786 if (value == 0x0) { 787 if (++count0 == section_size) { 788 return (i + 1 - section_size); 789 } 790 } else { 791 count0 = 0; 792 } 793 } 794 795 printf("TEEC: Not enough space available in secure storage !\n"); 796 return TEEC_ERROR_GENERIC; 797 } 798 799 static int rkss_incref_multi_usedflags_sections(unsigned int index, unsigned int num) 800 { 801 struct rk_secure_storage rkss = {0}; 802 int ret, value, i; 803 uint8_t *flag; 804 805 if ((index + num) >= RKSS_DATA_SECTION_COUNT) { 806 printf("TEEC: index[%d] out of range.\n", index); 807 return TEEC_ERROR_GENERIC; 808 } 809 810 rkss.index = RKSS_USED_FLAGS_INDEX; 811 ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 812 if (ret < 0) { 813 printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 814 return TEEC_ERROR_GENERIC; 815 } 816 817 for (i = 0; i < num; i++, index++) { 818 flag = (uint8_t *)rkss.data + (int)index/2; 819 value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; 820 if (++value > 0xF) { 821 printf("TEEC: reference out of data: %d\n", value); 822 value = 0xF; 823 } 824 *flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) : 825 (*flag & 0x0F) | (value << 4); 826 } 827 ret = rkss_write_multi_sections(rkss.data, rkss.index, 1); 828 if (ret < 0) { 829 printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret); 830 return TEEC_ERROR_GENERIC; 831 } 832 return TEEC_SUCCESS; 833 } 834 835 static int rkss_decref_multi_usedflags_sections(unsigned int index, unsigned int num) 836 { 837 struct rk_secure_storage rkss = {0}; 838 int ret, value, i; 839 uint8_t *flag; 840 841 if ((index + num) >= RKSS_DATA_SECTION_COUNT) { 842 printf("TEEC: index[%d] out of range.\n", index); 843 return TEEC_ERROR_GENERIC; 844 } 845 846 rkss.index = RKSS_USED_FLAGS_INDEX; 847 ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 848 if (ret < 0) { 849 printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 850 return TEEC_ERROR_GENERIC; 851 } 852 for (i = 0; i < num; i++, index++) { 853 flag = (uint8_t *)rkss.data + (int)index/2; 854 value = index & 0x1 ? *flag & 0x0F : (*flag & 0xF0) >> 4; 855 if (--value < 0) { 856 printf("TEEC: reference out of data: %d\n", value); 857 value = 0x0; 858 } 859 *flag = index & 0x1 ? (*flag & 0xF0) | (value & 0x0F) : 860 (*flag & 0x0F) | (value << 4); 861 } 862 ret = rkss_write_multi_sections(rkss.data, rkss.index, 1); 863 if (ret < 0) { 864 printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret); 865 return TEEC_ERROR_GENERIC; 866 } 867 return TEEC_SUCCESS; 868 } 869 870 static int rkss_write_empty_ptable(struct rkss_file_info *pfileinfo) 871 { 872 unsigned char *table_data; 873 int ret, i, n; 874 struct rk_secure_storage rkss = {0}; 875 void *pdata; 876 struct rkss_file_info *p; 877 878 table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 879 if (table_data == NULL) { 880 printf("TEEC: malloc table_data fail\n"); 881 return TEEC_ERROR_GENERIC; 882 } 883 884 ret = rkss_read_patition_tables(table_data); 885 if (ret < 0) { 886 printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 887 return TEEC_ERROR_GENERIC; 888 } 889 890 for (i = 0; i < RKSS_PARTITION_TABLE_COUNT; i++) { 891 rkss.index = i; 892 memcpy(rkss.data, table_data + rkss.index * RKSS_DATA_SECTION_LEN, RKSS_DATA_SECTION_LEN); 893 for (n = 0; n < RKSS_EACH_SECTION_FILECOUNT; n++) { 894 pdata = rkss.data; 895 p = (struct rkss_file_info *)pdata; 896 p += n; 897 if (p->used == 0) { 898 debug("TEEC: write ptable in [%d][%d] .\n", i, n); 899 memcpy(p, pfileinfo, sizeof(struct rkss_file_info)); 900 p->used = 1; 901 p->id = n; 902 debug("TEEC: write emt ptable : [%d,%d] name:%s, index:%d,\n", 903 i, n, p->name, p->index); 904 debug("TEEC: size:%d, used:%d\n", p->size, p->used); 905 ret = rkss_write_multi_sections(rkss.data, rkss.index, 1); 906 if (ret < 0) { 907 printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret); 908 free(table_data); 909 return TEEC_ERROR_GENERIC; 910 } 911 912 free(table_data); 913 return i * RKSS_EACH_SECTION_FILECOUNT + n; 914 } 915 } 916 } 917 debug("TEEC: No enough ptable space available in secure storage.\n"); 918 free(table_data); 919 return TEEC_ERROR_GENERIC; 920 } 921 922 static int rkss_write_back_ptable(int fd, struct rkss_file_info *pfileinfo) 923 { 924 int i = fd / RKSS_EACH_SECTION_FILECOUNT; 925 int n = fd - (RKSS_EACH_SECTION_FILECOUNT * i); 926 struct rk_secure_storage rkss = {0}; 927 int ret; 928 void *pdata; 929 struct rkss_file_info *p; 930 931 rkss.index = i; 932 ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 933 if (ret < 0) { 934 printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 935 return TEEC_ERROR_GENERIC; 936 } 937 938 pdata = rkss.data; 939 p = (struct rkss_file_info *)pdata; 940 p += n; 941 942 memcpy(p, pfileinfo, sizeof(struct rkss_file_info)); 943 debug("TEEC: write ptable : [%d,%d] name:%s, index:%d, size:%d, used:%d\n", 944 i, n, p->name, p->index, p->size, p->used); 945 946 ret = rkss_write_multi_sections(rkss.data, rkss.index, 1); 947 if (ret < 0) { 948 printf("TEEC: rkss_write_multi_sections fail ! ret: %d.\n", ret); 949 return TEEC_ERROR_GENERIC; 950 } 951 #ifdef DEBUG_RKFSS 952 rkss_dump_ptable(); 953 #endif 954 955 return TEEC_SUCCESS; 956 } 957 958 static uint32_t ree_fs_new_open(size_t num_params, 959 struct tee_ioctl_param *params) 960 { 961 char *filename; 962 int fd; 963 struct rkss_file_info p = {0}; 964 965 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 966 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 967 968 filename = (char *)(size_t)params[1].u.memref.shm_id; 969 if (!filename) 970 return TEEC_ERROR_BAD_PARAMETERS; 971 972 if (strlen(filename) > RKSS_MAX_NAME_LENGTH) { 973 printf("TEEC: ree_fs_new_open: file name too long. %s\n", filename); 974 return TEEC_ERROR_BAD_PARAMETERS; 975 } 976 977 debug("TEEC: ree_fs_new_open open file: %s, len: %zu\n", filename, strlen(filename)); 978 fd = rkss_get_fileinfo_by_name(filename, &p); 979 if (fd < 0) { 980 debug("TEEC: ree_fs_new_open : no such file. %s\n", filename); 981 return TEEC_ERROR_ITEM_NOT_FOUND; 982 } 983 984 debug("TEEC: ree_fs_new_open! %s, fd: %d\n", filename, fd); 985 986 params[2].u.value.a = fd; 987 return TEEC_SUCCESS; 988 } 989 990 static TEEC_Result ree_fs_new_create(size_t num_params, 991 struct tee_ioctl_param *params) 992 { 993 char *filename; 994 int fd; 995 int ret, num; 996 struct rkss_file_info p = {0}; 997 /* file open flags: O_RDWR | O_CREAT | O_TRUNC 998 * if file exists, we must remove it first. 999 */ 1000 ret = rkss_begin_commit(); 1001 if (ret < 0) { 1002 printf("TEEC: rkss_begin_commit failed!"); 1003 return -1; 1004 } 1005 1006 filename = (char *)(size_t)params[1].u.memref.shm_id; 1007 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 1008 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 1009 if (!filename) 1010 return TEEC_ERROR_BAD_PARAMETERS; 1011 1012 if (strlen(filename) > RKSS_MAX_NAME_LENGTH) { 1013 printf("TEEC: ree_fs_new_create: file name too long. %s\n", filename); 1014 return TEEC_ERROR_BAD_PARAMETERS; 1015 } 1016 1017 debug("TEEC: ree_fs_new_create create file: %s, len: %zu\n", filename, strlen(filename)); 1018 fd = rkss_get_fileinfo_by_name(filename, &p); 1019 if (fd >= 0) { 1020 debug("TEEC: ree_fs_new_create : file exist, clear it. %s\n", filename); 1021 /* decrease ref from usedflags */ 1022 num = p.size / RKSS_DATA_SECTION_LEN + 1; 1023 ret = rkss_decref_multi_usedflags_sections(p.index, num); 1024 if (ret < 0) { 1025 printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); 1026 return TEEC_ERROR_GENERIC; 1027 } 1028 1029 /* rm from ptable */ 1030 memset(&p, 0, sizeof(struct rkss_file_info)); 1031 ret = rkss_write_back_ptable(fd, &p); 1032 if (ret < 0) { 1033 printf("TEEC: ree_fs_new_create : write back error %d\n", ret); 1034 return TEEC_ERROR_GENERIC; 1035 } 1036 } 1037 1038 debug("TEEC: ree_fs_new_create create new file: %s\n", filename); 1039 strcpy(p.name, filename); 1040 p.index = 0; 1041 p.size = 0; 1042 p.used = 1; 1043 p.flags = RK_FS_R | RK_FS_W; 1044 fd = rkss_write_empty_ptable(&p); 1045 if (fd < 0) { 1046 printf("TEEC: ree_fs_new_create : write empty ptable error. %s\n", filename); 1047 return TEEC_ERROR_GENERIC; 1048 } 1049 1050 debug("TEEC: ree_fs_new_create ! %s, fd: %d.\n", filename, fd); 1051 1052 params[2].u.value.a = fd; 1053 1054 ret = rkss_finish_commit(); 1055 if (ret < 0) { 1056 printf("TEEC: rkss_finish_commit failed!"); 1057 return -1; 1058 } 1059 return TEEC_SUCCESS; 1060 } 1061 1062 static TEEC_Result ree_fs_new_close(size_t num_params, 1063 struct tee_ioctl_param *params) 1064 { 1065 debug("TEEC: ree_fs_new_close !\n"); 1066 UNREFERENCED_PARAMETER(params); 1067 UNREFERENCED_PARAMETER(num_params); 1068 return TEEC_SUCCESS; 1069 } 1070 1071 static TEEC_Result ree_fs_new_read(size_t num_params, 1072 struct tee_ioctl_param *params) 1073 { 1074 uint8_t *data; 1075 size_t len; 1076 off_t offs; 1077 int fd; 1078 int ret; 1079 struct rkss_file_info p = {0}; 1080 int di, section_num; 1081 uint8_t *temp_file_data; 1082 1083 fd = params[0].u.value.b; 1084 offs = params[0].u.value.c; 1085 1086 data = (uint8_t *)(size_t)params[1].u.memref.shm_id; 1087 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 1088 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 1089 1090 if (!data) 1091 return TEEC_ERROR_BAD_PARAMETERS; 1092 len = params[1].u.memref.size; 1093 1094 debug("TEEC: ree_fs_new_read! fd:%d, len:%zu, offs:%ld\n", fd, len, offs); 1095 1096 ret = rkss_get_fileinfo_by_index(fd, &p); 1097 if (ret < 0) { 1098 debug("TEEC: unavailable fd: %d!\n", fd); 1099 return TEEC_ERROR_GENERIC; 1100 } 1101 1102 if (offs >= p.size) 1103 return TEEC_ERROR_BAD_PARAMETERS; 1104 1105 section_num = p.size / RKSS_DATA_SECTION_LEN + 1; 1106 temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN); 1107 ret = rkss_read_multi_sections(temp_file_data, p.index, section_num); 1108 if (ret < 0) { 1109 printf("TEEC: unavailable file index!\n"); 1110 free(temp_file_data); 1111 return TEEC_ERROR_GENERIC; 1112 } 1113 di = (offs + len) > p.size ? (p.size - offs) : len; 1114 memcpy(data, temp_file_data + offs, di); 1115 free(temp_file_data); 1116 temp_file_data = 0; 1117 params[1].u.memref.size = di; 1118 1119 return TEEC_SUCCESS; 1120 } 1121 1122 static TEEC_Result ree_fs_new_write(size_t num_params, 1123 struct tee_ioctl_param *params) 1124 { 1125 uint8_t *data; 1126 size_t len; 1127 off_t offs; 1128 struct rkss_file_info p = {0}; 1129 int ret, fd, new_size; 1130 int section_num; 1131 uint8_t *file_data = 0, *temp_file_data = 0; 1132 1133 ret = rkss_begin_commit(); 1134 if (ret < 0) { 1135 printf("TEEC: rkss_begin_commit failed!"); 1136 return -1; 1137 } 1138 1139 fd = params[0].u.value.b; 1140 offs = params[0].u.value.c; 1141 1142 data = (uint8_t *)(size_t)params[1].u.memref.shm_id; 1143 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 1144 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 1145 if (!data) 1146 return TEEC_ERROR_BAD_PARAMETERS; 1147 len = params[1].u.memref.size; 1148 1149 debug("TEEC: ree_fs_new_write ! fd:%d, len:%zu, offs:%ld \n", fd, len, offs); 1150 1151 ret = rkss_get_fileinfo_by_index(fd, &p); 1152 if (ret < 0) { 1153 printf("TEEC: ree_fs_new_write: fd:%d unvailable!\n", fd); 1154 return TEEC_ERROR_BAD_PARAMETERS; 1155 } 1156 1157 new_size = offs + len > p.size ? offs + len : p.size; 1158 file_data = malloc(new_size); 1159 if (!file_data) 1160 return TEEC_ERROR_OUT_OF_MEMORY; 1161 1162 if (p.size != 0) { 1163 /* Read old file data out */ 1164 section_num = p.size / RKSS_DATA_SECTION_LEN + 1; 1165 temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN); 1166 ret = rkss_read_multi_sections(temp_file_data, p.index, section_num); 1167 if (ret < 0) { 1168 printf("TEEC: unavailable file index %d section_num %d\n", p.index, section_num); 1169 ret = TEEC_ERROR_GENERIC; 1170 goto out; 1171 } 1172 memcpy(file_data, temp_file_data, p.size); 1173 free(temp_file_data); 1174 temp_file_data = 0; 1175 ret = rkss_decref_multi_usedflags_sections(p.index, section_num); 1176 if (ret < 0) { 1177 printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); 1178 ret = TEEC_ERROR_GENERIC; 1179 goto out; 1180 } 1181 } 1182 1183 /* update new file info */ 1184 memcpy(file_data + offs, data, len); 1185 p.size = new_size; 1186 section_num = new_size / RKSS_DATA_SECTION_LEN + 1; 1187 p.index = rkss_get_empty_section_from_usedflags(section_num); 1188 debug("TEEC: Get Empty section in %d\n", p.index); 1189 p.used = 1; 1190 ret = rkss_incref_multi_usedflags_sections(p.index, section_num); 1191 if (ret < 0) { 1192 printf("TEEC: rkss_incref_multi_usedflags_sections error !\n"); 1193 ret = TEEC_ERROR_GENERIC; 1194 goto out; 1195 } 1196 1197 ret = rkss_write_back_ptable(fd, &p); 1198 if (ret < 0) { 1199 printf("TEEC: ree_fs_new_write: write ptable error!\n"); 1200 ret = TEEC_ERROR_GENERIC; 1201 goto out; 1202 } 1203 1204 /* write new file data */ 1205 temp_file_data = malloc(section_num * RKSS_DATA_SECTION_LEN); 1206 memset(temp_file_data, 0, section_num * RKSS_DATA_SECTION_LEN); 1207 memcpy(temp_file_data, file_data, p.size); 1208 rkss_write_multi_sections(temp_file_data, p.index, section_num); 1209 free(temp_file_data); 1210 temp_file_data = 0; 1211 1212 #ifdef DEBUG_RKFSS 1213 rkss_dump_usedflags(); 1214 #endif 1215 1216 out: 1217 if (file_data) 1218 free(file_data); 1219 if (temp_file_data) { 1220 free(temp_file_data); 1221 temp_file_data = 0; 1222 } 1223 ret = rkss_finish_commit(); 1224 if (ret < 0) { 1225 printf("TEEC: rkss_finish_commit failed!"); 1226 return -1; 1227 } 1228 1229 return TEEC_SUCCESS; 1230 } 1231 1232 /* TODO: update file data space */ 1233 static TEEC_Result ree_fs_new_truncate(size_t num_params, 1234 struct tee_ioctl_param *params) 1235 { 1236 size_t len; 1237 int fd, ret; 1238 struct rkss_file_info p = {0}; 1239 unsigned int section_num_old, section_num_new; 1240 1241 ret = rkss_begin_commit(); 1242 if (ret < 0) { 1243 printf("TEEC: rkss_begin_commit failed!"); 1244 return -1; 1245 } 1246 1247 fd = params[0].u.value.b; 1248 len = params[0].u.value.c; 1249 1250 debug("TEEC: ree_fs_new_truncate: fd:%d, lenth:%zu\n", fd, len); 1251 1252 ret = rkss_get_fileinfo_by_index(fd, &p); 1253 if (ret < 0) { 1254 printf("TEEC: fd:%d unvailable!\n", fd); 1255 return TEEC_ERROR_GENERIC; 1256 } 1257 if (len > p.size) { 1258 printf("TEEC: truncate error!\n"); 1259 return TEEC_ERROR_GENERIC; 1260 } 1261 section_num_old = p.size / RKSS_DATA_SECTION_LEN + 1; 1262 section_num_new = len / RKSS_DATA_SECTION_LEN + 1; 1263 ret = rkss_decref_multi_usedflags_sections(p.index + section_num_new, section_num_old - section_num_new); 1264 if (ret < 0) { 1265 printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); 1266 ret = TEEC_ERROR_GENERIC; 1267 } 1268 p.size = len; 1269 ret = rkss_write_back_ptable(fd, &p); 1270 if (ret < 0) { 1271 printf("TEEC: ree_fs_new_truncate: write ptable error!\n"); 1272 return TEEC_ERROR_GENERIC; 1273 } 1274 ret = rkss_finish_commit(); 1275 if (ret < 0) { 1276 printf("TEEC: rkss_finish_commit failed!"); 1277 return -1; 1278 } 1279 1280 return TEEC_SUCCESS; 1281 } 1282 1283 static TEEC_Result ree_fs_new_remove(size_t num_params, 1284 struct tee_ioctl_param *params) 1285 { 1286 char *filename; 1287 struct rkss_file_info p = {0}; 1288 int ret, fd, num; 1289 1290 ret = rkss_begin_commit(); 1291 if (ret < 0) { 1292 printf("TEEC: rkss_begin_commit failed!"); 1293 return -1; 1294 } 1295 1296 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 1297 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 1298 1299 filename = (char *)(size_t)params[1].u.memref.shm_id; 1300 if (!filename) 1301 return TEEC_ERROR_BAD_PARAMETERS; 1302 1303 ret = rkss_get_fileinfo_by_name(filename, &p); 1304 if (ret < 0) { 1305 printf("TEEC: ree_fs_new_remove: no such file. %s\n", filename); 1306 return 0; 1307 } 1308 fd = ret; 1309 1310 debug("TEEC: ree_fs_new_remove! %s fd:%d index:%d size:%d\n", filename, fd, p.index, p.size); 1311 1312 /* decrease ref from usedflags */ 1313 num = p.size / RKSS_DATA_SECTION_LEN + 1; 1314 ret = rkss_decref_multi_usedflags_sections(p.index, num); 1315 if (ret < 0) { 1316 printf("TEEC: rkss_decref_multi_usedflags_sections error !\n"); 1317 return TEEC_ERROR_GENERIC; 1318 } 1319 1320 /* rm from ptable */ 1321 memset(&p, 0, sizeof(struct rkss_file_info)); 1322 ret = rkss_write_back_ptable(fd, &p); 1323 if (ret < 0) { 1324 printf("TEEC: ree_fs_new_remove: write back error %d\n", ret); 1325 return TEEC_ERROR_GENERIC; 1326 } 1327 1328 #ifdef DEBUG_RKFSS 1329 rkss_dump_ptable(); 1330 rkss_dump_usedflags(); 1331 #endif 1332 ret = rkss_finish_commit(); 1333 if (ret < 0) { 1334 printf("TEEC: rkss_finish_commit failed!"); 1335 return -1; 1336 } 1337 1338 return TEEC_SUCCESS; 1339 } 1340 1341 static TEEC_Result ree_fs_new_rename(size_t num_params, 1342 struct tee_ioctl_param *params) 1343 { 1344 char *old_fname; 1345 char *new_fname; 1346 struct rkss_file_info p = {0}; 1347 int ret; 1348 1349 ret = rkss_begin_commit(); 1350 if (ret < 0) { 1351 printf("TEEC: rkss_begin_commit failed!"); 1352 return -1; 1353 } 1354 1355 old_fname = (char *)(size_t)params[1].u.memref.shm_id; 1356 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 1357 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 1358 if (!old_fname) 1359 return TEEC_ERROR_BAD_PARAMETERS; 1360 1361 new_fname = (char *)(size_t)params[2].u.memref.shm_id; 1362 debug("TEEC: params[2].u.memref.shm_id = 0x%llx params[2].u.memref.shm_offs = 0x%llx\n", 1363 params[2].u.memref.shm_id, params[2].u.memref.shm_offs); 1364 if (!new_fname) 1365 return TEEC_ERROR_BAD_PARAMETERS; 1366 1367 if (strlen(new_fname) > RKSS_MAX_NAME_LENGTH) { 1368 printf("TEEC: new file name too long. %s\n", new_fname); 1369 return TEEC_ERROR_BAD_PARAMETERS; 1370 } 1371 1372 debug("TEEC: rename: %s -> %s\n", old_fname, new_fname); 1373 1374 ret = rkss_get_fileinfo_by_name(old_fname, &p); 1375 if (ret < 0) { 1376 printf("TEEC: filename: %s no found.\n", old_fname); 1377 return TEEC_ERROR_ITEM_NOT_FOUND; 1378 } 1379 1380 strcpy(p.name, new_fname); 1381 1382 ret = rkss_write_back_ptable(ret, &p); 1383 if (ret < 0) { 1384 printf("TEEC: write ptable error!\n"); 1385 return TEEC_ERROR_GENERIC; 1386 } 1387 ret = rkss_finish_commit(); 1388 if (ret < 0) { 1389 printf("TEEC: rkss_finish_commit failed!"); 1390 return -1; 1391 } 1392 1393 return TEEC_SUCCESS; 1394 } 1395 1396 static TEEC_Result ree_fs_new_opendir(size_t num_params, 1397 struct tee_ioctl_param *params) 1398 { 1399 char *dirname; 1400 int ret; 1401 1402 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 1403 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 1404 1405 dirname = (char *)(size_t)params[1].u.memref.shm_id; 1406 if (!dirname) 1407 return TEEC_ERROR_BAD_PARAMETERS; 1408 1409 dir_seek = 0; 1410 ret = rkss_get_dirs_by_name(dirname); 1411 if (ret < 0) { 1412 printf("TEEC: ree_fs_new_opendir: error\n"); 1413 return TEEC_ERROR_GENERIC; 1414 } 1415 1416 debug("TEEC: ree_fs_new_opendir: %s, seek/num:%d/%d\n", dirname, dir_seek, dir_num); 1417 return TEEC_SUCCESS; 1418 } 1419 1420 static TEEC_Result ree_fs_new_closedir(size_t num_params, 1421 struct tee_ioctl_param *params) 1422 { 1423 if (num_params != 1 || 1424 (params[0].attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) != 1425 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT) 1426 return TEEC_ERROR_BAD_PARAMETERS; 1427 1428 dir_seek = 0; 1429 dir_num = 0; 1430 1431 return TEEC_SUCCESS; 1432 } 1433 1434 static TEEC_Result ree_fs_new_readdir(size_t num_params, 1435 struct tee_ioctl_param *params) 1436 { 1437 char *dirname; 1438 size_t len; 1439 size_t dirname_len; 1440 1441 dirname = (char *)(size_t)params[1].u.memref.shm_id; 1442 debug("TEEC: params[1].u.memref.shm_id = 0x%llx params[1].u.memref.shm_offs = 0x%llx\n", 1443 params[1].u.memref.shm_id, params[1].u.memref.shm_offs); 1444 if (!dirname) 1445 return TEEC_ERROR_BAD_PARAMETERS; 1446 len = params[1].u.memref.size; 1447 1448 debug("TEEC: seek/num:%d/%d\n", dir_seek, dir_num); 1449 if (dir_seek == dir_num) { 1450 params[1].u.memref.size = 0; 1451 debug("ree_fs_new_readdir: END \n"); 1452 return TEEC_ERROR_BAD_STATE; 1453 } 1454 1455 dirname_len = strlen(dir_cache[dir_seek]) + 1; 1456 params[1].u.memref.size = dirname_len; 1457 if (dirname_len > len) 1458 return TEEC_ERROR_SHORT_BUFFER; 1459 1460 strcpy(dirname, dir_cache[dir_seek]); 1461 ++dir_seek; 1462 1463 debug("TEEC: ree_fs_new_readdir: %s\n", dirname); 1464 1465 return TEEC_SUCCESS; 1466 } 1467 1468 int tee_supp_rk_fs_init_v1(void) 1469 { 1470 assert(sizeof(struct rkss_file_info) == 126); 1471 assert(512 / sizeof(struct rkss_file_info) == RKSS_EACH_SECTION_FILECOUNT); 1472 1473 int ret; 1474 struct rk_secure_storage rkss = {0}; 1475 unsigned char *table_data; 1476 1477 if (check_security_exist(0) < 0) 1478 return 0; 1479 1480 ret = rkss_resume(); 1481 if (ret < 0) { 1482 printf("rkss_resume failed!"); 1483 return TEEC_ERROR_GENERIC; 1484 } 1485 1486 /* clean secure storage*/ 1487 #ifdef DEBUG_CLEAN_RKSS 1488 int i = 0; 1489 for (i = 0; i < RKSS_DATA_SECTION_COUNT; i++) { 1490 memset(rkss.data, 0, RKSS_DATA_SECTION_LEN); 1491 rkss.index = i; 1492 rkss_write_multi_sections(rkss.data, rkss.index, 1); 1493 printf("TEEC: cleaned [%d]", i); 1494 } 1495 #endif 1496 ret = rkss_begin_commit(); 1497 if (ret < 0) { 1498 printf("TEEC: rkss_begin_commit failed!"); 1499 return TEEC_ERROR_GENERIC; 1500 } 1501 1502 table_data = malloc(RKSS_DATA_SECTION_LEN * RKSS_PARTITION_TABLE_COUNT); 1503 if (table_data == NULL) { 1504 printf("TEEC: malloc table_data fail\n"); 1505 return TEEC_ERROR_GENERIC; 1506 } 1507 ret = rkss_read_patition_tables(table_data); 1508 if (ret < 0) { 1509 printf("TEEC: rkss_read_patition_tables fail ! ret: %d.\n", ret); 1510 return TEEC_ERROR_GENERIC; 1511 } 1512 1513 /* Verify Partition Table*/ 1514 rkss_verify_ptable(table_data); 1515 free(table_data); 1516 table_data = NULL; 1517 1518 /* Verify Usedflags Section*/ 1519 rkss.index = RKSS_USED_FLAGS_INDEX; 1520 ret = rkss_read_multi_sections(rkss.data, rkss.index, 1); 1521 if (ret < 0) { 1522 printf("TEEC: rkss_read_multi_sections fail ! ret: %d.\n", ret); 1523 return TEEC_ERROR_GENERIC; 1524 } 1525 ret = rkss_verify_usedflags(&rkss); 1526 if (ret < 0) { 1527 printf("TEEC: rkss_verify_usedflags fail ! ret: %d.\n", ret); 1528 return TEEC_ERROR_GENERIC; 1529 } 1530 1531 #ifdef DEBUG_RKFSS 1532 rkss_dump_ptable(); 1533 rkss_dump_usedflags(); 1534 #endif 1535 1536 ret = rkss_finish_commit(); 1537 if (ret < 0) { 1538 printf("TEEC: rkss_finish_commit failed!"); 1539 return TEEC_ERROR_GENERIC; 1540 } 1541 1542 return TEEC_SUCCESS; 1543 } 1544 1545 static bool tee_supp_param_is_value(struct tee_ioctl_param *param) 1546 { 1547 switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { 1548 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: 1549 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: 1550 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: 1551 return true; 1552 default: 1553 return false; 1554 } 1555 } 1556 1557 static int rkss_step; 1558 int tee_supp_rk_fs_process_v1(size_t num_params, 1559 struct tee_ioctl_param *params) 1560 { 1561 if (!num_params || !tee_supp_param_is_value(params)) 1562 return TEEC_ERROR_BAD_PARAMETERS; 1563 1564 switch (params->u.value.a) { 1565 case OPTEE_MRF_OPEN: 1566 debug(">>>>>>> [%d] OPTEE_MRF_OPEN!\n", rkss_step++); 1567 return ree_fs_new_open(num_params, params); 1568 case OPTEE_MRF_CREATE: 1569 debug(">>>>>>> [%d] OPTEE_MRF_CREATE!\n", rkss_step++); 1570 return ree_fs_new_create(num_params, params); 1571 case OPTEE_MRF_CLOSE: 1572 debug(">>>>>>> [%d] OPTEE_MRF_CLOSE!\n", rkss_step++); 1573 return ree_fs_new_close(num_params, params); 1574 case OPTEE_MRF_READ: 1575 debug(">>>>>>> [%d] OPTEE_MRF_READ!\n", rkss_step++); 1576 return ree_fs_new_read(num_params, params); 1577 case OPTEE_MRF_WRITE: 1578 debug(">>>>>>> [%d] OPTEE_MRF_WRITE!\n", rkss_step++); 1579 return ree_fs_new_write(num_params, params); 1580 case OPTEE_MRF_TRUNCATE: 1581 debug(">>>>>>> [%d] OPTEE_MRF_TRUNCATE!\n", rkss_step++); 1582 return ree_fs_new_truncate(num_params, params); 1583 case OPTEE_MRF_REMOVE: 1584 debug(">>>>>>> [%d] OPTEE_MRF_REMOVE!\n", rkss_step++); 1585 return ree_fs_new_remove(num_params, params); 1586 case OPTEE_MRF_RENAME: 1587 debug(">>>>>>> [%d] OPTEE_MRF_RENAME!\n", rkss_step++); 1588 return ree_fs_new_rename(num_params, params); 1589 case OPTEE_MRF_OPENDIR: 1590 debug(">>>>>>> [%d] OPTEE_MRF_OPENDIR!\n", rkss_step++); 1591 return ree_fs_new_opendir(num_params, params); 1592 case OPTEE_MRF_CLOSEDIR: 1593 debug(">>>>>>> [%d] OPTEE_MRF_CLOSEDIR!\n", rkss_step++); 1594 return ree_fs_new_closedir(num_params, params); 1595 case OPTEE_MRF_READDIR: 1596 debug(">>>>>>> [%d] OPTEE_MRF_READDIR!\n", rkss_step++); 1597 return ree_fs_new_readdir(num_params, params); 1598 default: 1599 return TEEC_ERROR_BAD_PARAMETERS; 1600 } 1601 } 1602