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