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