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