xref: /optee_os/lib/libutee/tee_api_objects.c (revision 79a3c601fa657bb596483d8c215d659a6e9d0021)
1 /*
2  * Copyright (c) 2014, STMicroelectronics International N.V.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include <tee_api.h>
31 #include <utee_syscalls.h>
32 
33 #include <assert.h>
34 
35 #define TEE_USAGE_DEFAULT   0xffffffff
36 
37 #define TEE_ATTR_BIT_VALUE                  (1 << 29)
38 #define TEE_ATTR_BIT_PROTECTED              (1 << 28)
39 
40 /* Data and Key Storage API  - Generic Object Functions */
41 void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
42 {
43 	TEE_Result res;
44 
45 	res = utee_cryp_obj_get_info((uint32_t)object, objectInfo);
46 	if (res != TEE_SUCCESS)
47 		TEE_Panic(res);
48 }
49 
50 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage)
51 {
52 	TEE_Result res;
53 	res = utee_cryp_obj_restrict_usage((uint32_t)object, objectUsage);
54 
55 	if (res != TEE_SUCCESS)
56 		TEE_Panic(0);
57 }
58 
59 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
60 					uint32_t attributeID, void *buffer,
61 					uint32_t *size)
62 {
63 	TEE_Result res;
64 	TEE_ObjectInfo info;
65 
66 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
67 	if (res != TEE_SUCCESS)
68 		TEE_Panic(0);
69 
70 	if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
71 		TEE_Panic(0);
72 
73 	/* This function only supports reference attributes */
74 	if ((attributeID & TEE_ATTR_BIT_VALUE) != 0)
75 		TEE_Panic(0);
76 
77 	res =
78 	    utee_cryp_obj_get_attr((uint32_t)object, attributeID, buffer,
79 				   size);
80 
81 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND &&
82 	    res != TEE_ERROR_SHORT_BUFFER)
83 		TEE_Panic(0);
84 
85 	return res;
86 }
87 
88 TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
89 				       uint32_t attributeID, uint32_t *a,
90 				       uint32_t *b)
91 {
92 	TEE_Result res;
93 	TEE_ObjectInfo info;
94 	uint32_t buf[2];
95 	size_t size = sizeof(buf);
96 
97 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
98 	if (res != TEE_SUCCESS)
99 		TEE_Panic(0);
100 
101 	if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
102 		TEE_Panic(0);
103 
104 	/* This function only supports value attributes */
105 	if ((attributeID & TEE_ATTR_BIT_VALUE) == 0)
106 		TEE_Panic(0);
107 
108 	res =
109 	    utee_cryp_obj_get_attr((uint32_t)object, attributeID, buf, &size);
110 
111 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND &&
112 	    res != TEE_ERROR_ACCESS_DENIED)
113 		TEE_Panic(0);
114 
115 	if (size != sizeof(buf))
116 		TEE_Panic(0);
117 
118 	*a = buf[0];
119 	*b = buf[1];
120 
121 	return res;
122 }
123 
124 void TEE_CloseObject(TEE_ObjectHandle object)
125 {
126 	TEE_Result res;
127 
128 	if (object == TEE_HANDLE_NULL)
129 		return;
130 
131 	res = utee_cryp_obj_close((uint32_t)object);
132 	if (res != TEE_SUCCESS)
133 		TEE_Panic(0);
134 }
135 
136 /* Data and Key Storage API  - Transient Object Functions */
137 
138 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,
139 				       uint32_t maxKeySize,
140 				       TEE_ObjectHandle *object)
141 {
142 	TEE_Result res;
143 	uint32_t obj;
144 
145 	res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj);
146 	if (res == TEE_SUCCESS)
147 		*object = (TEE_ObjectHandle) obj;
148 	return res;
149 }
150 
151 void TEE_FreeTransientObject(TEE_ObjectHandle object)
152 {
153 	TEE_Result res;
154 	TEE_ObjectInfo info;
155 
156 	if (object == TEE_HANDLE_NULL)
157 		return;
158 
159 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
160 	if (res != TEE_SUCCESS)
161 		TEE_Panic(0);
162 
163 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
164 		TEE_Panic(0);
165 
166 	res = utee_cryp_obj_close((uint32_t)object);
167 	if (res != TEE_SUCCESS)
168 		TEE_Panic(0);
169 }
170 
171 void TEE_ResetTransientObject(TEE_ObjectHandle object)
172 {
173 	TEE_Result res;
174 	TEE_ObjectInfo info;
175 
176 	if (object == TEE_HANDLE_NULL)
177 		return;
178 
179 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
180 	if (res != TEE_SUCCESS)
181 		TEE_Panic(0);
182 
183 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
184 		TEE_Panic(0);
185 
186 	res = utee_cryp_obj_reset((uint32_t)object);
187 	if (res != TEE_SUCCESS)
188 		TEE_Panic(0);
189 }
190 
191 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
192 				       TEE_Attribute *attrs,
193 				       uint32_t attrCount)
194 {
195 	TEE_Result res;
196 	TEE_ObjectInfo info;
197 
198 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
199 	if (res != TEE_SUCCESS)
200 		TEE_Panic(0);
201 
202 	/* Must be a transient object */
203 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
204 		TEE_Panic(0);
205 
206 	/* Must not be initialized already */
207 	if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
208 		TEE_Panic(0);
209 
210 	res = utee_cryp_obj_populate((uint32_t)object, attrs, attrCount);
211 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
212 		TEE_Panic(res);
213 	return res;
214 }
215 
216 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,
217 			  void *buffer, uint32_t length)
218 {
219 	if (attr == NULL)
220 		TEE_Panic(0);
221 	if ((attributeID & TEE_ATTR_BIT_VALUE) != 0)
222 		TEE_Panic(0);
223 	attr->attributeID = attributeID;
224 	attr->content.ref.buffer = buffer;
225 	attr->content.ref.length = length;
226 }
227 
228 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,
229 			    uint32_t a, uint32_t b)
230 {
231 	if (attr == NULL)
232 		TEE_Panic(0);
233 	if ((attributeID & TEE_ATTR_BIT_VALUE) == 0)
234 		TEE_Panic(0);
235 	attr->attributeID = attributeID;
236 	attr->content.value.a = a;
237 	attr->content.value.b = b;
238 }
239 
240 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
241 			      TEE_ObjectHandle srcObject)
242 {
243 	TEE_Result res;
244 	TEE_ObjectInfo dst_info;
245 	TEE_ObjectInfo src_info;
246 
247 	res = utee_cryp_obj_get_info((uint32_t)destObject, &dst_info);
248 	if (res != TEE_SUCCESS)
249 		TEE_Panic(0);
250 
251 	res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info);
252 	if (res != TEE_SUCCESS)
253 		TEE_Panic(0);
254 
255 	if ((src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
256 		TEE_Panic(0);
257 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
258 		TEE_Panic(0);
259 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
260 		TEE_Panic(0);
261 
262 	res = utee_cryp_obj_copy((uint32_t)destObject, (uint32_t)srcObject);
263 	if (res != TEE_SUCCESS)
264 		TEE_Panic(0);
265 }
266 
267 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
268 			   TEE_Attribute *params, uint32_t paramCount)
269 {
270 	TEE_Result res;
271 
272 	res = utee_cryp_obj_generate_key((uint32_t)object, keySize,
273 					 params, paramCount);
274 
275 	if (res != TEE_SUCCESS)
276 		TEE_Panic(0);
277 
278 	return res;
279 }
280 
281 /* Data and Key Storage API  - Persistent Object Functions */
282 
283 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, void *objectID,
284 				    uint32_t objectIDLen, uint32_t flags,
285 				    TEE_ObjectHandle *object)
286 {
287 	if (storageID != TEE_STORAGE_PRIVATE)
288 		return TEE_ERROR_ITEM_NOT_FOUND;
289 
290 	if (objectID == NULL)
291 		return TEE_ERROR_ITEM_NOT_FOUND;
292 
293 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN)
294 		TEE_Panic(0);
295 
296 	if (object == NULL)
297 		return TEE_ERROR_BAD_PARAMETERS;
298 
299 	return utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
300 				     object);
301 }
302 
303 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, void *objectID,
304 				      uint32_t objectIDLen, uint32_t flags,
305 				      TEE_ObjectHandle attributes,
306 				      const void *initialData,
307 				      uint32_t initialDataLen,
308 				      TEE_ObjectHandle *object)
309 {
310 	if (storageID != TEE_STORAGE_PRIVATE)
311 		return TEE_ERROR_ITEM_NOT_FOUND;
312 
313 	if (objectID == NULL)
314 		return TEE_ERROR_ITEM_NOT_FOUND;
315 
316 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN)
317 		TEE_Panic(0);
318 
319 	if (object == NULL)
320 		return TEE_ERROR_BAD_PARAMETERS;
321 
322 	return utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
323 				       attributes, initialData, initialDataLen,
324 				       object);
325 }
326 
327 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
328 {
329 	TEE_Result res;
330 
331 	if (object == TEE_HANDLE_NULL)
332 		return;
333 
334 	res = utee_storage_obj_del(object);
335 
336 	if (res != TEE_SUCCESS)
337 		TEE_Panic(0);
338 }
339 
340 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
341 				      const void *newObjectID,
342 				      uint32_t newObjectIDLen)
343 {
344 	TEE_Result res;
345 
346 	if (object == TEE_HANDLE_NULL)
347 		return TEE_ERROR_ITEM_NOT_FOUND;
348 
349 	if (newObjectID == NULL)
350 		return TEE_ERROR_BAD_PARAMETERS;
351 
352 	if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN)
353 		TEE_Panic(0);
354 
355 	res = utee_storage_obj_rename(object, newObjectID, newObjectIDLen);
356 
357 	if (res != TEE_SUCCESS && res != TEE_ERROR_ACCESS_CONFLICT)
358 		TEE_Panic(0);
359 
360 	return res;
361 }
362 
363 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
364 						  objectEnumerator)
365 {
366 	TEE_Result res;
367 
368 	if (objectEnumerator == NULL)
369 		return TEE_ERROR_BAD_PARAMETERS;
370 
371 	res = utee_storage_alloc_enum(objectEnumerator);
372 
373 	if (res != TEE_SUCCESS)
374 		*objectEnumerator = TEE_HANDLE_NULL;
375 
376 	return res;
377 }
378 
379 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
380 {
381 	TEE_Result res;
382 
383 	if (objectEnumerator == TEE_HANDLE_NULL)
384 		return;
385 
386 	res = utee_storage_free_enum(objectEnumerator);
387 
388 	if (res != TEE_SUCCESS)
389 		TEE_Panic(0);
390 }
391 
392 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
393 {
394 	TEE_Result res;
395 
396 	if (objectEnumerator == TEE_HANDLE_NULL)
397 		return;
398 
399 	res = utee_storage_reset_enum(objectEnumerator);
400 
401 	if (res != TEE_SUCCESS)
402 		TEE_Panic(0);
403 }
404 
405 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
406 					       objectEnumerator,
407 					       uint32_t storageID)
408 {
409 	TEE_Result res;
410 
411 	if (storageID != TEE_STORAGE_PRIVATE)
412 		return TEE_ERROR_ITEM_NOT_FOUND;
413 
414 	res = utee_storage_start_enum(objectEnumerator, storageID);
415 
416 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
417 		TEE_Panic(0);
418 
419 	return res;
420 }
421 
422 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
423 				       TEE_ObjectInfo *objectInfo,
424 				       void *objectID, uint32_t *objectIDLen)
425 {
426 	TEE_Result res;
427 
428 	res =
429 	    utee_storage_next_enum(objectEnumerator, objectInfo, objectID,
430 				   objectIDLen);
431 
432 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
433 		TEE_Panic(0);
434 
435 	return res;
436 }
437 
438 /* Data and Key Storage API  - Data Stream Access Functions */
439 
440 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
441 			      uint32_t size, uint32_t *count)
442 {
443 	TEE_Result res;
444 
445 	if (object == TEE_HANDLE_NULL)
446 		TEE_Panic(0);
447 
448 	res = utee_storage_obj_read(object, buffer, size, count);
449 
450 	if (res != TEE_SUCCESS)
451 		TEE_Panic(0);
452 
453 	return res;
454 }
455 
456 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void *buffer,
457 			       uint32_t size)
458 {
459 	TEE_Result res;
460 
461 	if (object == TEE_HANDLE_NULL)
462 		TEE_Panic(0);
463 
464 	res = utee_storage_obj_write(object, buffer, size);
465 
466 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE)
467 		TEE_Panic(0);
468 
469 	return res;
470 }
471 
472 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
473 {
474 	TEE_Result res;
475 
476 	if (object == TEE_HANDLE_NULL)
477 		TEE_Panic(0);
478 
479 	res = utee_storage_obj_trunc(object, size);
480 
481 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE)
482 		TEE_Panic(0);
483 
484 	return res;
485 }
486 
487 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
488 			      TEE_Whence whence)
489 {
490 	TEE_Result res;
491 	TEE_ObjectInfo info;
492 
493 	if (object == TEE_HANDLE_NULL)
494 		TEE_Panic(0);
495 
496 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
497 	if (res != TEE_SUCCESS)
498 		TEE_Panic(0);
499 
500 	switch (whence) {
501 	case TEE_DATA_SEEK_SET:
502 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION)
503 			return TEE_ERROR_OVERFLOW;
504 		break;
505 	case TEE_DATA_SEEK_CUR:
506 		if (offset > 0 &&
507 		    ((uint32_t)offset + info.dataPosition >
508 		     TEE_DATA_MAX_POSITION ||
509 		     (uint32_t)offset + info.dataPosition <
510 		     info.dataPosition))
511 			return TEE_ERROR_OVERFLOW;
512 		break;
513 	case TEE_DATA_SEEK_END:
514 		if (offset > 0 &&
515 		    ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
516 		     (uint32_t)offset + info.dataSize < info.dataSize))
517 			return TEE_ERROR_OVERFLOW;
518 		break;
519 	default:
520 		TEE_Panic(0);
521 	}
522 
523 	res = utee_storage_obj_seek(object, offset, whence);
524 
525 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW)
526 		TEE_Panic(0);
527 
528 	return res;
529 }
530