1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include <tee_api.h>
9 #include <utee_syscalls.h>
10 #include "tee_api_private.h"
11 
12 #define TEE_USAGE_DEFAULT   0xffffffff
13 
__utee_from_attr(struct utee_attribute * ua,const TEE_Attribute * attrs,uint32_t attr_count)14 void __utee_from_attr(struct utee_attribute *ua, const TEE_Attribute *attrs,
15 			uint32_t attr_count)
16 {
17 	size_t n;
18 
19 	for (n = 0; n < attr_count; n++) {
20 		ua[n].attribute_id = attrs[n].attributeID;
21 		if (attrs[n].attributeID & TEE_ATTR_FLAG_VALUE) {
22 			ua[n].a = attrs[n].content.value.a;
23 			ua[n].b = attrs[n].content.value.b;
24 		} else {
25 			ua[n].a = (uintptr_t)attrs[n].content.ref.buffer;
26 			ua[n].b = attrs[n].content.ref.length;
27 		}
28 	}
29 }
30 
31 /* Data and Key Storage API  - Generic Object Functions */
32 /*
33  * Use of this function is deprecated
34  * new code SHOULD use the TEE_GetObjectInfo1 function instead
35  * These functions will be removed at some future major revision of
36  * this specification
37  */
TEE_GetObjectInfo(TEE_ObjectHandle object,TEE_ObjectInfo * objectInfo)38 void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
39 {
40 	struct utee_object_info info = { };
41 	TEE_Result res = TEE_SUCCESS;
42 
43 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
44 
45 	if (res != TEE_SUCCESS)
46 		TEE_Panic(res);
47 
48 	if (info.obj_type == TEE_TYPE_CORRUPTED_OBJECT) {
49 		objectInfo->keySize = 0;
50 		objectInfo->maxKeySize = 0;
51 		objectInfo->objectUsage = 0;
52 		objectInfo->dataSize = 0;
53 		objectInfo->dataPosition = 0;
54 		objectInfo->handleFlags = 0;
55 	} else {
56 		objectInfo->objectType = info.obj_type;
57 		objectInfo->keySize = info.obj_size;
58 		objectInfo->maxKeySize = info.max_obj_size;
59 		objectInfo->objectUsage = info.obj_usage;
60 		objectInfo->dataSize = info.data_size;
61 		objectInfo->dataPosition = info.data_pos;
62 		objectInfo->handleFlags = info.handle_flags;
63 	}
64 }
65 
TEE_GetObjectInfo1(TEE_ObjectHandle object,TEE_ObjectInfo * objectInfo)66 TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
67 {
68 	struct utee_object_info info = { };
69 	TEE_Result res = TEE_SUCCESS;
70 
71 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
72 
73 	if (res != TEE_SUCCESS &&
74 	    res != TEE_ERROR_CORRUPT_OBJECT &&
75 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
76 		TEE_Panic(res);
77 
78 	objectInfo->objectType = info.obj_type;
79 	objectInfo->keySize = info.obj_size;
80 	objectInfo->maxKeySize = info.max_obj_size;
81 	objectInfo->objectUsage = info.obj_usage;
82 	objectInfo->dataSize = info.data_size;
83 	objectInfo->dataPosition = info.data_pos;
84 	objectInfo->handleFlags = info.handle_flags;
85 
86 	return res;
87 }
88 
89 /*
90  * Use of this function is deprecated
91  * new code SHOULD use the TEE_RestrictObjectUsage1 function instead
92  * These functions will be removed at some future major revision of
93  * this specification
94  */
TEE_RestrictObjectUsage(TEE_ObjectHandle object,uint32_t objectUsage)95 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage)
96 {
97 	struct utee_object_info info = { };
98 	TEE_Result res = TEE_SUCCESS;
99 
100 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
101 	if (info.obj_type == TEE_TYPE_CORRUPTED_OBJECT)
102 		return;
103 
104 	res = TEE_RestrictObjectUsage1(object, objectUsage);
105 
106 	if (res != TEE_SUCCESS)
107 		TEE_Panic(res);
108 }
109 
TEE_RestrictObjectUsage1(TEE_ObjectHandle object,uint32_t objectUsage)110 TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage)
111 {
112 	TEE_Result res;
113 
114 	res = _utee_cryp_obj_restrict_usage((unsigned long)object,
115 					    objectUsage);
116 
117 	if (res != TEE_SUCCESS &&
118 	    res != TEE_ERROR_CORRUPT_OBJECT &&
119 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
120 		TEE_Panic(res);
121 
122 	return res;
123 }
124 
TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,uint32_t attributeID,void * buffer,uint32_t * size)125 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
126 					uint32_t attributeID, void *buffer,
127 					uint32_t *size)
128 {
129 	struct utee_object_info info = { };
130 	TEE_Result res = TEE_SUCCESS;
131 	uint64_t sz = 0;
132 
133 	__utee_check_inout_annotation(size, sizeof(*size));
134 
135 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
136 	if (res != TEE_SUCCESS)
137 		goto exit;
138 
139 	/* This function only supports reference attributes */
140 	if ((attributeID & TEE_ATTR_FLAG_VALUE)) {
141 		res = TEE_ERROR_BAD_PARAMETERS;
142 		goto exit;
143 	}
144 
145 	sz = *size;
146 	res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID,
147 				      buffer, &sz);
148 	*size = sz;
149 
150 exit:
151 	if (res != TEE_SUCCESS &&
152 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
153 	    res != TEE_ERROR_SHORT_BUFFER &&
154 	    res != TEE_ERROR_CORRUPT_OBJECT &&
155 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
156 		TEE_Panic(res);
157 
158 	return res;
159 }
160 
TEE_GetObjectValueAttribute(TEE_ObjectHandle object,uint32_t attributeID,uint32_t * a,uint32_t * b)161 TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
162 				       uint32_t attributeID, uint32_t *a,
163 				       uint32_t *b)
164 {
165 	struct utee_object_info info = { };
166 	TEE_Result res = TEE_SUCCESS;
167 	uint32_t buf[2];
168 	uint64_t size = sizeof(buf);
169 
170 	if (a)
171 		__utee_check_out_annotation(a, sizeof(*a));
172 	if (b)
173 		__utee_check_out_annotation(b, sizeof(*b));
174 
175 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
176 	if (res != TEE_SUCCESS)
177 		goto exit;
178 
179 	/* This function only supports value attributes */
180 	if (!(attributeID & TEE_ATTR_FLAG_VALUE)) {
181 		res = TEE_ERROR_BAD_PARAMETERS;
182 		goto exit;
183 	}
184 
185 	res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf,
186 				      &size);
187 
188 exit:
189 	if (res != TEE_SUCCESS &&
190 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
191 	    res != TEE_ERROR_CORRUPT_OBJECT &&
192 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
193 		TEE_Panic(res);
194 
195 	if (size != sizeof(buf))
196 		TEE_Panic(0);
197 
198 	if (res == TEE_SUCCESS) {
199 		if (a)
200 			*a = buf[0];
201 		if (b)
202 			*b = buf[1];
203 	}
204 
205 	return res;
206 }
207 
TEE_CloseObject(TEE_ObjectHandle object)208 void TEE_CloseObject(TEE_ObjectHandle object)
209 {
210 	TEE_Result res;
211 
212 	if (object == TEE_HANDLE_NULL)
213 		return;
214 
215 	res = _utee_cryp_obj_close((unsigned long)object);
216 	if (res != TEE_SUCCESS)
217 		TEE_Panic(res);
218 }
219 
220 /* Data and Key Storage API  - Transient Object Functions */
221 
TEE_AllocateTransientObject(TEE_ObjectType objectType,uint32_t maxKeySize,TEE_ObjectHandle * object)222 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,
223 				       uint32_t maxKeySize,
224 				       TEE_ObjectHandle *object)
225 {
226 	TEE_Result res;
227 	uint32_t obj;
228 
229 	__utee_check_out_annotation(object, sizeof(*object));
230 
231 	res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj);
232 
233 	if (res != TEE_SUCCESS &&
234 	    res != TEE_ERROR_OUT_OF_MEMORY &&
235 	    res != TEE_ERROR_NOT_SUPPORTED)
236 		TEE_Panic(res);
237 
238 	if (res == TEE_SUCCESS)
239 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
240 
241 	return res;
242 }
243 
TEE_FreeTransientObject(TEE_ObjectHandle object)244 void TEE_FreeTransientObject(TEE_ObjectHandle object)
245 {
246 	struct utee_object_info info = { };
247 	TEE_Result res = TEE_SUCCESS;
248 
249 	if (object == TEE_HANDLE_NULL)
250 		return;
251 
252 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
253 	if (res != TEE_SUCCESS)
254 		TEE_Panic(res);
255 
256 	if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
257 		TEE_Panic(0);
258 
259 	res = _utee_cryp_obj_close((unsigned long)object);
260 	if (res != TEE_SUCCESS)
261 		TEE_Panic(res);
262 }
263 
TEE_ResetTransientObject(TEE_ObjectHandle object)264 void TEE_ResetTransientObject(TEE_ObjectHandle object)
265 {
266 	struct utee_object_info info = { };
267 	TEE_Result res = TEE_SUCCESS;
268 
269 	if (object == TEE_HANDLE_NULL)
270 		return;
271 
272 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
273 	if (res != TEE_SUCCESS)
274 		TEE_Panic(res);
275 
276 	if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
277 		TEE_Panic(0);
278 
279 	res = _utee_cryp_obj_reset((unsigned long)object);
280 	if (res != TEE_SUCCESS)
281 		TEE_Panic(res);
282 }
283 
TEE_PopulateTransientObject(TEE_ObjectHandle object,const TEE_Attribute * attrs,uint32_t attrCount)284 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
285 				       const TEE_Attribute *attrs,
286 				       uint32_t attrCount)
287 {
288 	struct utee_attribute ua[attrCount];
289 	struct utee_object_info info = { };
290 	TEE_Result res = TEE_SUCCESS;
291 
292 	__utee_check_attr_in_annotation(attrs, attrCount);
293 
294 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
295 	if (res != TEE_SUCCESS)
296 		TEE_Panic(res);
297 
298 	/* Must be a transient object */
299 	if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
300 		TEE_Panic(0);
301 
302 	/* Must not be initialized already */
303 	if ((info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
304 		TEE_Panic(0);
305 
306 	__utee_from_attr(ua, attrs, attrCount);
307 	res = _utee_cryp_obj_populate((unsigned long)object, ua, attrCount);
308 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
309 		TEE_Panic(res);
310 	return res;
311 }
312 
TEE_InitRefAttribute(TEE_Attribute * attr,uint32_t attributeID,const void * buffer,uint32_t length)313 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,
314 			  const void *buffer, uint32_t length)
315 {
316 	__utee_check_out_annotation(attr, sizeof(*attr));
317 
318 	if ((attributeID & TEE_ATTR_FLAG_VALUE) != 0)
319 		TEE_Panic(0);
320 	attr->attributeID = attributeID;
321 	attr->content.ref.buffer = (void *)buffer;
322 	attr->content.ref.length = length;
323 }
324 
TEE_InitValueAttribute(TEE_Attribute * attr,uint32_t attributeID,uint32_t a,uint32_t b)325 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,
326 			    uint32_t a, uint32_t b)
327 {
328 	__utee_check_out_annotation(attr, sizeof(*attr));
329 
330 	if ((attributeID & TEE_ATTR_FLAG_VALUE) == 0)
331 		TEE_Panic(0);
332 	attr->attributeID = attributeID;
333 	attr->content.value.a = a;
334 	attr->content.value.b = b;
335 }
336 
337 /*
338  * Use of this function is deprecated
339  * new code SHOULD use the TEE_CopyObjectAttributes1 function instead
340  * These functions will be removed at some future major revision of
341  * this specification
342  */
TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,TEE_ObjectHandle srcObject)343 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
344 			      TEE_ObjectHandle srcObject)
345 {
346 	struct utee_object_info src_info = { };
347 	TEE_Result res = TEE_SUCCESS;
348 
349 	res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
350 	if (src_info.obj_type == TEE_TYPE_CORRUPTED_OBJECT)
351 		return;
352 
353 	res = TEE_CopyObjectAttributes1(destObject, srcObject);
354 	if (res != TEE_SUCCESS)
355 		TEE_Panic(res);
356 }
357 
TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject,TEE_ObjectHandle srcObject)358 TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject,
359 			      TEE_ObjectHandle srcObject)
360 {
361 	struct utee_object_info dst_info = { };
362 	struct utee_object_info src_info = { };
363 	TEE_Result res = TEE_SUCCESS;
364 
365 	res = _utee_cryp_obj_get_info((unsigned long)destObject, &dst_info);
366 	if (res != TEE_SUCCESS)
367 		goto exit;
368 
369 	res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
370 	if (res != TEE_SUCCESS)
371 		goto exit;
372 
373 	if (!(src_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED))
374 		TEE_Panic(0);
375 
376 	if ((dst_info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT))
377 		TEE_Panic(0);
378 
379 	if ((dst_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED))
380 		TEE_Panic(0);
381 
382 	res = _utee_cryp_obj_copy((unsigned long)destObject,
383 				  (unsigned long)srcObject);
384 
385 exit:
386 	if (res != TEE_SUCCESS &&
387 	    res != TEE_ERROR_CORRUPT_OBJECT &&
388 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
389 		TEE_Panic(res);
390 
391 	return res;
392 }
393 
TEE_GenerateKey(TEE_ObjectHandle object,uint32_t keySize,const TEE_Attribute * params,uint32_t paramCount)394 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
395 			   const TEE_Attribute *params, uint32_t paramCount)
396 {
397 	TEE_Result res;
398 	struct utee_attribute ua[paramCount];
399 
400 	__utee_check_attr_in_annotation(params, paramCount);
401 
402 	__utee_from_attr(ua, params, paramCount);
403 	res = _utee_cryp_obj_generate_key((unsigned long)object, keySize,
404 					  ua, paramCount);
405 
406 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
407 		TEE_Panic(res);
408 
409 	return res;
410 }
411 
412 /* Data and Key Storage API  - Persistent Object Functions */
413 
TEE_OpenPersistentObject(uint32_t storageID,const void * objectID,uint32_t objectIDLen,uint32_t flags,TEE_ObjectHandle * object)414 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID,
415 				    uint32_t objectIDLen, uint32_t flags,
416 				    TEE_ObjectHandle *object)
417 {
418 	TEE_Result res;
419 	uint32_t obj;
420 
421 	__utee_check_out_annotation(object, sizeof(*object));
422 
423 	res = _utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
424 				     &obj);
425 	if (res == TEE_SUCCESS)
426 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
427 
428 	if (res != TEE_SUCCESS &&
429 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
430 	    res != TEE_ERROR_ACCESS_CONFLICT &&
431 	    res != TEE_ERROR_OUT_OF_MEMORY &&
432 	    res != TEE_ERROR_CORRUPT_OBJECT &&
433 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
434 		TEE_Panic(res);
435 
436 	if (res != TEE_SUCCESS)
437 		*object = TEE_HANDLE_NULL;
438 
439 	return res;
440 }
441 
TEE_CreatePersistentObject(uint32_t storageID,const void * objectID,uint32_t objectIDLen,uint32_t flags,TEE_ObjectHandle attributes,const void * initialData,uint32_t initialDataLen,TEE_ObjectHandle * object)442 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID,
443 				      uint32_t objectIDLen, uint32_t flags,
444 				      TEE_ObjectHandle attributes,
445 				      const void *initialData,
446 				      uint32_t initialDataLen,
447 				      TEE_ObjectHandle *object)
448 {
449 	TEE_Result res;
450 	uint32_t obj;
451 
452 	__utee_check_out_annotation(object, sizeof(*object));
453 
454 	res = _utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
455 				       (unsigned long)attributes, initialData,
456 				       initialDataLen, &obj);
457 
458 	if (res == TEE_SUCCESS)
459 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
460 
461 	if (res != TEE_SUCCESS &&
462 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
463 	    res != TEE_ERROR_ACCESS_CONFLICT &&
464 	    res != TEE_ERROR_OUT_OF_MEMORY &&
465 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
466 	    res != TEE_ERROR_CORRUPT_OBJECT &&
467 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
468 		TEE_Panic(res);
469 
470 	if (res != TEE_SUCCESS)
471 		*object = TEE_HANDLE_NULL;
472 
473 	return res;
474 }
475 
476 /*
477  * Use of this function is deprecated
478  * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
479  * These functions will be removed at some future major revision of
480  * this specification
481  */
TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)482 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
483 {
484 	TEE_Result res;
485 
486 	if (object == TEE_HANDLE_NULL)
487 		return;
488 
489 	res = TEE_CloseAndDeletePersistentObject1(object);
490 
491 	if (res != TEE_SUCCESS)
492 		TEE_Panic(0);
493 }
494 
TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)495 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
496 {
497 	TEE_Result res;
498 
499 	if (object == TEE_HANDLE_NULL)
500 		return TEE_SUCCESS;
501 
502 	res = _utee_storage_obj_del((unsigned long)object);
503 
504 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
505 		TEE_Panic(res);
506 
507 	return res;
508 }
509 
510 
TEE_RenamePersistentObject(TEE_ObjectHandle object,const void * newObjectID,uint32_t newObjectIDLen)511 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
512 				      const void *newObjectID,
513 				      uint32_t newObjectIDLen)
514 {
515 	TEE_Result res;
516 
517 	if (object == TEE_HANDLE_NULL) {
518 		res = TEE_ERROR_ITEM_NOT_FOUND;
519 		goto out;
520 	}
521 
522 	res = _utee_storage_obj_rename((unsigned long)object, newObjectID,
523 				       newObjectIDLen);
524 
525 out:
526 	if (res != TEE_SUCCESS &&
527 	    res != TEE_ERROR_ACCESS_CONFLICT &&
528 	    res != TEE_ERROR_CORRUPT_OBJECT &&
529 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
530 		TEE_Panic(res);
531 
532 	return res;
533 }
534 
TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * objectEnumerator)535 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
536 						  objectEnumerator)
537 {
538 	TEE_Result res;
539 	uint32_t oe;
540 
541 	__utee_check_out_annotation(objectEnumerator,
542 				    sizeof(*objectEnumerator));
543 
544 	res = _utee_storage_alloc_enum(&oe);
545 
546 	if (res != TEE_SUCCESS)
547 		oe = TEE_HANDLE_NULL;
548 
549 	*objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe;
550 
551 	if (res != TEE_SUCCESS &&
552 	    res != TEE_ERROR_ACCESS_CONFLICT)
553 		TEE_Panic(res);
554 
555 	return res;
556 }
557 
TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)558 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
559 {
560 	TEE_Result res;
561 
562 	if (objectEnumerator == TEE_HANDLE_NULL)
563 		return;
564 
565 	res = _utee_storage_free_enum((unsigned long)objectEnumerator);
566 
567 	if (res != TEE_SUCCESS)
568 		TEE_Panic(res);
569 }
570 
TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)571 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
572 {
573 	TEE_Result res;
574 
575 	if (objectEnumerator == TEE_HANDLE_NULL)
576 		return;
577 
578 	res = _utee_storage_reset_enum((unsigned long)objectEnumerator);
579 
580 	if (res != TEE_SUCCESS)
581 		TEE_Panic(res);
582 }
583 
TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator,uint32_t storageID)584 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
585 					       objectEnumerator,
586 					       uint32_t storageID)
587 {
588 	TEE_Result res;
589 
590 	res = _utee_storage_start_enum((unsigned long)objectEnumerator,
591 				       storageID);
592 
593 	if (res != TEE_SUCCESS &&
594 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
595 	    res != TEE_ERROR_CORRUPT_OBJECT &&
596 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
597 		TEE_Panic(res);
598 
599 	return res;
600 }
601 
TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,TEE_ObjectInfo * objectInfo,void * objectID,uint32_t * objectIDLen)602 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
603 				       TEE_ObjectInfo *objectInfo,
604 				       void *objectID, uint32_t *objectIDLen)
605 {
606 	struct utee_object_info info = { };
607 	TEE_Result res = TEE_SUCCESS;
608 	uint64_t len = 0;
609 
610 	if (objectInfo)
611 		__utee_check_out_annotation(objectInfo, sizeof(*objectInfo));
612 	__utee_check_out_annotation(objectIDLen, sizeof(*objectIDLen));
613 
614 	if (!objectID) {
615 		res = TEE_ERROR_BAD_PARAMETERS;
616 		goto out;
617 	}
618 
619 	len = *objectIDLen;
620 	res = _utee_storage_next_enum((unsigned long)objectEnumerator,
621 				      &info, objectID, &len);
622 	if (objectInfo) {
623 		objectInfo->objectType = info.obj_type;
624 		objectInfo->keySize = info.obj_size;
625 		objectInfo->maxKeySize = info.max_obj_size;
626 		objectInfo->objectUsage = info.obj_usage;
627 		objectInfo->dataSize = info.data_size;
628 		objectInfo->dataPosition = info.data_pos;
629 		objectInfo->handleFlags = info.handle_flags;
630 	}
631 	*objectIDLen = len;
632 
633 out:
634 	if (res != TEE_SUCCESS &&
635 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
636 	    res != TEE_ERROR_CORRUPT_OBJECT &&
637 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
638 		TEE_Panic(res);
639 
640 	return res;
641 }
642 
643 /* Data and Key Storage API  - Data Stream Access Functions */
644 
TEE_ReadObjectData(TEE_ObjectHandle object,void * buffer,uint32_t size,uint32_t * count)645 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
646 			      uint32_t size, uint32_t *count)
647 {
648 	TEE_Result res;
649 	uint64_t cnt64;
650 
651 	if (object == TEE_HANDLE_NULL) {
652 		res = TEE_ERROR_BAD_PARAMETERS;
653 		goto out;
654 	}
655 	__utee_check_out_annotation(count, sizeof(*count));
656 
657 	cnt64 = *count;
658 	res = _utee_storage_obj_read((unsigned long)object, buffer, size,
659 				     &cnt64);
660 	*count = cnt64;
661 
662 out:
663 	if (res != TEE_SUCCESS &&
664 	    res != TEE_ERROR_CORRUPT_OBJECT &&
665 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
666 		TEE_Panic(res);
667 
668 	return res;
669 }
670 
TEE_WriteObjectData(TEE_ObjectHandle object,const void * buffer,uint32_t size)671 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer,
672 			       uint32_t size)
673 {
674 	TEE_Result res;
675 
676 	if (object == TEE_HANDLE_NULL) {
677 		res = TEE_ERROR_BAD_PARAMETERS;
678 		goto out;
679 	}
680 
681 	if (size > TEE_DATA_MAX_POSITION) {
682 		res = TEE_ERROR_OVERFLOW;
683 		goto out;
684 	}
685 
686 	res = _utee_storage_obj_write((unsigned long)object, buffer, size);
687 
688 out:
689 	if (res != TEE_SUCCESS &&
690 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
691 	    res != TEE_ERROR_OVERFLOW &&
692 	    res != TEE_ERROR_CORRUPT_OBJECT &&
693 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
694 		TEE_Panic(res);
695 
696 	return res;
697 }
698 
TEE_TruncateObjectData(TEE_ObjectHandle object,uint32_t size)699 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
700 {
701 	TEE_Result res;
702 
703 	if (object == TEE_HANDLE_NULL) {
704 		res = TEE_ERROR_BAD_PARAMETERS;
705 		goto out;
706 	}
707 
708 	res = _utee_storage_obj_trunc((unsigned long)object, size);
709 
710 out:
711 	if (res != TEE_SUCCESS &&
712 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
713 	    res != TEE_ERROR_CORRUPT_OBJECT &&
714 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
715 		TEE_Panic(res);
716 
717 	return res;
718 }
719 
TEE_SeekObjectData(TEE_ObjectHandle object,int32_t offset,TEE_Whence whence)720 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
721 			      TEE_Whence whence)
722 {
723 	struct utee_object_info info = { };
724 	TEE_Result res = TEE_SUCCESS;
725 
726 	if (object == TEE_HANDLE_NULL) {
727 		res = TEE_ERROR_BAD_PARAMETERS;
728 		goto out;
729 	}
730 
731 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
732 	if (res != TEE_SUCCESS)
733 		goto out;
734 
735 	switch (whence) {
736 	case TEE_DATA_SEEK_SET:
737 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) {
738 			res = TEE_ERROR_OVERFLOW;
739 			goto out;
740 		}
741 		break;
742 	case TEE_DATA_SEEK_CUR:
743 		if (offset > 0 &&
744 		    ((uint32_t)offset + info.data_pos > TEE_DATA_MAX_POSITION ||
745 		     (uint32_t)offset + info.data_pos < info.data_pos)) {
746 			res = TEE_ERROR_OVERFLOW;
747 			goto out;
748 		}
749 		break;
750 	case TEE_DATA_SEEK_END:
751 		if (offset > 0 &&
752 		    ((uint32_t)offset + info.data_size >
753 		     TEE_DATA_MAX_POSITION ||
754 		     (uint32_t)offset + info.data_size < info.data_size)) {
755 			res = TEE_ERROR_OVERFLOW;
756 			goto out;
757 		}
758 		break;
759 	default:
760 		res = TEE_ERROR_ITEM_NOT_FOUND;
761 		goto out;
762 	}
763 
764 	res = _utee_storage_obj_seek((unsigned long)object, offset, whence);
765 
766 out:
767 	if (res != TEE_SUCCESS &&
768 	    res != TEE_ERROR_OVERFLOW &&
769 	    res != TEE_ERROR_CORRUPT_OBJECT &&
770 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
771 		TEE_Panic(res);
772 
773 	return res;
774 }
775