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