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