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