1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * All rights reserved.
5  */
6 
7 #include "storage.h"
8 #include "ta_storage.h"
9 
10 #include <tee_api.h>
11 #include <trace.h>
12 
13 #define ASSERT_PARAM_TYPE(pt) \
14 do { \
15 	if ((pt) != param_types) \
16 		return TEE_ERROR_BAD_PARAMETERS; \
17 } while (0)
18 
19 #define VAL2HANDLE(v) (void *)(uintptr_t)(v)
20 
ta_storage_cmd_open(uint32_t command,uint32_t param_types,TEE_Param params[4])21 TEE_Result ta_storage_cmd_open(uint32_t command,
22 				uint32_t param_types, TEE_Param params[4])
23 {
24 	TEE_Result res = TEE_ERROR_GENERIC;
25 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
26 	void *object_id = NULL;
27 
28 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
29 			  (TEE_PARAM_TYPE_MEMREF_INPUT,
30 			   TEE_PARAM_TYPE_VALUE_INOUT,
31 			   TEE_PARAM_TYPE_VALUE_INPUT,
32 			   TEE_PARAM_TYPE_NONE));
33 
34 	switch (command) {
35 	case TA_STORAGE_CMD_OPEN:
36 		if (params[0].memref.buffer) {
37 			object_id = TEE_Malloc(params[0].memref.size, 0);
38 			if (!object_id)
39 				return TEE_ERROR_OUT_OF_MEMORY;
40 
41 			TEE_MemMove(object_id, params[0].memref.buffer,
42 				    params[0].memref.size);
43 		}
44 		break;
45 	case TA_STORAGE_CMD_OPEN_ID_IN_SHM:
46 		object_id = params[0].memref.buffer;
47 		break;
48 	default:
49 		return TEE_ERROR_NOT_SUPPORTED;
50 	}
51 
52 	res = TEE_OpenPersistentObject(params[2].value.a,
53 					object_id, params[0].memref.size,
54 					params[1].value.a, &o);
55 
56 	params[1].value.b = (uintptr_t)o;
57 
58 	if (command == TA_STORAGE_CMD_OPEN)
59 		TEE_Free(object_id);
60 
61 	return res;
62 }
63 
ta_storage_cmd_create(uint32_t command,uint32_t param_types,TEE_Param params[4])64 TEE_Result ta_storage_cmd_create(uint32_t command,
65 				 uint32_t param_types, TEE_Param params[4])
66 {
67 	TEE_Result res = TEE_ERROR_GENERIC;
68 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
69 	void *object_id = NULL;
70 	TEE_ObjectHandle ref_handle = TEE_HANDLE_NULL;
71 
72 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
73 			  (TEE_PARAM_TYPE_MEMREF_INPUT,
74 			   TEE_PARAM_TYPE_VALUE_INOUT,
75 			   TEE_PARAM_TYPE_VALUE_INPUT,
76 			   TEE_PARAM_TYPE_MEMREF_INPUT));
77 
78 	switch (command) {
79 	case TA_STORAGE_CMD_CREATE:
80 		if (params[0].memref.buffer) {
81 			object_id = TEE_Malloc(params[0].memref.size, 0);
82 			if (!object_id)
83 				return TEE_ERROR_OUT_OF_MEMORY;
84 
85 			TEE_MemMove(object_id, params[0].memref.buffer,
86 				    params[0].memref.size);
87 		}
88 		break;
89 	case TA_STORAGE_CMD_CREATE_ID_IN_SHM:
90 		object_id = params[0].memref.buffer;
91 		break;
92 	default:
93 		return TEE_ERROR_NOT_SUPPORTED;
94 	}
95 
96 	ref_handle = (TEE_ObjectHandle)(uintptr_t)params[2].value.a;
97 
98 	res = TEE_CreatePersistentObject(params[2].value.b,
99 					 object_id, params[0].memref.size,
100 					 params[1].value.a, ref_handle,
101 					 params[3].memref.buffer,
102 					 params[3].memref.size, &o);
103 
104 	if (command == TA_STORAGE_CMD_CREATE)
105 		TEE_Free(object_id);
106 
107 	params[1].value.b = (uintptr_t)o;
108 
109 	return res;
110 }
111 
ta_storage_cmd_create_overwrite(uint32_t command,uint32_t param_types,TEE_Param params[4])112 TEE_Result ta_storage_cmd_create_overwrite(uint32_t command,
113 					   uint32_t param_types,
114 					   TEE_Param params[4])
115 {
116 	TEE_Result res = TEE_ERROR_GENERIC;
117 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
118 	void *object_id = NULL;
119 
120 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
121 			  (TEE_PARAM_TYPE_MEMREF_INPUT,
122 			   TEE_PARAM_TYPE_VALUE_INPUT,
123 			   TEE_PARAM_TYPE_NONE,
124 			   TEE_PARAM_TYPE_NONE));
125 
126 	switch (command) {
127 	case TA_STORAGE_CMD_CREATE_OVERWRITE:
128 		object_id = TEE_Malloc(params[0].memref.size, 0);
129 		if (!object_id)
130 			return TEE_ERROR_OUT_OF_MEMORY;
131 
132 		TEE_MemMove(object_id, params[0].memref.buffer,
133 			    params[0].memref.size);
134 		break;
135 	case TA_STORAGE_CMD_CREATEOVER_ID_IN_SHM:
136 		object_id = params[0].memref.buffer;
137 		break;
138 	default:
139 		return TEE_ERROR_NOT_SUPPORTED;
140 	}
141 
142 	res = TEE_CreatePersistentObject(params[1].value.a,
143 					 object_id, params[0].memref.size,
144 					 TEE_DATA_FLAG_OVERWRITE,
145 					 NULL, NULL, 0, &o);
146 	TEE_CloseObject(o);
147 
148 	if (command == TA_STORAGE_CMD_CREATE_OVERWRITE)
149 		TEE_Free(object_id);
150 
151 	return res;
152 }
153 
ta_storage_cmd_close(uint32_t param_types,TEE_Param params[4])154 TEE_Result ta_storage_cmd_close(uint32_t param_types, TEE_Param params[4])
155 {
156 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
157 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
158 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
159 
160 	TEE_CloseObject((TEE_ObjectHandle)(uintptr_t)params[0].value.a);
161 
162 	return TEE_SUCCESS;
163 }
164 
ta_storage_cmd_read(uint32_t param_types,TEE_Param params[4])165 TEE_Result ta_storage_cmd_read(uint32_t param_types, TEE_Param params[4])
166 {
167 	TEE_ObjectHandle o = VAL2HANDLE(params[1].value.a);
168 	TEE_Result res = TEE_SUCCESS;
169 	void *b0 = NULL;
170 
171 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
172 			  (TEE_PARAM_TYPE_MEMREF_OUTPUT,
173 			   TEE_PARAM_TYPE_VALUE_INOUT, TEE_PARAM_TYPE_NONE,
174 			   TEE_PARAM_TYPE_NONE));
175 
176 	b0 = TEE_Malloc(params[0].memref.size, 0);
177 	if (!b0)
178 		return TEE_ERROR_OUT_OF_MEMORY;
179 
180 	res = TEE_ReadObjectData(o, b0, params[0].memref.size,
181 				 &params[1].value.b);
182 	if (!res)
183 		TEE_MemMove(params[0].memref.buffer, b0, params[0].memref.size);
184 	TEE_Free(b0);
185 
186 	return res;
187 }
188 
ta_storage_cmd_write(uint32_t param_types,TEE_Param params[4])189 TEE_Result ta_storage_cmd_write(uint32_t param_types, TEE_Param params[4])
190 {
191 	TEE_ObjectHandle o = VAL2HANDLE(params[1].value.a);
192 	TEE_Result res = TEE_SUCCESS;
193 	void *b0 = NULL;
194 
195 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
196 			  (TEE_PARAM_TYPE_MEMREF_INPUT,
197 			   TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
198 			   TEE_PARAM_TYPE_NONE));
199 
200 	b0 = TEE_Malloc(params[0].memref.size, 0);
201 	if (!b0)
202 		return TEE_ERROR_OUT_OF_MEMORY;
203 	TEE_MemMove(b0, params[0].memref.buffer, params[0].memref.size);
204 
205 	res = TEE_WriteObjectData(o, b0, params[0].memref.size);
206 	TEE_Free(b0);
207 
208 	return res;
209 }
210 
ta_storage_cmd_seek(uint32_t param_types,TEE_Param params[4])211 TEE_Result ta_storage_cmd_seek(uint32_t param_types, TEE_Param params[4])
212 {
213 	TEE_Result res = TEE_ERROR_GENERIC;
214 	TEE_ObjectInfo info;
215 	TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
216 	int32_t offs = 0;
217 
218 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
219 			  (TEE_PARAM_TYPE_VALUE_INPUT,
220 			   TEE_PARAM_TYPE_VALUE_INOUT, TEE_PARAM_TYPE_NONE,
221 			   TEE_PARAM_TYPE_NONE));
222 
223 	offs = *(int32_t *)&params[0].value.b;
224 	res = TEE_SeekObjectData(o, offs, params[1].value.a);
225 	if (res != TEE_SUCCESS)
226 		return res;
227 	res = TEE_GetObjectInfo1(o, &info);
228 
229 	params[1].value.b = info.dataPosition;
230 
231 	return res;
232 }
233 
ta_storage_cmd_unlink(uint32_t param_types,TEE_Param params[4])234 TEE_Result ta_storage_cmd_unlink(uint32_t param_types, TEE_Param params[4])
235 {
236 	TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
237 
238 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
239 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
240 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
241 
242 	TEE_CloseAndDeletePersistentObject1(o);
243 
244 	return TEE_SUCCESS;
245 }
246 
ta_storage_cmd_rename(uint32_t command,uint32_t param_types,TEE_Param params[4])247 TEE_Result ta_storage_cmd_rename(uint32_t command, uint32_t param_types,
248 				 TEE_Param params[4])
249 {
250 	TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
251 	void *object_id = NULL;
252 	TEE_Result res = TEE_ERROR_GENERIC;
253 
254 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
255 			  (TEE_PARAM_TYPE_VALUE_INPUT,
256 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
257 			   TEE_PARAM_TYPE_NONE));
258 
259 	switch (command) {
260 	case TA_STORAGE_CMD_RENAME:
261 		if (params[0].memref.buffer) {
262 			object_id = TEE_Malloc(params[1].memref.size, 0);
263 			if (!object_id)
264 				return TEE_ERROR_OUT_OF_MEMORY;
265 
266 			TEE_MemMove(object_id, params[1].memref.buffer,
267 				    params[1].memref.size);
268 		}
269 		break;
270 	case TA_STORAGE_CMD_RENAME_ID_IN_SHM:
271 		object_id = params[1].memref.buffer;
272 		break;
273 	default:
274 		return TEE_ERROR_NOT_SUPPORTED;
275 	}
276 
277 	res = TEE_RenamePersistentObject(o, object_id, params[1].memref.size);
278 
279 	if (command == TA_STORAGE_CMD_RENAME)
280 		TEE_Free(object_id);
281 
282 	return res;
283 }
284 
ta_storage_cmd_trunc(uint32_t param_types,TEE_Param params[4])285 TEE_Result ta_storage_cmd_trunc(uint32_t param_types, TEE_Param params[4])
286 {
287 	TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
288 
289 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
290 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
291 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
292 
293 	return TEE_TruncateObjectData(o, params[0].value.b);
294 }
295 
ta_storage_cmd_alloc_enum(uint32_t param_types,TEE_Param params[4])296 TEE_Result ta_storage_cmd_alloc_enum(uint32_t param_types, TEE_Param params[4])
297 {
298 	TEE_Result res = TEE_ERROR_GENERIC;
299 	TEE_ObjectEnumHandle oe = TEE_HANDLE_NULL;
300 
301 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
302 			  (TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE,
303 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
304 
305 	res = TEE_AllocatePersistentObjectEnumerator(&oe);
306 	params[0].value.a = (uintptr_t)oe;
307 	return res;
308 }
309 
ta_storage_cmd_free_enum(uint32_t param_types,TEE_Param params[4])310 TEE_Result ta_storage_cmd_free_enum(uint32_t param_types, TEE_Param params[4])
311 {
312 	TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
313 
314 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
315 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
316 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
317 
318 	TEE_FreePersistentObjectEnumerator(oe);
319 	return TEE_SUCCESS;
320 }
321 
ta_storage_cmd_reset_enum(uint32_t param_types,TEE_Param params[4])322 TEE_Result ta_storage_cmd_reset_enum(uint32_t param_types, TEE_Param params[4])
323 {
324 	TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
325 
326 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
327 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
328 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
329 
330 	TEE_ResetPersistentObjectEnumerator(oe);
331 	return TEE_SUCCESS;
332 }
333 
ta_storage_cmd_start_enum(uint32_t param_types,TEE_Param params[4])334 TEE_Result ta_storage_cmd_start_enum(uint32_t param_types, TEE_Param params[4])
335 {
336 	TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
337 
338 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
339 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
340 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
341 
342 	return TEE_StartPersistentObjectEnumerator(oe, params[0].value.b);
343 }
344 
ta_storage_cmd_next_enum(uint32_t param_types,TEE_Param params[4])345 TEE_Result ta_storage_cmd_next_enum(uint32_t param_types, TEE_Param params[4])
346 {
347 	TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
348 	TEE_Result res = TEE_SUCCESS;
349 	TEE_ObjectInfo *obj = NULL;
350 	void *b2 = NULL;
351 
352 	if (TEE_PARAM_TYPE_GET(param_types, 0) != TEE_PARAM_TYPE_VALUE_INPUT)
353 		return TEE_ERROR_BAD_PARAMETERS;
354 	if (TEE_PARAM_TYPE_GET(param_types, 2) != TEE_PARAM_TYPE_MEMREF_OUTPUT)
355 		return TEE_ERROR_BAD_PARAMETERS;
356 	if (TEE_PARAM_TYPE_GET(param_types, 3) != TEE_PARAM_TYPE_NONE)
357 		return TEE_ERROR_BAD_PARAMETERS;
358 
359 	if (params[2].memref.size < TEE_OBJECT_ID_MAX_LEN)
360 		return TEE_ERROR_SHORT_BUFFER;
361 
362 	if (TEE_PARAM_TYPE_GET(param_types, 1) == TEE_PARAM_TYPE_NONE)
363 		obj = NULL;
364 	else if (TEE_PARAM_TYPE_GET(param_types, 1) ==
365 		 TEE_PARAM_TYPE_MEMREF_OUTPUT) {
366 		if (params[1].memref.size < sizeof(TEE_ObjectInfo)) {
367 			params[1].memref.size = sizeof(TEE_ObjectInfo);
368 			return TEE_ERROR_SHORT_BUFFER;
369 		}
370 		params[1].memref.size = sizeof(TEE_ObjectInfo);
371 		obj = TEE_Malloc(sizeof(TEE_ObjectInfo), 0);
372 		if (!obj)
373 			return TEE_ERROR_OUT_OF_MEMORY;
374 	} else
375 		return TEE_ERROR_BAD_PARAMETERS;
376 
377 	b2 = TEE_Malloc(params[2].memref.size, 0);
378 	if (!b2) {
379 		res = TEE_ERROR_OUT_OF_MEMORY;
380 		goto out;
381 	}
382 
383 	res = TEE_GetNextPersistentObject(oe, obj, b2, &params[2].memref.size);
384 	if (res)
385 		goto out;
386 
387 	TEE_MemMove(params[2].memref.buffer, b2, params[2].memref.size);
388 	if (obj)
389 		TEE_MemMove(params[1].memref.buffer, obj, sizeof(*obj));
390 out:
391 	TEE_Free(b2);
392 	TEE_Free(obj);
393 
394 	return res;
395 }
396 
check_obj(TEE_ObjectInfo * o1,TEE_ObjectInfo * o2)397 static TEE_Result check_obj(TEE_ObjectInfo *o1, TEE_ObjectInfo *o2)
398 {
399 	if ((o1->objectType != o2->objectType) ||
400 	    (o1->keySize != o2->keySize) ||
401 	    (o1->maxKeySize != o2->maxKeySize) ||
402 	    (o1->objectUsage != o2->objectUsage))
403 		return TEE_ERROR_GENERIC;
404 	return TEE_SUCCESS;
405 }
406 
ta_storage_cmd_key_in_persistent(uint32_t param_types,TEE_Param params[4])407 TEE_Result ta_storage_cmd_key_in_persistent(uint32_t param_types,
408 					    TEE_Param params[4])
409 {
410 	TEE_Result result = TEE_SUCCESS;
411 	TEE_ObjectHandle transient_key = TEE_HANDLE_NULL;
412 	TEE_ObjectHandle persistent_key = TEE_HANDLE_NULL;
413 	TEE_ObjectHandle key = TEE_HANDLE_NULL;
414 	TEE_OperationHandle encrypt_op = TEE_HANDLE_NULL;
415 	TEE_ObjectInfo keyInfo;
416 	TEE_ObjectInfo keyInfo2;
417 	TEE_ObjectInfo keyInfo3;
418 	uint32_t alg = TEE_ALG_AES_CBC_NOPAD;
419 	void *IV = NULL;
420 	size_t IVlen = 16;
421 	size_t key_size = 256;
422 	uint32_t objectID = 1;
423 	uint32_t flags = TEE_DATA_FLAG_ACCESS_READ |
424 			 TEE_DATA_FLAG_ACCESS_WRITE |
425 			 TEE_DATA_FLAG_ACCESS_WRITE_META |
426 			 TEE_DATA_FLAG_SHARE_READ |
427 			 TEE_DATA_FLAG_SHARE_WRITE;
428 
429 	TEE_MemFill(&keyInfo, 0, sizeof(keyInfo));
430 	TEE_MemFill(&keyInfo2, 0, sizeof(keyInfo2));
431 	TEE_MemFill(&keyInfo3, 0, sizeof(keyInfo3));
432 
433 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
434 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
435 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
436 
437 	result = TEE_AllocateTransientObject(TEE_TYPE_AES, key_size,
438 					     &transient_key);
439 	if (result != TEE_SUCCESS) {
440 		EMSG("Failed to Allocate transient object handle : 0x%x",
441 		     result);
442 		goto cleanup1;
443 	}
444 
445 	result = TEE_GenerateKey(transient_key, key_size, NULL, 0);
446 	if (result != TEE_SUCCESS) {
447 		EMSG("Failed to generate a transient key: 0x%x", result);
448 		goto cleanup2;
449 	}
450 
451 	TEE_GetObjectInfo1(transient_key, &keyInfo);
452 	result = TEE_CreatePersistentObject(params[0].value.a,
453 					    &objectID, sizeof(objectID),
454 					    flags, transient_key, NULL, 0,
455 					    &persistent_key);
456 	if (result != TEE_SUCCESS) {
457 		EMSG("Failed to create a persistent key: 0x%x", result);
458 		goto cleanup2;
459 	}
460 
461 	TEE_GetObjectInfo1(persistent_key, &keyInfo2);
462 	result = check_obj(&keyInfo, &keyInfo2);
463 	if (result != TEE_SUCCESS) {
464 		EMSG("keyInfo and keyInfo2 are different");
465 		goto cleanup2;
466 	}
467 
468 	TEE_CloseObject(persistent_key);
469 
470 	result = TEE_OpenPersistentObject(params[0].value.a,
471 					  &objectID, sizeof(objectID),
472 					  flags, &key);
473 	if (result != TEE_SUCCESS) {
474 		EMSG("Failed to open persistent key: 0x%x", result);
475 		goto cleanup2;
476 	}
477 
478 	TEE_GetObjectInfo(key, &keyInfo3);
479 	result = check_obj(&keyInfo3, &keyInfo2);
480 	if (result != TEE_SUCCESS) {
481 		EMSG("keyInfo2 and keyInfo3 are different");
482 		goto cleanup2;
483 	}
484 
485 	result = TEE_AllocateOperation(&encrypt_op, alg, TEE_MODE_ENCRYPT,
486 				       keyInfo3.maxObjectSize);
487 	if (result != TEE_SUCCESS) {
488 		EMSG("Failed to allocate an operation: 0x%x", result);
489 		goto cleanup3;
490 	}
491 
492 	result = TEE_SetOperationKey(encrypt_op, key);
493 	if (result != TEE_SUCCESS) {
494 		EMSG("Failed to set operation key: 0x%x", result);
495 		goto cleanup4;
496 	}
497 
498 	IV = TEE_Malloc(IVlen, 0);
499 	if (!IV) {
500 		EMSG("Out of memory for IV.");
501 		result = TEE_ERROR_OUT_OF_MEMORY;
502 		goto cleanup4;
503 	}
504 
505 	TEE_CipherInit(encrypt_op, IV, IVlen);
506 	TEE_Free(IV);
507 
508 cleanup4:
509 	TEE_FreeOperation(encrypt_op);
510 cleanup3:
511 	TEE_CloseAndDeletePersistentObject1(key);
512 cleanup2:
513 	TEE_FreeTransientObject(transient_key);
514 cleanup1:
515 	return result;
516 }
517 
ta_storage_cmd_loop(uint32_t param_types,TEE_Param params[4])518 TEE_Result ta_storage_cmd_loop(uint32_t param_types, TEE_Param params[4])
519 {
520 	TEE_ObjectHandle object = TEE_HANDLE_NULL;
521 	TEE_Result res = TEE_ERROR_GENERIC;
522 	int object_id = 0;
523 	uint32_t flags =  TEE_DATA_FLAG_OVERWRITE |
524 			  TEE_DATA_FLAG_ACCESS_WRITE_META;
525 	int i = 0;
526 
527 	(void)params;
528 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
529 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
530 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
531 
532 	for (i = 0; i < 20; i++) {
533 		DMSG("\n\nLOOP : %d", i);
534 		object = TEE_HANDLE_NULL;
535 		object_id = i;
536 		res = TEE_CreatePersistentObject(params[0].value.a,
537 						 &object_id, sizeof(int), flags,
538 						 TEE_HANDLE_NULL, NULL, 0,
539 						 &object);
540 
541 		if (res != TEE_SUCCESS) {
542 			EMSG("FAIL");
543 			return res;
544 		}
545 
546 		res = TEE_CloseAndDeletePersistentObject1(object);
547 		if (res != TEE_SUCCESS) {
548 			EMSG("FAIL");
549 			return res;
550 		}
551 	}
552 
553 	return TEE_SUCCESS;
554 }
555 
ta_storage_cmd_restrict_usage(uint32_t param_types,TEE_Param params[4])556 TEE_Result ta_storage_cmd_restrict_usage(uint32_t param_types,
557 					 TEE_Param params[4])
558 {
559 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
560 
561 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
562 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
563 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
564 
565 	o = (TEE_ObjectHandle)(uintptr_t)params[0].value.a;
566 	TEE_RestrictObjectUsage1(o, params[0].value.b);
567 	return TEE_SUCCESS;
568 }
569 
ta_storage_cmd_alloc_obj(uint32_t param_types,TEE_Param params[4])570 TEE_Result ta_storage_cmd_alloc_obj(uint32_t param_types, TEE_Param params[4])
571 {
572 	TEE_Result res = TEE_ERROR_GENERIC;
573 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
574 
575 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
576 			  (TEE_PARAM_TYPE_VALUE_INPUT,
577 			   TEE_PARAM_TYPE_VALUE_OUTPUT,
578 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
579 
580 	res = TEE_AllocateTransientObject(params[0].value.a, params[0].value.b,
581 					  &o);
582 	params[1].value.a = (uint32_t)(uintptr_t)o;
583 	return res;
584 }
585 
ta_storage_cmd_free_obj(uint32_t param_types,TEE_Param params[4])586 TEE_Result ta_storage_cmd_free_obj(uint32_t param_types, TEE_Param params[4])
587 {
588 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
589 
590 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
591 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
592 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
593 
594 	o = (TEE_ObjectHandle)(uintptr_t)params[0].value.a;
595 	TEE_FreeTransientObject(o);
596 	return TEE_SUCCESS;
597 }
598 
ta_storage_cmd_reset_obj(uint32_t param_types,TEE_Param params[4])599 TEE_Result ta_storage_cmd_reset_obj(uint32_t param_types, TEE_Param params[4])
600 {
601 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
602 
603 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
604 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
605 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
606 
607 	o = (TEE_ObjectHandle)(uintptr_t)params[0].value.a;
608 	TEE_ResetTransientObject(o);
609 	return TEE_SUCCESS;
610 }
611 
ta_storage_cmd_get_obj_info(uint32_t param_types,TEE_Param params[4])612 TEE_Result ta_storage_cmd_get_obj_info(uint32_t param_types,
613 					    TEE_Param params[4])
614 {
615 	TEE_Result res = TEE_ERROR_GENERIC;
616 	TEE_ObjectInfo info = { };
617 	TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
618 
619 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
620 			  (TEE_PARAM_TYPE_VALUE_INPUT,
621 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE,
622 			   TEE_PARAM_TYPE_NONE));
623 
624 	if (params[1].memref.size < sizeof(info))
625 		return TEE_ERROR_SHORT_BUFFER;
626 	res = TEE_GetObjectInfo1(o, &info);
627 	if (!res) {
628 		params[1].memref.size = sizeof(info);
629 		TEE_MemMove(params[1].memref.buffer, &info, sizeof(info));
630 	}
631 
632 	return res;
633 }
634