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
check_security_exist(int print_flag)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
rkss_verify_usedflags(unsigned int area_index)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
rkss_storage_delete(uint32_t area_index)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
rkss_storage_reset(void)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
rkss_dump(void * data,unsigned int len)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
rkss_dump_ptable(void)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
rkss_dump_usedflags(void)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
rkss_read_multi_sections(unsigned int area_index,unsigned char * data,unsigned long index,unsigned int num)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
rkss_write_multi_sections(unsigned int area_index,unsigned char * data,unsigned long index,unsigned int num)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
rkss_get_fileinfo_by_index(int fd,struct rkss_file_table * ptable,unsigned int * out_area_index)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
rkss_get_fileinfo_by_name(char * filename,struct rkss_file_table * ptable,unsigned int * out_area_index)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
rkss_get_dirs_by_name(char * filename)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
rkss_get_empty_section_from_usedflags(unsigned int area_index,int section_size)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
rkss_incref_multi_usedflags_sections(unsigned int area_index,unsigned int index,unsigned int num)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
rkss_decref_multi_usedflags_sections(unsigned int area_index,unsigned int index,unsigned int num)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
rkss_get_remain_tables(struct rkss_file_table * p)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
rkss_get_remain_flags(uint8_t * flags)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
rkss_get_larger_area(void)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
rkss_write_area_empty_ptable(unsigned int area_index,struct rkss_file_table * pfile_table)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
rkss_write_empty_ptable(struct rkss_file_table * pfile_table)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
rkss_write_back_ptable(int fd,struct rkss_file_table * pfile_table)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
rkss_storage_write(void)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
rkss_storage_init(uint32_t area_index)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
ree_fs_new_open(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_create(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_close(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_read(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_write(size_t num_params,struct tee_ioctl_param * params)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 */
ree_fs_new_truncate(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_remove(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_rename(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_opendir(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_closedir(size_t num_params,struct tee_ioctl_param * params)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
ree_fs_new_readdir(size_t num_params,struct tee_ioctl_param * params)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
tee_supp_rk_fs_init_v2(void)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
tee_supp_param_is_value(struct tee_ioctl_param * param)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;
tee_supp_rk_fs_process_v2(size_t num_params,struct tee_ioctl_param * params)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 break;
1388 case OPTEE_MRF_READ:
1389 debug(">>>>>>> [%d] OPTEE_MRF_READ!\n", rkss_step++);
1390 ret = ree_fs_new_read(num_params, params);
1391 break;
1392 case OPTEE_MRF_WRITE:
1393 debug(">>>>>>> [%d] OPTEE_MRF_WRITE!\n", rkss_step++);
1394 ret = ree_fs_new_write(num_params, params);
1395 break;
1396 case OPTEE_MRF_TRUNCATE:
1397 debug(">>>>>>> [%d] OPTEE_MRF_TRUNCATE!\n", rkss_step++);
1398 ret = ree_fs_new_truncate(num_params, params);
1399 break;
1400 case OPTEE_MRF_REMOVE:
1401 debug(">>>>>>> [%d] OPTEE_MRF_REMOVE!\n", rkss_step++);
1402 ret = ree_fs_new_remove(num_params, params);
1403 break;
1404 case OPTEE_MRF_RENAME:
1405 debug(">>>>>>> [%d] OPTEE_MRF_RENAME!\n", rkss_step++);
1406 ret = ree_fs_new_rename(num_params, params);
1407 break;
1408 case OPTEE_MRF_OPENDIR:
1409 debug(">>>>>>> [%d] OPTEE_MRF_OPENDIR!\n", rkss_step++);
1410 ret = ree_fs_new_opendir(num_params, params);
1411 break;
1412 case OPTEE_MRF_CLOSEDIR:
1413 debug(">>>>>>> [%d] OPTEE_MRF_CLOSEDIR!\n", rkss_step++);
1414 ret = ree_fs_new_closedir(num_params, params);
1415 break;
1416 case OPTEE_MRF_READDIR:
1417 debug(">>>>>>> [%d] OPTEE_MRF_READDIR!\n", rkss_step++);
1418 ret = ree_fs_new_readdir(num_params, params);
1419 break;
1420 default:
1421 ret = TEEC_ERROR_BAD_PARAMETERS;
1422 break;
1423 }
1424 rkss_storage_write();
1425 return ret;
1426 }
1427