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 #include "tee_trusted_storage_api.h"
13 #include "ta_framework.h"
14 #include "tee_ss_agent_api.h"
15 #include "tee_log.h"
16 #include "tee_obj.h"
17 #include "securec.h"
18 #include "crypto_inner_defines.h"
19 #include "tee_ext_trusted_storage_api.h"
20 #include "tee_obj_attr.h"
21
22 #ifndef SUPPORT_GP_PANIC
23 #define TEE_Panic(x) \
24 do { \
25 } while (0)
26 #endif
27
28 #define LITTLE_TO_BIG 3UL
29
30 /* rotate 32-bits word by 16 bits */
31 #define TEE_CRYS_COMMON_ROT32(x) (((x) >> 16) | ((x) << 16))
32
33 /* inverse the bytes order in a word */
34 #define TEE_CRYS_COMMON_REVERSE32(x) (((TEE_CRYS_COMMON_ROT32((x)) & 0xff00ff00UL) >> 8) | \
35 ((TEE_CRYS_COMMON_ROT32((x)) & 0x00ff00ffUL) << 8))
36 #define HALF_OF(x) ((x) / 2)
tee_convert_bytes_words_and_array_endianness(uint32_t * buf_ptr,uint32_t size_words)37 static void tee_convert_bytes_words_and_array_endianness(
38 uint32_t *buf_ptr,
39 uint32_t size_words)
40 {
41 uint32_t i, tmp;
42
43 if (buf_ptr == NULL)
44 return;
45
46 /* Reverse words order and bytes in each word */
47 for (i = 0; i < HALF_OF(size_words); i++) {
48 tmp = TEE_CRYS_COMMON_REVERSE32(buf_ptr[i]);
49 buf_ptr[i] = TEE_CRYS_COMMON_REVERSE32(buf_ptr[size_words - i - 1]);
50 buf_ptr[size_words - i - 1] = tmp;
51 }
52 if (size_words & 1UL)
53 buf_ptr[HALF_OF(size_words)] = TEE_CRYS_COMMON_REVERSE32(buf_ptr[HALF_OF(size_words)]);
54
55 return;
56 }
57
tee_ConvertLswMswWordsToMsbLsbBytes(uint8_t * out8_ptr,uint32_t out_size,uint32_t * in32_ptr,uint32_t size_in_bytes)58 TEE_Result tee_ConvertLswMswWordsToMsbLsbBytes(
59 uint8_t *out8_ptr,
60 uint32_t out_size,
61 uint32_t *in32_ptr,
62 uint32_t size_in_bytes)
63 {
64 /* FUNCTION DECLARATIONS */
65 uint32_t size_in_words;
66
67 if (out8_ptr == NULL || in32_ptr == NULL)
68 return TEE_ERROR_BAD_PARAMETERS;
69
70 /* Size in words rounded up */
71 size_in_words = (size_in_bytes + (UINT32_SIZE - 1)) / UINT32_SIZE;
72
73 /* Reverse words order and bytes according to endianness of CPU */
74 tee_convert_bytes_words_and_array_endianness(in32_ptr, size_in_words);
75
76 /* Copy output buffer */
77 if ((uintptr_t)out8_ptr != (uintptr_t)in32_ptr) {
78 if (out_size < size_in_bytes)
79 return TEE_ERROR_BAD_PARAMETERS;
80 if (memmove_s(out8_ptr, out_size,
81 (uint8_t *)in32_ptr + ((UINT32_SIZE - (size_in_bytes & LITTLE_TO_BIG)) & LITTLE_TO_BIG),
82 size_in_bytes) != EOK)
83 return TEE_ERROR_SECURITY;
84 /* Revert the input buffer to previous state */
85 tee_convert_bytes_words_and_array_endianness(in32_ptr, size_in_words);
86 }
87
88 return TEE_SUCCESS;
89 }
90
check_object_id(const void * object_id,size_t object_id_len,size_t object_id_max_len)91 static TEE_Result check_object_id(const void *object_id, size_t object_id_len, size_t object_id_max_len)
92 {
93 if (object_id == NULL ||
94 strnlen(object_id, object_id_max_len) >= object_id_max_len) {
95 tloge("bad parameter!\n");
96 return TEE_ERROR_BAD_PARAMETERS;
97 }
98
99 if (strlen((const char *)object_id) != object_id_len) {
100 tloge("objectID string length is less than objectIDLen!\n");
101 return TEE_ERROR_BAD_PARAMETERS;
102 }
103
104 if (check_file_name(object_id)) {
105 tloge("file name invalid!\n");
106 return TEE_ERROR_BAD_PARAMETERS;
107 }
108
109 return TEE_SUCCESS;
110 }
111
check_object_param(uint32_t storage_id,const void * object_id,size_t object_id_len)112 static TEE_Result check_object_param(uint32_t storage_id, const void *object_id, size_t object_id_len)
113 {
114 TEE_Result ret = check_object_id(object_id, object_id_len, MAX_FILE_ID_LEN);
115 if (ret != TEE_SUCCESS) {
116 tloge("Check object id failed!\n");
117 return ret;
118 }
119
120 if (check_name_by_storageid(object_id, object_id_len, storage_id)) {
121 tloge("Check name by storage id failed!\n");
122 return TEE_ERROR_STORAGE_PATH_WRONG;
123 }
124
125 return TEE_SUCCESS;
126 }
127
128 static TEE_Result g_create_obj_specify_value[] = {
129 TEE_SUCCESS,
130 TEE_ERROR_ITEM_NOT_FOUND,
131 TEE_ERROR_ACCESS_CONFLICT,
132 TEE_ERROR_OUT_OF_MEMORY,
133 TEE_ERROR_STORAGE_NO_SPACE,
134 TEE_ERROR_CORRUPT_OBJECT,
135 TEE_ERROR_STORAGE_NOT_AVAILABLE
136 };
137 static TEE_Result g_open_obj_specify_value[] = {
138 TEE_SUCCESS,
139 TEE_ERROR_ITEM_NOT_FOUND,
140 TEE_ERROR_ACCESS_CONFLICT,
141 TEE_ERROR_OUT_OF_MEMORY,
142 TEE_ERROR_CORRUPT_OBJECT,
143 TEE_ERROR_STORAGE_NOT_AVAILABLE
144 };
145 static TEE_Result g_read_obj_specify_value[] = {
146 TEE_SUCCESS,
147 TEE_ERROR_CORRUPT_OBJECT,
148 TEE_ERROR_STORAGE_NOT_AVAILABLE
149 };
150 static TEE_Result g_write_obj_specify_value[] = {
151 TEE_SUCCESS,
152 TEE_ERROR_STORAGE_NO_SPACE,
153 TEE_ERROR_OVERFLOW,
154 TEE_ERROR_CORRUPT_OBJECT,
155 TEE_ERROR_STORAGE_NOT_AVAILABLE
156 };
157 static TEE_Result g_truncate_obj_specify_value[] = {
158 TEE_SUCCESS,
159 TEE_ERROR_STORAGE_NO_SPACE,
160 TEE_ERROR_CORRUPT_OBJECT,
161 TEE_ERROR_STORAGE_NOT_AVAILABLE
162 };
163 static TEE_Result g_seek_obj_specify_value[] = {
164 TEE_SUCCESS,
165 TEE_ERROR_OVERFLOW,
166 TEE_ERROR_CORRUPT_OBJECT,
167 TEE_ERROR_STORAGE_NOT_AVAILABLE
168 };
169 static TEE_Result g_close_obj_specify_value[] = {
170 TEE_SUCCESS,
171 TEE_ERROR_STORAGE_NOT_AVAILABLE
172 };
173
174 typedef enum object_operation_type {
175 OBJECT_OP_CREATE = 0,
176 OBJECT_OP_OPEN,
177 OBJECT_OP_READ,
178 OBJECT_OP_WRITE,
179 OBJECT_OP_TRUNCATE,
180 OBJECT_OP_SEEK,
181 OBJECT_OP_CLOSE
182 }obj_oper_type;
183
184 typedef struct object_operation_info {
185 obj_oper_type oper_type;
186 TEE_Result *spec_return_value;
187 uint32_t value_num;
188 }obj_oper_info;
189
190 static obj_oper_info g_obj_oper_list[] = {
191 { OBJECT_OP_CREATE, g_create_obj_specify_value, ELEM_NUM(g_create_obj_specify_value) },
192 { OBJECT_OP_OPEN, g_open_obj_specify_value, ELEM_NUM(g_open_obj_specify_value) },
193 { OBJECT_OP_READ, g_read_obj_specify_value, ELEM_NUM(g_read_obj_specify_value) },
194 { OBJECT_OP_WRITE, g_write_obj_specify_value, ELEM_NUM(g_write_obj_specify_value) },
195 { OBJECT_OP_TRUNCATE, g_truncate_obj_specify_value, ELEM_NUM(g_truncate_obj_specify_value) },
196 { OBJECT_OP_SEEK, g_seek_obj_specify_value, ELEM_NUM(g_seek_obj_specify_value) },
197 { OBJECT_OP_CLOSE, g_close_obj_specify_value, ELEM_NUM(g_close_obj_specify_value) }
198 };
199
check_oper_object_return_value(TEE_Result return_val,uint32_t oper_type)200 static void check_oper_object_return_value(TEE_Result return_val, uint32_t oper_type)
201 {
202 if (oper_type > OBJECT_OP_CLOSE)
203 return;
204
205 uint32_t i;
206 bool is_gp_specify_value = false;
207
208 TEE_Result *gp_specify_value = g_obj_oper_list[oper_type].spec_return_value;
209 uint32_t value_num = g_obj_oper_list[oper_type].value_num;
210
211 for (i = 0; i < value_num; i++) {
212 if (gp_specify_value[i] == return_val) {
213 is_gp_specify_value = true;
214 break;
215 }
216 }
217
218 if (is_gp_specify_value)
219 return;
220
221 TEE_Panic(return_val);
222 }
223
check_create_storage_id(uint32_t storage_id)224 static TEE_Result check_create_storage_id(uint32_t storage_id)
225 {
226 bool storage_valid_flag = (storage_id == TEE_OBJECT_STORAGE_PRIVATE) ||
227 (storage_id == TEE_OBJECT_STORAGE_CE);
228
229 if (!storage_valid_flag) {
230 tloge("bad storageID!\n");
231 return TEE_ERROR_ITEM_NOT_FOUND;
232 }
233
234 return TEE_SUCCESS;
235 }
236
fill_id_params(struct create_obj_msg_t * params,uint32_t cmd_id,uint32_t storage_id,const void * object_id,uint32_t object_id_len)237 static void fill_id_params(struct create_obj_msg_t *params, uint32_t cmd_id, uint32_t storage_id,
238 const void *object_id, uint32_t object_id_len)
239 {
240 params->cmd_id = cmd_id;
241 params->storage_id = storage_id;
242 params->object_id = (uintptr_t)object_id;
243 params->obj_id_len = object_id_len;
244 }
245
fill_data_params(struct create_obj_msg_t * params,const void * initial_data,uint32_t initial_data_len,uint32_t flags,TEE_ObjectHandle attributes)246 static void fill_data_params(struct create_obj_msg_t *params, const void *initial_data, uint32_t initial_data_len,
247 uint32_t flags, TEE_ObjectHandle attributes)
248 {
249 params->flags = flags;
250 params->initial_data = (uintptr_t)initial_data;
251 params->data_len = initial_data_len;
252 params->attributes = (uintptr_t)attributes;
253 }
254
TEE_CreatePersistentObject(uint32_t storageID,const void * objectID,size_t objectIDLen,uint32_t flags,TEE_ObjectHandle attributes,const void * initialData,size_t initialDataLen,TEE_ObjectHandle * object)255 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen, uint32_t flags,
256 TEE_ObjectHandle attributes, const void *initialData, size_t initialDataLen, TEE_ObjectHandle *object)
257 {
258 TEE_Result ret = check_create_storage_id(storageID);
259 if (ret != TEE_SUCCESS)
260 return ret;
261
262 if ((attributes != NULL) && (check_object_valid(attributes) != TEE_SUCCESS)) {
263 tloge("The attributes is invalid object!\n");
264 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
265 return TEE_ERROR_BAD_PARAMETERS;
266 }
267 ret = check_object_param(storageID, objectID, objectIDLen);
268 if (ret != TEE_SUCCESS) {
269 tloge("Object id is invalid!\n");
270 TEE_Panic(ret);
271 return ret;
272 }
273
274 /* if no w&r permission ,add default read */
275 if (((flags & TEE_DATA_FLAG_ACCESS_WRITE) == 0) &&
276 ((flags & TEE_DATA_FLAG_ACCESS_READ) == 0))
277 flags = (flags | TEE_DATA_FLAG_ACCESS_READ);
278
279 TEE_UUID uuid = {0};
280 struct create_obj_msg_t params;
281 params.target_uuid = uuid;
282 fill_id_params(¶ms, SS_AGENT_CREATE_OBJECT, storageID, objectID, objectIDLen);
283 fill_data_params(¶ms, initialData, initialDataLen, flags, attributes);
284 ret = ss_agent_create_object(¶ms, object);
285 check_oper_object_return_value(ret, OBJECT_OP_CREATE);
286
287 return ret;
288 }
289
open_object_by_storage_id(uint32_t storage_id,const void * object_id,size_t object_id_len,uint32_t flags,TEE_ObjectHandle * object)290 static TEE_Result open_object_by_storage_id(uint32_t storage_id, const void *object_id, size_t object_id_len,
291 uint32_t flags, TEE_ObjectHandle *object)
292 {
293 TEE_UUID uuid = {0};
294 struct create_obj_msg_t params;
295 params.target_uuid = uuid;
296 fill_id_params(¶ms, SS_AGENT_OPEN_OBJECT, storage_id, object_id, object_id_len);
297 fill_data_params(¶ms, NULL, 0, flags, TEE_HANDLE_NULL);
298 return ss_agent_open_object(¶ms, object);
299 }
300
TEE_OpenPersistentObject(uint32_t storageID,const void * objectID,size_t objectIDLen,uint32_t flags,TEE_ObjectHandle * object)301 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen,
302 uint32_t flags, TEE_ObjectHandle *object)
303 {
304 TEE_Result ret;
305 /* para */
306 bool storage_valid_flag = (storageID == TEE_OBJECT_STORAGE_PRIVATE) ||
307 (storageID == TEE_OBJECT_STORAGE_CE);
308 if (storage_valid_flag != true) {
309 tloge("bad storageID!\n");
310 return TEE_ERROR_ITEM_NOT_FOUND;
311 }
312 ret = check_object_param(storageID, objectID, objectIDLen);
313 if (ret != TEE_SUCCESS) {
314 tloge("Object id is invalid!\n");
315 TEE_Panic(ret);
316 return ret;
317 }
318 /* start: if no w&r permission ,add default read */
319 if (((flags & TEE_DATA_FLAG_ACCESS_WRITE) == 0) && ((flags & TEE_DATA_FLAG_ACCESS_READ) == 0)) {
320 flags = (flags | TEE_DATA_FLAG_ACCESS_READ);
321 tlogd("add read\n");
322 }
323
324 ret = open_object_by_storage_id(storageID, objectID, objectIDLen, flags, object);
325 check_oper_object_return_value(ret, OBJECT_OP_OPEN);
326 return ret;
327 }
328
check_operator_object_valid(TEE_ObjectHandle object)329 static TEE_Result check_operator_object_valid(TEE_ObjectHandle object)
330 {
331 if (object == NULL) {
332 tloge("Object is NULL!\n");
333 return TEE_ERROR_BAD_PARAMETERS;
334 }
335
336 if (check_object(object) != TEE_SUCCESS) {
337 tloge("Object is invalid\n");
338 return TEE_ERROR_BAD_PARAMETERS;
339 }
340
341 if (object->ObjectInfo == NULL) {
342 tloge("Bad parameter!\n");
343 return TEE_ERROR_BAD_PARAMETERS;
344 }
345
346 if ((object->ObjectInfo->handleFlags & TEE_HANDLE_FLAG_PERSISTENT) == 0) {
347 tloge("Object is not a persistent object\n");
348 return TEE_ERROR_ACCESS_DENIED;
349 }
350
351 return TEE_SUCCESS;
352 }
353
TEE_ReadObjectData(TEE_ObjectHandle object,void * buffer,size_t size,uint32_t * count)354 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, size_t size, uint32_t *count)
355 {
356 if (buffer == NULL || count == NULL || size == 0 || size > MAX_FILE_SIZE) {
357 tloge("bad parameter!\n");
358 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
359 return TEE_ERROR_BAD_PARAMETERS;
360 }
361
362 TEE_Result ret = check_operator_object_valid(object);
363 if (ret != TEE_SUCCESS) {
364 tloge("Object is not a valid object!\n");
365 TEE_Panic(ret);
366 return ret;
367 }
368
369 if ((object->ObjectInfo->handleFlags & TEE_DATA_FLAG_ACCESS_READ) == 0) {
370 tloge("Access denied\n");
371 TEE_Panic(TEE_ERROR_ACCESS_DENIED);
372 return TEE_ERROR_ACCESS_DENIED;
373 }
374
375 ret = ss_agent_read_object_data(object, buffer, size, count);
376 check_oper_object_return_value(ret, OBJECT_OP_READ);
377
378 return ret;
379 }
380
TEE_WriteObjectData(TEE_ObjectHandle object,const void * buffer,size_t size)381 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, size_t size)
382 {
383 if (buffer == NULL || size == 0 || size > MAX_FILE_SIZE) {
384 tloge("bad parameter!\n");
385 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
386 return TEE_ERROR_BAD_PARAMETERS;
387 }
388
389 TEE_Result ret = check_operator_object_valid(object);
390 if (ret != TEE_SUCCESS) {
391 tloge("Object is not a valid persistent object!\n");
392 TEE_Panic(ret);
393 return ret;
394 }
395
396 if ((object->ObjectInfo->handleFlags & TEE_DATA_FLAG_ACCESS_WRITE) == 0) {
397 tloge("Access denied\n");
398 TEE_Panic(TEE_ERROR_ACCESS_DENIED);
399 return TEE_ERROR_ACCESS_DENIED;
400 }
401
402 ret = ss_agent_write_object_data(object, buffer, size);
403 check_oper_object_return_value(ret, OBJECT_OP_WRITE);
404 return ret;
405 }
406
TEE_TruncateObjectData(TEE_ObjectHandle object,size_t size)407 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, size_t size)
408 {
409 if (size > MAX_FILE_SIZE) {
410 tloge("bad parameter!\n");
411 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
412 return TEE_ERROR_BAD_PARAMETERS;
413 }
414
415 TEE_Result ret = check_operator_object_valid(object);
416 if (ret != TEE_SUCCESS) {
417 tloge("Object is not a valid object!\n");
418 TEE_Panic(ret);
419 return ret;
420 }
421
422 if ((object->ObjectInfo->handleFlags & TEE_DATA_FLAG_ACCESS_WRITE) == 0) {
423 tloge("Access denied\n");
424 TEE_Panic(TEE_ERROR_ACCESS_DENIED);
425 return TEE_ERROR_ACCESS_DENIED;
426 }
427
428 ret = ss_agent_truncate_object_data(object, (int32_t)size);
429 check_oper_object_return_value(ret, OBJECT_OP_TRUNCATE);
430 return ret;
431 }
432
TEE_SeekObjectData(TEE_ObjectHandle object,int32_t offset,TEE_Whence whence)433 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, TEE_Whence whence)
434 {
435 int32_t offset_size = (offset < 0) ? (-offset) : offset;
436
437 if (offset_size > MAX_FILE_SIZE) {
438 tloge("bad parameter!\n");
439 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
440 return TEE_ERROR_BAD_PARAMETERS;
441 }
442
443 TEE_Result ret = check_operator_object_valid(object);
444 if (ret != TEE_SUCCESS) {
445 tloge("Object is not a valid object!\n");
446 TEE_Panic(ret);
447 return ret;
448 }
449
450 ret = ss_agent_seek_object_data(object, offset, whence);
451 check_oper_object_return_value(ret, OBJECT_OP_SEEK);
452 return ret;
453 }
454
close_object_by_storage_id(TEE_ObjectHandle object)455 static void close_object_by_storage_id(TEE_ObjectHandle object)
456 {
457 ss_agent_close_object(object);
458 }
459
delete_object_by_storage_id(TEE_ObjectHandle object)460 static void delete_object_by_storage_id(TEE_ObjectHandle object)
461 {
462 if (ss_agent_close_and_delete_object(object) != TEE_SUCCESS)
463 tloge("Close and del object failed\n");
464 }
465
TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)466 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
467 {
468 if (object == TEE_HANDLE_NULL) {
469 tloge("object is TEE_HANDLE_NULL.\n");
470 return;
471 }
472
473 if (check_object(object) != TEE_SUCCESS) {
474 tloge("object is invalid\n");
475 return;
476 }
477
478 if (object->ObjectInfo == NULL) {
479 tloge("bad parameter!\n");
480 return;
481 }
482
483 /* check permission */
484 if ((object->ObjectInfo->handleFlags & TEE_DATA_FLAG_ACCESS_WRITE_META) == 0) {
485 tloge("Access denied, Can not delete, only close object.\n");
486 /* if object no write meta flag,
487 * we only close the file so that free resource */
488 if ((object->ObjectInfo->handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) {
489 tlogd("this is a persistent object\n");
490 close_object_by_storage_id(object);
491 } else {
492 tlogd("this is a transitent object\n");
493 TEE_FreeTransientObject(object);
494 tlogd("TEE_CloseObject end!\n");
495 }
496 return;
497 }
498
499 delete_object_by_storage_id(object);
500 return;
501 }
502
TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)503 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
504 {
505 TEE_Result ret = check_operator_object_valid(object);
506 if (ret != TEE_SUCCESS) {
507 tloge("Object is not a valid object!\n");
508 TEE_Panic(ret);
509 return ret;
510 }
511
512 if ((object->ObjectInfo->handleFlags & TEE_DATA_FLAG_ACCESS_WRITE_META) == 0) {
513 tloge("Access denied\n");
514 TEE_Panic(TEE_ERROR_ACCESS_DENIED);
515 return TEE_ERROR_ACCESS_DENIED;
516 }
517
518 ret = ss_agent_close_and_delete_object(object);
519 check_oper_object_return_value(ret, OBJECT_OP_CLOSE);
520 return ret;
521 }
522
TEE_SyncPersistentObject(TEE_ObjectHandle object)523 TEE_Result TEE_SyncPersistentObject(TEE_ObjectHandle object)
524 {
525 /* param check */
526 if (object == TEE_HANDLE_NULL) {
527 tloge("object is TEE_HANDLE_NULL.\n");
528 return TEE_ERROR_BAD_PARAMETERS;
529 }
530
531 if (check_object(object) != TEE_SUCCESS) {
532 tloge("object is invalid\n");
533 return TEE_ERROR_BAD_PARAMETERS;
534 }
535
536 return ss_agent_sync_object(object);
537 }
538
TEE_RenamePersistentObject(TEE_ObjectHandle object,void * newObjectID,size_t newObjectIDLen)539 TEE_Result TEE_RenamePersistentObject(
540 TEE_ObjectHandle object,
541 void *newObjectID,
542 size_t newObjectIDLen)
543 {
544 if (object == NULL || newObjectID == NULL ||
545 strnlen(newObjectID, HASH_NAME_BUFF_LEN) >= HASH_NAME_BUFF_LEN) {
546 tloge("bad parameter!\n");
547 return TEE_ERROR_BAD_PARAMETERS;
548 }
549
550 if (check_object(object) != TEE_SUCCESS) {
551 tloge("object is invalid\n");
552 return TEE_ERROR_BAD_PARAMETERS;
553 }
554 if (strlen((const char *)newObjectID) != newObjectIDLen) {
555 tloge("newObjectID string length is less than newObjectIDLen!\n");
556 return TEE_ERROR_BAD_PARAMETERS;
557 }
558
559 if (check_file_name(newObjectID)) {
560 tloge("file name invalid!\n");
561 return TEE_ERROR_BAD_PARAMETERS;
562 }
563
564 if (object->ObjectInfo == NULL) {
565 tloge("bad parameter!\n");
566 return TEE_ERROR_BAD_PARAMETERS;
567 }
568
569 /* check permission */
570 if ((object->ObjectInfo->handleFlags & TEE_DATA_FLAG_ACCESS_WRITE_META) == 0) {
571 tloge("Access denied\n");
572 return TEE_ERROR_ACCESS_DENIED;
573 }
574
575 return ss_agent_rename_object(object, newObjectID, newObjectIDLen);
576 }
577
578 static pthread_mutex_t g_enum_mutex = PTHREAD_MUTEX_INITIALIZER;
TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * obj_enumerator)579 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *obj_enumerator)
580 {
581 TEE_Result ret;
582
583 if (obj_enumerator == TEE_HANDLE_NULL) {
584 tloge("objectEnumerator is null.\n");
585 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
586 return TEE_ERROR_BAD_PARAMETERS;
587 }
588
589 if (mutex_lock_ops(&g_enum_mutex) != 0) {
590 tloge("pthread_mutex_lock failed\n");
591 return TEE_ERROR_GENERIC;
592 }
593
594 ret = allocate_enum_handle(obj_enumerator);
595 if (ret != TEE_SUCCESS) {
596 (void)pthread_mutex_unlock(&g_enum_mutex);
597 return ret;
598 }
599
600 ret = add_enum_object_in_list(*obj_enumerator);
601 if (ret != TEE_SUCCESS) {
602 tloge("add enum object fail, ret:0x%x", ret);
603 free_enum_handle(*obj_enumerator);
604 *obj_enumerator = NULL;
605 (void)pthread_mutex_unlock(&g_enum_mutex);
606 return ret;
607 }
608
609 (void)pthread_mutex_unlock(&g_enum_mutex);
610
611 return TEE_SUCCESS;
612 }
613
TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator)614 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator)
615 {
616 if (obj_enumerator == TEE_HANDLE_NULL) {
617 tloge("The objectEnumerator is NULL, return\n");
618 return;
619 }
620
621 if (mutex_lock_ops(&g_enum_mutex) != 0) {
622 tloge("pthread_mutex_lock failed\n");
623 return;
624 }
625
626 if (check_enum_object_in_list(obj_enumerator) != TEE_SUCCESS) {
627 tloge("enum object is invalid");
628 (void)pthread_mutex_unlock(&g_enum_mutex);
629 return;
630 }
631
632 delete_enum_object_in_list(obj_enumerator);
633 free_enum_handle(obj_enumerator);
634 obj_enumerator = NULL;
635
636 (void)pthread_mutex_unlock(&g_enum_mutex);
637 }
638
TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator)639 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator)
640 {
641 if (obj_enumerator == TEE_HANDLE_NULL) {
642 tloge("bad object parameter!\n");
643 return;
644 }
645
646 if (mutex_lock_ops(&g_enum_mutex) != 0) {
647 tloge("pthread_mutex_lock failed\n");
648 return;
649 }
650
651 if (check_enum_object_in_list(obj_enumerator) != TEE_SUCCESS) {
652 tloge("enum object is invalid");
653 (void)pthread_mutex_unlock(&g_enum_mutex);
654 return;
655 }
656
657 reset_enum_handle(obj_enumerator);
658
659 (void)pthread_mutex_unlock(&g_enum_mutex);
660 }
661
TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle obj_enumerator,uint32_t storage_id)662 TEE_Result TEE_StartPersistentObjectEnumerator(
663 TEE_ObjectEnumHandle obj_enumerator, uint32_t storage_id)
664 {
665 TEE_Result ret;
666
667 if (storage_id != TEE_OBJECT_STORAGE_PRIVATE) {
668 tloge("bad storageID!\n");
669 return TEE_ERROR_ITEM_NOT_FOUND;
670 }
671
672 if (obj_enumerator == TEE_HANDLE_NULL) {
673 tloge("objectEnumerator is null, please check.\n");
674 return TEE_ERROR_BAD_PARAMETERS;
675 }
676
677 if (mutex_lock_ops(&g_enum_mutex) != 0) {
678 tloge("pthread_mutex_lock failed\n");
679 return TEE_ERROR_GENERIC;
680 }
681
682 if (check_enum_object_in_list(obj_enumerator) != TEE_SUCCESS) {
683 tloge("enum object is invalid");
684 (void)pthread_mutex_unlock(&g_enum_mutex);
685 return TEE_ERROR_BAD_PARAMETERS;
686 }
687
688 ret = ta_start_enumerator(obj_enumerator);
689 if (ret != TEE_SUCCESS) {
690 tloge("Failed to execute ta_start_enumerator, ret=0x%x\n", ret);
691 (void)pthread_mutex_unlock(&g_enum_mutex);
692 return ret;
693 }
694
695 (void)pthread_mutex_unlock(&g_enum_mutex);
696
697 return TEE_SUCCESS;
698 }
699
TEE_GetNextPersistentObject(TEE_ObjectEnumHandle obj_enumerator,TEE_ObjectInfo * object_info,void * object_id,size_t * object_id_len)700 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle obj_enumerator,
701 TEE_ObjectInfo *object_info,
702 void *object_id,
703 size_t *object_id_len)
704 {
705 TEE_Result ret;
706
707 if (obj_enumerator == NULL || object_info == NULL ||
708 object_id == NULL || object_id_len == NULL) {
709 tloge("Bad parameters, please check.\n");
710 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
711 return TEE_ERROR_BAD_PARAMETERS;
712 }
713
714 if (mutex_lock_ops(&g_enum_mutex) != 0) {
715 tloge("pthread_mutex_lock failed\n");
716 return TEE_ERROR_GENERIC;
717 }
718
719 if (check_enum_object_in_list(obj_enumerator) != TEE_SUCCESS) {
720 tloge("enum object is invalid");
721 (void)pthread_mutex_unlock(&g_enum_mutex);
722 return TEE_ERROR_BAD_PARAMETERS;
723 }
724
725 ret = ta_get_next(obj_enumerator, object_info, object_id, object_id_len);
726 if (ret != TEE_SUCCESS) {
727 (void)pthread_mutex_unlock(&g_enum_mutex);
728 return ret;
729 }
730
731 (void)pthread_mutex_unlock(&g_enum_mutex);
732
733 return TEE_SUCCESS;
734 }
735
tee_ext_create_persistent_object(TEE_UUID target,uint32_t storage_id,const void * object_id,size_t object_id_len,uint32_t flags,TEE_ObjectHandle attributes,const void * initial_data,size_t initial_data_len,TEE_ObjectHandle * object)736 TEE_Result tee_ext_create_persistent_object(
737 TEE_UUID target, uint32_t storage_id, const void *object_id, size_t object_id_len, uint32_t flags,
738 TEE_ObjectHandle attributes, const void *initial_data, size_t initial_data_len, TEE_ObjectHandle *object)
739 {
740 (void)object_id;
741 (void)object_id_len;
742 (void)initial_data;
743 (void)initial_data_len;
744 (void)flags;
745 (void)attributes;
746 (void)object;
747 (void)target;
748 (void)storage_id;
749 return TEE_ERROR_NOT_SUPPORTED;
750 }
751
tee_ext_open_persistent_object(TEE_UUID target,uint32_t storage_id,const void * object_id,size_t object_id_len,uint32_t flags,TEE_ObjectHandle * object)752 TEE_Result tee_ext_open_persistent_object(
753 TEE_UUID target,
754 uint32_t storage_id,
755 const void *object_id, size_t object_id_len,
756 uint32_t flags,
757 TEE_ObjectHandle *object)
758 {
759 (void)target;
760 (void)storage_id;
761 (void)object_id;
762 (void)object_id_len;
763 (void)flags;
764 (void)object;
765 return TEE_ERROR_NOT_SUPPORTED;
766 }
767
tee_ext_delete_all_objects(TEE_UUID target)768 TEE_Result tee_ext_delete_all_objects(TEE_UUID target)
769 {
770 (void)target;
771 return TEE_ERROR_NOT_SUPPORTED;
772 }
773
774