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