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