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