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