• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #include "tee_trusted_storage_api.h"
14 #include "tee_mem_mgmt_api.h"
15 #include "tee_log.h"
16 #include "securec.h"
17 #include "tee_ext_api.h"
18 
19 #define PARAM_COUNT             4
20 #define MAX_AES_KEY_SIZE        256
21 #define ARRAY_SIZE              32
22 
23 enum {
24     CMD_STORE_KEY_DEMO = 1,
25     CMD_STORE_DATA_DEMO = 2,
26     CMD_ENUMERATOR_DEMO = 3,
27 };
28 
29 const char *g_write_buffer = "It is a test for persist object!";
30 
store_key_sample(void)31 TEE_Result store_key_sample(void)
32 {
33     uint32_t storage_id = TEE_OBJECT_STORAGE_PRIVATE;
34     TEE_ObjectHandle transient_key = NULL;
35     TEE_ObjectHandle persistent_key = NULL;
36     TEE_Result ret;
37     uint32_t w_flags = TEE_DATA_FLAG_ACCESS_WRITE;
38     uint32_t r_flags = TEE_DATA_FLAG_ACCESS_READ;
39     char attr_buffer[ARRAY_SIZE] = "test save attribute\n";
40     void *object_id = "store_key_sample.txt";
41     void *aes_key = NULL;
42 
43     tlogd("store_key_sample start:============");
44 
45     /* Allocating Storage Space for Keys */
46     ret = TEE_AllocateTransientObject(TEE_TYPE_AES, MAX_AES_KEY_SIZE, (&transient_key));
47     if (ret != TEE_SUCCESS) {
48         tloge("Failed to execute allocate transient object:ret = 0x%x", ret);
49         return ret;
50     }
51 
52     TEE_Attribute *aes_attribute = (TEE_Attribute *)TEE_Malloc(sizeof(TEE_Attribute), 0);
53     if (aes_attribute == NULL) {
54         tloge("Failed to malloc");
55         TEE_FreeTransientObject(transient_key);
56         return TEE_ERROR_OUT_OF_MEMORY;
57     }
58 
59     TEE_InitRefAttribute(aes_attribute, TEE_ATTR_SECRET_VALUE, attr_buffer, sizeof(attr_buffer));
60     ret = TEE_PopulateTransientObject(transient_key, aes_attribute, 1);
61     if (ret != TEE_SUCCESS) {
62         tloge("Failed to execute populate transient object:ret = %d", ret);
63         goto cleanup_1;
64     }
65 
66     /* Create a persistent file to store the key */
67     ret = TEE_CreatePersistentObject(storage_id, object_id, strlen(object_id), w_flags, transient_key, NULL, 0,
68         (&persistent_key));
69     if (ret != TEE_SUCCESS) {
70         tloge("Failed to create object:ret = 0x%x", ret);
71         goto cleanup_1;
72     }
73     TEE_CloseObject(persistent_key);
74 
75     /* Open the object to obtain key. */
76     ret = TEE_OpenPersistentObject(storage_id, object_id, strlen(object_id),
77         r_flags | TEE_DATA_FLAG_ACCESS_WRITE_META, (&persistent_key));
78     if (ret != TEE_SUCCESS) {
79         tloge("Failed to execute open persistent object:ret = %x", ret);
80         TEE_Free(aes_key);
81         return ret;
82     }
83     TEE_CloseObject(persistent_key);
84     persistent_key = NULL;
85 cleanup_1:
86     TEE_Free(aes_attribute);
87     TEE_FreeTransientObject(transient_key);
88     return ret;
89 }
90 
check_store_data(uint32_t storage_id,void * create_object_id)91 TEE_Result check_store_data(uint32_t storage_id, void *create_object_id)
92 {
93     char *read_buffer = NULL;
94     uint32_t count = 0;
95     TEE_ObjectHandle persistent_data = NULL;
96     TEE_ObjectInfo object_info = {0};
97     uint32_t r_flags = TEE_DATA_FLAG_ACCESS_READ;
98     TEE_Result ret;
99 
100     /* Open the created file and read data. */
101     ret = TEE_OpenPersistentObject(storage_id, create_object_id, strlen(create_object_id),
102         r_flags, (&persistent_data));
103     if (ret != TEE_SUCCESS) {
104         tloge("Failed to open file:ret = 0x%x", ret);
105         return ret;
106     }
107 
108     ret = TEE_GetObjectInfo1(persistent_data, &object_info);
109     if (ret != TEE_SUCCESS) {
110         tloge("Failed to open file:ret = 0x%x", ret);
111         TEE_CloseObject(persistent_data);
112         return ret;
113     }
114 
115     read_buffer = TEE_Malloc(object_info.dataSize + 1, 0);
116     if (read_buffer == NULL) {
117         tloge("Failed to open file:ret = 0x%x", ret);
118         TEE_CloseObject(persistent_data);
119         return ret;
120     }
121 
122     /* Read data that has been stored in secure storage */
123     ret = TEE_ReadObjectData(persistent_data, read_buffer, object_info.dataSize, &count);
124     if (ret != TEE_SUCCESS) {
125         TEE_CloseObject(persistent_data);
126         TEE_Free(read_buffer);
127         return ret;
128     }
129     if (TEE_MemCompare(g_write_buffer, read_buffer, strlen(g_write_buffer)) != 0) {
130         TEE_CloseObject(persistent_data);
131         TEE_Free(read_buffer);
132         return TEE_FAIL;
133     }
134     tlogi("Succeed to Compare Date");
135     /* close permanent object */
136     TEE_CloseObject(persistent_data);
137     TEE_Free(read_buffer);
138     return TEE_SUCCESS;
139 }
140 
store_data_sample(void)141 TEE_Result store_data_sample(void)
142 {
143     uint32_t storage_id = TEE_OBJECT_STORAGE_PRIVATE;
144     uint32_t w_flags = TEE_DATA_FLAG_ACCESS_WRITE;
145     void *create_object_id = "store_data_sample.txt";
146     TEE_ObjectHandle persistent_data = NULL;
147     TEE_Result ret;
148 
149     tlogd("store_data_sample start:============");
150 
151     /*
152      * Create a permanent object: The flag is a write operation.
153      * (The initialData, objectinfo, and attributes are written to the physical media.)
154      */
155     ret = TEE_CreatePersistentObject(storage_id, create_object_id, strlen(create_object_id), w_flags,
156         TEE_HANDLE_NULL, NULL, 0, (&persistent_data));
157     if (ret != TEE_SUCCESS) {
158         tloge("Failed to create file: ret = 0x%x", ret);
159         return ret;
160     }
161 
162     ret = TEE_WriteObjectData(persistent_data, g_write_buffer, strlen(g_write_buffer));
163     if (ret != TEE_SUCCESS) {
164         tloge("Failed to write file: ret = 0x%x", ret);
165         /*
166          * After a file is opened or created, the exception branch must close the file.
167          * Otherwise, memory leakage occurs.
168          */
169         TEE_CloseObject(persistent_data);
170         return ret;
171     }
172     TEE_CloseObject(persistent_data);
173 
174     return check_store_data(storage_id, create_object_id);
175 }
176 
177 #define HASH_LEN 32
178 #define DIR_LEN 64
179 #define HASH_NAME_BUFF_LEN (2 * HASH_LEN + 1 + DIR_LEN)
180 
enumerator_sample()181 TEE_Result enumerator_sample()
182 {
183     TEE_Result ret;
184     TEE_ObjectEnumHandle object_enumerator = NULL;
185     TEE_ObjectInfo obj_info = {0};
186     uint8_t object_id[HASH_NAME_BUFF_LEN] = {0};
187     size_t object_id_len = HASH_NAME_BUFF_LEN;
188 
189     ret = TEE_AllocatePersistentObjectEnumerator(&object_enumerator);
190     if (ret != TEE_SUCCESS) {
191         tloge("Failed to allocate objectEnumerator");
192         return ret;
193     }
194 
195     ret = TEE_StartPersistentObjectEnumerator(object_enumerator, TEE_OBJECT_STORAGE_PRIVATE);
196     if (ret != TEE_SUCCESS) {
197         tloge("Failed to start object_enumerator");
198         goto clean;
199     }
200 
201     ret = TEE_GetNextPersistentObject(object_enumerator, &obj_info, object_id, &object_id_len);
202     if (ret != TEE_SUCCESS) {
203         tloge("Failed get next persistent object");
204     }
205 clean:
206     TEE_FreePersistentObjectEnumerator(object_enumerator);
207     return ret;
208 }
209 
TA_CreateEntryPoint(void)210 TEE_Result TA_CreateEntryPoint(void)
211 {
212     TEE_Result ret;
213 
214     tlogd("----- TA entry point ----- ");
215     /* When you develop your own CA, you need to change the name to your own path and CA name. */
216     ret = AddCaller_CA_exec("/vendor/bin/secstorage_demo_ca", 0);
217     if (ret == TEE_SUCCESS) {
218         tlogd("TA entry point: add ca whitelist success");
219     } else {
220         tloge("TA entry point: add ca whitelist failed");
221         return TEE_ERROR_GENERIC;
222     }
223     return TEE_SUCCESS;
224 }
225 
TA_OpenSessionEntryPoint(uint32_t parm_type,TEE_Param params[PARAM_COUNT],void ** session_context)226 TEE_Result TA_OpenSessionEntryPoint(uint32_t parm_type,
227     TEE_Param params[PARAM_COUNT], void** session_context)
228 {
229     (void)parm_type;
230     (void)params;
231     (void)session_context;
232     tlogd("---- TA open session -------- ");
233 
234     return TEE_SUCCESS;
235 }
236 
TA_InvokeCommandEntryPoint(void * session_context,uint32_t cmd_id,uint32_t parm_type,TEE_Param params[PARAM_COUNT])237 TEE_Result TA_InvokeCommandEntryPoint(void* session_context, uint32_t cmd_id, uint32_t parm_type,
238     TEE_Param params[PARAM_COUNT])
239 {
240     TEE_Result ret;
241     (void)session_context;
242     (void)params;
243     tlogd("---- TA invoke command ----------- ");
244     if (!check_param_type(parm_type,
245         TEE_PARAM_TYPE_NONE,
246         TEE_PARAM_TYPE_NONE,
247         TEE_PARAM_TYPE_NONE,
248         TEE_PARAM_TYPE_NONE)) {
249         tloge("Bad expected parameter types");
250         return TEE_ERROR_BAD_PARAMETERS;
251     }
252 
253     switch (cmd_id) {
254     case CMD_STORE_KEY_DEMO:
255         ret = store_key_sample();
256         if (ret != TEE_SUCCESS) {
257             tloge("InvokeCommand Failed 0x%x. cmd is %u", ret, cmd_id);
258             return ret;
259         }
260         break;
261     case CMD_STORE_DATA_DEMO:
262         ret = store_data_sample();
263         if (ret != TEE_SUCCESS) {
264             tloge("InvokeCommand Failed 0x%x. cmd is %u", ret, cmd_id);
265             return ret;
266         }
267         break;
268     case CMD_ENUMERATOR_DEMO:
269         ret = enumerator_sample();
270         if (ret != TEE_SUCCESS) {
271             tloge("InvokeCommand Failed 0x%x. cmd is %u", ret, cmd_id);
272             return ret;
273         }
274         break;
275     default:
276         tloge("Unknown cmd is %u", cmd_id);
277         ret = TEE_ERROR_BAD_PARAMETERS;
278     }
279 
280     return  ret;
281 }
282 
TA_CloseSessionEntryPoint(void * session_context)283 void TA_CloseSessionEntryPoint(void* session_context)
284 {
285     (void)session_context;
286     tlogd("---- close session ----- ");
287 }
288 
TA_DestroyEntryPoint(void)289 void TA_DestroyEntryPoint(void)
290 {
291     tlogd("---- destory TA ---- ");
292 }
293