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