1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * All rights reserved.
5  * Copyright (c) 2022, Linaro Limited.
6  */
7 
8 #include <assert.h>
9 #include <cryp_taf.h>
10 #include <memtag.h>
11 #include <tee_internal_api.h>
12 #include <trace.h>
13 #include <user_ta_header.h>
14 
15 #include "handle.h"
16 
17 #define ASSERT_PARAM_TYPE(pt)                    \
18 do {                                             \
19 	if ((pt) != param_type)                  \
20 		return TEE_ERROR_BAD_PARAMETERS; \
21 } while (0)
22 
23 static struct handle_db op_db = HANDLE_DB_INITIALIZER;
24 static struct handle_db obj_db = HANDLE_DB_INITIALIZER;
25 
op_handle_get(TEE_OperationHandle h)26 static uint32_t op_handle_get(TEE_OperationHandle h)
27 {
28 	int rc = handle_get(&op_db, h);
29 
30 	if (rc < 0) {
31 		EMSG("Failed to allocate handle");
32 		TEE_Panic(TEE_ERROR_OUT_OF_MEMORY);
33 	}
34 
35 	/* +1 since 0 (TEE_HANDLE_NULL) is invalid */
36 	return rc + 1;
37 }
38 
op_handle_put(uint32_t val)39 static TEE_OperationHandle op_handle_put(uint32_t val)
40 {
41 	void *h = NULL;
42 
43 	if (val) {
44 		h = handle_put(&op_db, val - 1);
45 		if (!h) {
46 			EMSG("Invalid handle 0x%"PRIx32, val);
47 			TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
48 		}
49 	}
50 
51 	return h;
52 }
53 
op_handle_lookup(uint32_t val)54 static TEE_OperationHandle op_handle_lookup(uint32_t val)
55 {
56 	void *h = NULL;
57 
58 	if (val) {
59 		h = handle_lookup(&op_db, val - 1);
60 		if (!h) {
61 			EMSG("Invalid handle 0x%"PRIx32, val);
62 			TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
63 		}
64 	}
65 
66 	return h;
67 }
68 
obj_handle_get(TEE_ObjectHandle h)69 static uint32_t obj_handle_get(TEE_ObjectHandle h)
70 {
71 	int rc = handle_get(&obj_db, h);
72 
73 	if (rc < 0) {
74 		EMSG("Failed to allocate handle");
75 		TEE_Panic(TEE_ERROR_OUT_OF_MEMORY);
76 	}
77 
78 	/* +1 since 0 (TEE_HANDLE_NULL) is invalid */
79 	return rc + 1;
80 }
81 
obj_handle_put(uint32_t val)82 static TEE_ObjectHandle obj_handle_put(uint32_t val)
83 {
84 	void *h = NULL;
85 
86 	if (val) {
87 		h = handle_put(&obj_db, val - 1);
88 		if (!h) {
89 			EMSG("Invalid handle 0x%"PRIx32, val);
90 			TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
91 		}
92 	}
93 
94 	return h;
95 }
96 
obj_handle_lookup(uint32_t val)97 static TEE_ObjectHandle obj_handle_lookup(uint32_t val)
98 {
99 	void *h = NULL;
100 
101 	if (val) {
102 		h = handle_lookup(&obj_db, val - 1);
103 		if (!h) {
104 			EMSG("Invalid handle 0x%"PRIx32, val);
105 			TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
106 		}
107 	}
108 
109 	return h;
110 }
111 
ta_entry_allocate_operation(uint32_t param_type,TEE_Param params[4])112 TEE_Result ta_entry_allocate_operation(uint32_t param_type, TEE_Param params[4])
113 {
114 	TEE_Result res = TEE_ERROR_GENERIC;
115 	TEE_OperationHandle op = TEE_HANDLE_NULL;
116 
117 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
118 			  (TEE_PARAM_TYPE_VALUE_INOUT,
119 			   TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
120 			   TEE_PARAM_TYPE_NONE));
121 
122 	res = TEE_AllocateOperation(&op,
123 				    params[0].value.b, params[1].value.a,
124 				    params[1].value.b);
125 	params[0].value.a = op_handle_get(op);
126 	return res;
127 }
128 
ta_entry_free_operation(uint32_t param_type,TEE_Param params[4])129 TEE_Result ta_entry_free_operation(uint32_t param_type, TEE_Param params[4])
130 {
131 	TEE_OperationHandle op = op_handle_put(params[0].value.a);
132 
133 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
134 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
135 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
136 
137 	TEE_FreeOperation(op);
138 	return TEE_SUCCESS;
139 }
140 
ta_entry_get_operation_info(uint32_t param_type,TEE_Param params[4])141 TEE_Result ta_entry_get_operation_info(uint32_t param_type, TEE_Param params[4])
142 {
143 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
144 
145 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
146 			  (TEE_PARAM_TYPE_VALUE_INPUT,
147 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE,
148 			   TEE_PARAM_TYPE_NONE));
149 
150 	if (params[1].memref.size < sizeof(TEE_OperationInfo))
151 		return TEE_ERROR_SHORT_BUFFER;
152 	params[1].memref.size = sizeof(TEE_OperationInfo);
153 
154 	TEE_GetOperationInfo(op, params[1].memref.buffer);
155 	return TEE_SUCCESS;
156 }
157 
ta_entry_reset_operation(uint32_t param_type,TEE_Param params[4])158 TEE_Result ta_entry_reset_operation(uint32_t param_type, TEE_Param params[4])
159 {
160 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
161 
162 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
163 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
164 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
165 
166 	TEE_ResetOperation(op);
167 	return TEE_SUCCESS;
168 }
169 
ta_entry_set_operation_key(uint32_t param_type,TEE_Param params[4])170 TEE_Result ta_entry_set_operation_key(uint32_t param_type, TEE_Param params[4])
171 {
172 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
173 	TEE_ObjectHandle key = obj_handle_lookup(params[0].value.b);
174 
175 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
176 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
177 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
178 
179 	return TEE_SetOperationKey(op, key);
180 }
181 
ta_entry_set_operation_key2(uint32_t param_type,TEE_Param params[4])182 TEE_Result ta_entry_set_operation_key2(uint32_t param_type, TEE_Param params[4])
183 {
184 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
185 	TEE_ObjectHandle key1 = obj_handle_lookup(params[0].value.b);
186 	TEE_ObjectHandle key2 = obj_handle_lookup(params[1].value.a);
187 
188 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
189 			  (TEE_PARAM_TYPE_VALUE_INPUT,
190 			   TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
191 			   TEE_PARAM_TYPE_NONE));
192 
193 	return TEE_SetOperationKey2(op, key1, key2);
194 }
195 
ta_entry_copy_operation(uint32_t param_type,TEE_Param params[4])196 TEE_Result ta_entry_copy_operation(uint32_t param_type, TEE_Param params[4])
197 {
198 	TEE_OperationHandle dst = op_handle_lookup(params[0].value.a);
199 	TEE_OperationHandle src = op_handle_lookup(params[0].value.b);
200 
201 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
202 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
203 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
204 
205 
206 	TEE_CopyOperation(dst, src);
207 	return TEE_SUCCESS;
208 }
209 
ta_entry_digest_update(uint32_t param_type,TEE_Param params[4])210 TEE_Result ta_entry_digest_update(uint32_t param_type, TEE_Param params[4])
211 {
212 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
213 
214 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
215 			  (TEE_PARAM_TYPE_VALUE_INPUT,
216 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
217 			   TEE_PARAM_TYPE_NONE));
218 
219 	TEE_DigestUpdate(op, params[1].memref.buffer, params[1].memref.size);
220 	return TEE_SUCCESS;
221 }
222 
ta_entry_digest_do_final(uint32_t param_type,TEE_Param params[4])223 TEE_Result ta_entry_digest_do_final(uint32_t param_type, TEE_Param params[4])
224 {
225 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
226 
227 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
228 			  (TEE_PARAM_TYPE_VALUE_INPUT,
229 			   TEE_PARAM_TYPE_MEMREF_INPUT,
230 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE));
231 
232 	return TEE_DigestDoFinal(op,
233 			params[1].memref.buffer, params[1].memref.size,
234 			params[2].memref.buffer, &params[2].memref.size);
235 }
236 
ta_entry_cipher_init(uint32_t param_type,TEE_Param params[4])237 TEE_Result ta_entry_cipher_init(uint32_t param_type, TEE_Param params[4])
238 {
239 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
240 	void *buffer = NULL;
241 	size_t size = 0;
242 
243 	if (param_type == TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
244 					  TEE_PARAM_TYPE_NONE,
245 					  TEE_PARAM_TYPE_NONE,
246 					  TEE_PARAM_TYPE_NONE)) {
247 		buffer = NULL;
248 		size = 0;
249 	} else if (param_type == TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
250 						 TEE_PARAM_TYPE_MEMREF_INPUT,
251 						 TEE_PARAM_TYPE_NONE,
252 						 TEE_PARAM_TYPE_NONE)) {
253 		buffer = params[1].memref.buffer;
254 		size = params[1].memref.size;
255 	} else
256 		return TEE_ERROR_BAD_PARAMETERS;
257 
258 	TEE_CipherInit(op, buffer, size);
259 	return TEE_SUCCESS;
260 }
261 
ta_entry_cipher_update(uint32_t param_type,TEE_Param params[4])262 TEE_Result ta_entry_cipher_update(uint32_t param_type, TEE_Param params[4])
263 {
264 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
265 
266 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
267 			  (TEE_PARAM_TYPE_VALUE_INPUT,
268 			   TEE_PARAM_TYPE_MEMREF_INPUT,
269 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE));
270 
271 	return TEE_CipherUpdate(op,
272 			params[1].memref.buffer, params[1].memref.size,
273 			params[2].memref.buffer, &params[2].memref.size);
274 }
275 
ta_entry_cipher_do_final(uint32_t param_type,TEE_Param params[4])276 TEE_Result ta_entry_cipher_do_final(uint32_t param_type, TEE_Param params[4])
277 {
278 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
279 
280 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
281 			  (TEE_PARAM_TYPE_VALUE_INPUT,
282 			   TEE_PARAM_TYPE_MEMREF_INPUT,
283 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE));
284 
285 	return TEE_CipherDoFinal(op,
286 			 params[1].memref.buffer, params[1].memref.size,
287 			 params[2].memref.buffer, &params[2].memref.size);
288 }
289 
ta_entry_mac_init(uint32_t param_type,TEE_Param params[4])290 TEE_Result ta_entry_mac_init(uint32_t param_type, TEE_Param params[4])
291 {
292 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
293 	void *buffer = NULL;
294 	size_t size = 0;
295 
296 	if (param_type == TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
297 					  TEE_PARAM_TYPE_NONE,
298 					  TEE_PARAM_TYPE_NONE,
299 					  TEE_PARAM_TYPE_NONE)) {
300 		buffer = NULL;
301 		size = 0;
302 	} else if (param_type == TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
303 						 TEE_PARAM_TYPE_MEMREF_INPUT,
304 						 TEE_PARAM_TYPE_NONE,
305 						 TEE_PARAM_TYPE_NONE)) {
306 		buffer = params[1].memref.buffer;
307 		size = params[1].memref.size;
308 	} else
309 		return TEE_ERROR_BAD_PARAMETERS;
310 
311 	TEE_MACInit(op, buffer, size);
312 	return TEE_SUCCESS;
313 }
314 
ta_entry_mac_update(uint32_t param_type,TEE_Param params[4])315 TEE_Result ta_entry_mac_update(uint32_t param_type, TEE_Param params[4])
316 {
317 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
318 
319 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
320 			  (TEE_PARAM_TYPE_VALUE_INPUT,
321 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
322 			   TEE_PARAM_TYPE_NONE));
323 
324 	TEE_MACUpdate(op, params[1].memref.buffer, params[1].memref.size);
325 	return TEE_SUCCESS;
326 }
327 
ta_entry_mac_final_compute(uint32_t param_type,TEE_Param params[4])328 TEE_Result ta_entry_mac_final_compute(uint32_t param_type, TEE_Param params[4])
329 {
330 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
331 
332 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
333 			  (TEE_PARAM_TYPE_VALUE_INPUT,
334 			   TEE_PARAM_TYPE_MEMREF_INPUT,
335 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE));
336 
337 	return TEE_MACComputeFinal(op,
338 			   params[1].memref.buffer, params[1].memref.size,
339 			   params[2].memref.buffer, &params[2].memref.size);
340 }
341 
ta_entry_mac_final_compare(uint32_t param_type,TEE_Param params[4])342 TEE_Result ta_entry_mac_final_compare(uint32_t param_type, TEE_Param params[4])
343 {
344 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
345 
346 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
347 			  (TEE_PARAM_TYPE_VALUE_INPUT,
348 			   TEE_PARAM_TYPE_MEMREF_INPUT,
349 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE));
350 
351 	return TEE_MACCompareFinal(op,
352 			   params[1].memref.buffer, params[1].memref.size,
353 			   params[2].memref.buffer, params[2].memref.size);
354 }
355 
ta_entry_allocate_transient_object(uint32_t param_type,TEE_Param params[4])356 TEE_Result ta_entry_allocate_transient_object(uint32_t param_type,
357 					      TEE_Param params[4])
358 {
359 	TEE_Result res = TEE_ERROR_GENERIC;
360 	TEE_ObjectHandle o = TEE_HANDLE_NULL;
361 
362 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
363 			  (TEE_PARAM_TYPE_VALUE_INPUT,
364 			   TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE,
365 			   TEE_PARAM_TYPE_NONE));
366 
367 	res = TEE_AllocateTransientObject(params[0].value.a, params[0].value.b,
368 					  &o);
369 	if (res == TEE_SUCCESS)
370 		params[1].value.a = obj_handle_get(o);
371 	return res;
372 }
373 
ta_entry_free_transient_object(uint32_t param_type,TEE_Param params[4])374 TEE_Result ta_entry_free_transient_object(uint32_t param_type,
375 					  TEE_Param params[4])
376 {
377 	TEE_ObjectHandle o = obj_handle_put(params[0].value.a);
378 
379 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
380 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
381 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
382 
383 	TEE_FreeTransientObject(o);
384 	return TEE_SUCCESS;
385 }
386 
ta_entry_reset_transient_object(uint32_t param_type,TEE_Param params[4])387 TEE_Result ta_entry_reset_transient_object(uint32_t param_type,
388 					   TEE_Param params[4])
389 {
390 	TEE_ObjectHandle o = obj_handle_lookup(params[0].value.a);
391 
392 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
393 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
394 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
395 
396 	TEE_ResetTransientObject(o);
397 	return TEE_SUCCESS;
398 }
399 
400 struct attr_packed {
401 	uint32_t id;
402 	uint32_t a;
403 	uint32_t b;
404 };
405 
unpack_attrs(const uint8_t * buf,size_t blen,TEE_Attribute ** attrs,uint32_t * attr_count)406 static TEE_Result unpack_attrs(const uint8_t *buf, size_t blen,
407 			       TEE_Attribute **attrs, uint32_t *attr_count)
408 {
409 	TEE_Result res = TEE_SUCCESS;
410 	TEE_Attribute *a = NULL;
411 	const struct attr_packed *ap = NULL;
412 	size_t num_attrs = 0;
413 	const size_t num_attrs_size = sizeof(uint32_t);
414 
415 	if (blen == 0)
416 		goto out;
417 
418 	if (((uintptr_t)buf & 0x3) != 0 || blen < num_attrs_size)
419 		return TEE_ERROR_BAD_PARAMETERS;
420 	num_attrs = *(uint32_t *) (void *)buf;
421 	if ((blen - num_attrs_size) < (num_attrs * sizeof(*ap)))
422 		return TEE_ERROR_BAD_PARAMETERS;
423 	ap = (const struct attr_packed *)(const void *)(buf + num_attrs_size);
424 
425 	if (num_attrs > 0) {
426 		size_t n;
427 
428 		a = TEE_Malloc(num_attrs * sizeof(TEE_Attribute), 0);
429 		if (!a)
430 			return TEE_ERROR_OUT_OF_MEMORY;
431 		for (n = 0; n < num_attrs; n++) {
432 			uintptr_t p;
433 
434 			a[n].attributeID = ap[n].id;
435 			if (ap[n].id & TEE_ATTR_FLAG_VALUE) {
436 				a[n].content.value.a = ap[n].a;
437 				a[n].content.value.b = ap[n].b;
438 				continue;
439 			}
440 
441 			a[n].content.ref.length = ap[n].b;
442 			p = (uintptr_t)ap[n].a;
443 			if (p) {
444 				if ((p + a[n].content.ref.length) > blen) {
445 					res = TEE_ERROR_BAD_PARAMETERS;
446 					goto out;
447 				}
448 				p += (uintptr_t)buf;
449 			}
450 			a[n].content.ref.buffer = (void *)p;
451 		}
452 	}
453 
454 	res = TEE_SUCCESS;
455 out:
456 	if (res == TEE_SUCCESS) {
457 		*attrs = a;
458 		*attr_count = num_attrs;
459 	} else {
460 		TEE_Free(a);
461 	}
462 	return res;
463 }
464 
ta_entry_populate_transient_object(uint32_t param_type,TEE_Param params[4])465 TEE_Result ta_entry_populate_transient_object(uint32_t param_type,
466 					      TEE_Param params[4])
467 {
468 	TEE_Result res = TEE_ERROR_GENERIC;
469 	TEE_Attribute *attrs = NULL;
470 	uint32_t attr_count = 0;
471 	TEE_ObjectHandle o = obj_handle_lookup(params[0].value.a);
472 
473 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
474 			  (TEE_PARAM_TYPE_VALUE_INPUT,
475 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
476 			   TEE_PARAM_TYPE_NONE));
477 
478 	res = unpack_attrs(params[1].memref.buffer, params[1].memref.size,
479 			   &attrs, &attr_count);
480 	if (res != TEE_SUCCESS)
481 		return res;
482 
483 	res = TEE_PopulateTransientObject(o, attrs, attr_count);
484 	TEE_Free(attrs);
485 	return res;
486 }
487 
ta_entry_copy_object_attributes(uint32_t param_type,TEE_Param params[4])488 TEE_Result ta_entry_copy_object_attributes(uint32_t param_type,
489 					   TEE_Param params[4])
490 {
491 	TEE_ObjectHandle dst = obj_handle_lookup(params[0].value.a);
492 	TEE_ObjectHandle src = obj_handle_lookup(params[0].value.b);
493 
494 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
495 			  (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
496 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
497 
498 	return TEE_CopyObjectAttributes1(dst, src);
499 }
500 
ta_entry_generate_key(uint32_t param_type,TEE_Param params[4])501 TEE_Result ta_entry_generate_key(uint32_t param_type, TEE_Param params[4])
502 {
503 	TEE_ObjectHandle o = obj_handle_lookup(params[0].value.a);
504 	TEE_Result res = TEE_ERROR_GENERIC;
505 	TEE_Attribute *attrs = NULL;
506 	uint32_t attr_count = 0;
507 
508 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
509 			  (TEE_PARAM_TYPE_VALUE_INPUT,
510 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
511 			   TEE_PARAM_TYPE_NONE));
512 
513 	res = unpack_attrs(params[1].memref.buffer, params[1].memref.size,
514 			   &attrs, &attr_count);
515 	if (res != TEE_SUCCESS)
516 		return res;
517 
518 	res = TEE_GenerateKey(o, params[0].value.b, attrs, attr_count);
519 	TEE_Free(attrs);
520 	return res;
521 }
522 
ta_entry_asymmetric_encrypt(uint32_t param_type,TEE_Param params[4])523 TEE_Result ta_entry_asymmetric_encrypt(uint32_t param_type, TEE_Param params[4])
524 {
525 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
526 	TEE_Result res = TEE_ERROR_GENERIC;
527 	TEE_Attribute *attrs = NULL;
528 	uint32_t attr_count = 0;
529 
530 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
531 			  (TEE_PARAM_TYPE_VALUE_INPUT,
532 			   TEE_PARAM_TYPE_MEMREF_INPUT,
533 			   TEE_PARAM_TYPE_MEMREF_INPUT,
534 			   TEE_PARAM_TYPE_MEMREF_OUTPUT));
535 
536 	res = unpack_attrs(params[1].memref.buffer, params[1].memref.size,
537 			   &attrs, &attr_count);
538 	if (res != TEE_SUCCESS)
539 		return res;
540 
541 	res = TEE_AsymmetricEncrypt(op, attrs, attr_count,
542 			params[2].memref.buffer, params[2].memref.size,
543 			params[3].memref.buffer, &params[3].memref.size);
544 	TEE_Free(attrs);
545 	return res;
546 }
547 
ta_entry_asymmetric_decrypt(uint32_t param_type,TEE_Param params[4])548 TEE_Result ta_entry_asymmetric_decrypt(uint32_t param_type, TEE_Param params[4])
549 {
550 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
551 	TEE_Result res = TEE_ERROR_GENERIC;
552 	TEE_Attribute *attrs = NULL;
553 	uint32_t attr_count = 0;
554 
555 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
556 			  (TEE_PARAM_TYPE_VALUE_INPUT,
557 			   TEE_PARAM_TYPE_MEMREF_INPUT,
558 			   TEE_PARAM_TYPE_MEMREF_INPUT,
559 			   TEE_PARAM_TYPE_MEMREF_OUTPUT));
560 
561 	res = unpack_attrs(params[1].memref.buffer, params[1].memref.size,
562 			   &attrs, &attr_count);
563 	if (res != TEE_SUCCESS)
564 		return res;
565 
566 	res = TEE_AsymmetricDecrypt(op, attrs, attr_count,
567 			params[2].memref.buffer, params[2].memref.size,
568 			params[3].memref.buffer, &params[3].memref.size);
569 	TEE_Free(attrs);
570 	return res;
571 }
572 
ta_entry_asymmetric_sign_digest(uint32_t param_type,TEE_Param params[4])573 TEE_Result ta_entry_asymmetric_sign_digest(uint32_t param_type,
574 					   TEE_Param params[4])
575 {
576 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
577 	TEE_Result res = TEE_ERROR_GENERIC;
578 	TEE_Attribute *attrs = NULL;
579 	uint32_t attr_count = 0;
580 
581 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
582 			  (TEE_PARAM_TYPE_VALUE_INPUT,
583 			   TEE_PARAM_TYPE_MEMREF_INPUT,
584 			   TEE_PARAM_TYPE_MEMREF_INPUT,
585 			   TEE_PARAM_TYPE_MEMREF_OUTPUT));
586 
587 	res = unpack_attrs(params[1].memref.buffer, params[1].memref.size,
588 			   &attrs, &attr_count);
589 	if (res != TEE_SUCCESS)
590 		return res;
591 
592 	res = TEE_AsymmetricSignDigest(op, attrs, attr_count,
593 			params[2].memref.buffer, params[2].memref.size,
594 			params[3].memref.buffer, &params[3].memref.size);
595 	TEE_Free(attrs);
596 	return res;
597 }
598 
ta_entry_asymmetric_verify_digest(uint32_t param_type,TEE_Param params[4])599 TEE_Result ta_entry_asymmetric_verify_digest(uint32_t param_type,
600 					     TEE_Param params[4])
601 {
602 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
603 	TEE_Result res = TEE_ERROR_GENERIC;
604 	TEE_Attribute *attrs = NULL;
605 	uint32_t attr_count = 0;
606 
607 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
608 			  (TEE_PARAM_TYPE_VALUE_INPUT,
609 			   TEE_PARAM_TYPE_MEMREF_INPUT,
610 			   TEE_PARAM_TYPE_MEMREF_INPUT,
611 			   TEE_PARAM_TYPE_MEMREF_INPUT));
612 
613 	res = unpack_attrs(params[1].memref.buffer, params[1].memref.size,
614 			   &attrs, &attr_count);
615 	if (res != TEE_SUCCESS)
616 		return res;
617 
618 	res = TEE_AsymmetricVerifyDigest(op, attrs, attr_count,
619 			params[2].memref.buffer, params[2].memref.size,
620 			params[3].memref.buffer, params[3].memref.size);
621 	TEE_Free(attrs);
622 	return res;
623 }
624 
ta_entry_derive_key(uint32_t param_type,TEE_Param params[4])625 TEE_Result ta_entry_derive_key(uint32_t param_type, TEE_Param params[4])
626 {
627 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
628 	TEE_ObjectHandle key = obj_handle_lookup(params[0].value.b);
629 	TEE_Result res = TEE_ERROR_GENERIC;
630 	TEE_Attribute *attrs = NULL;
631 	uint32_t attr_count = 0;
632 
633 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
634 			  (TEE_PARAM_TYPE_VALUE_INPUT,
635 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
636 			   TEE_PARAM_TYPE_NONE));
637 
638 	res = unpack_attrs(params[1].memref.buffer, params[1].memref.size,
639 			   &attrs, &attr_count);
640 	if (res != TEE_SUCCESS)
641 		return res;
642 
643 	TEE_DeriveKey(op, attrs, attr_count, key);
644 	TEE_Free(attrs);
645 	return TEE_SUCCESS;
646 }
647 
ta_entry_random_number_generate(uint32_t param_type,TEE_Param params[4])648 TEE_Result ta_entry_random_number_generate(uint32_t param_type,
649 					   TEE_Param params[4])
650 {
651 	void *buf = NULL;
652 
653 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
654 			  (TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE,
655 			   TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
656 
657 	buf = TEE_Malloc(params[0].memref.size, 0);
658 	if (!buf)
659 		return TEE_ERROR_OUT_OF_MEMORY;
660 
661 	TEE_GenerateRandom(buf, params[0].memref.size);
662 	TEE_MemMove(params[0].memref.buffer, buf, params[0].memref.size);
663 	TEE_Free(buf);
664 	return TEE_SUCCESS;
665 }
666 
ta_entry_ae_init(uint32_t param_type,TEE_Param params[4])667 TEE_Result ta_entry_ae_init(uint32_t param_type, TEE_Param params[4])
668 {
669 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
670 
671 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
672 			  (TEE_PARAM_TYPE_VALUE_INPUT,
673 			   TEE_PARAM_TYPE_MEMREF_INPUT,
674 			   TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE));
675 	return TEE_AEInit(op, params[1].memref.buffer, params[1].memref.size,
676 			  params[0].value.b * 8, /* tag_len in bits */
677 			  params[2].value.a, params[2].value.b);
678 }
679 
ta_entry_ae_update_aad(uint32_t param_type,TEE_Param params[4])680 TEE_Result ta_entry_ae_update_aad(uint32_t param_type, TEE_Param params[4])
681 {
682 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
683 
684 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
685 			  (TEE_PARAM_TYPE_VALUE_INPUT,
686 			   TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
687 			   TEE_PARAM_TYPE_NONE));
688 
689 	TEE_AEUpdateAAD(op, params[1].memref.buffer, params[1].memref.size);
690 	return TEE_SUCCESS;
691 }
692 
ta_entry_ae_update(uint32_t param_type,TEE_Param params[4])693 TEE_Result ta_entry_ae_update(uint32_t param_type, TEE_Param params[4])
694 {
695 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
696 
697 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
698 			  (TEE_PARAM_TYPE_VALUE_INPUT,
699 			   TEE_PARAM_TYPE_MEMREF_INPUT,
700 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE));
701 
702 	TEE_AEUpdate(op, params[1].memref.buffer, params[1].memref.size,
703 		     params[2].memref.buffer, &params[2].memref.size);
704 	return TEE_SUCCESS;
705 }
706 
ta_entry_ae_encrypt_final(uint32_t param_type,TEE_Param params[4])707 TEE_Result ta_entry_ae_encrypt_final(uint32_t param_type, TEE_Param params[4])
708 {
709 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
710 	TEE_Result res = TEE_ERROR_OUT_OF_MEMORY;
711 	void *b2 = NULL;
712 	void *b3 = NULL;
713 
714 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
715 			  (TEE_PARAM_TYPE_VALUE_INPUT,
716 			   TEE_PARAM_TYPE_MEMREF_INPUT,
717 			   TEE_PARAM_TYPE_MEMREF_OUTPUT,
718 			   TEE_PARAM_TYPE_MEMREF_OUTPUT));
719 
720 	b2 = TEE_Malloc(params[2].memref.size, 0);
721 	b3 = TEE_Malloc(params[3].memref.size, 0);
722 	if (!b2 || !b3)
723 		goto out;
724 
725 	res = TEE_AEEncryptFinal(op, params[1].memref.buffer,
726 				 params[1].memref.size, b2,
727 				 &params[2].memref.size, b3,
728 				 &params[3].memref.size);
729 	if (!res) {
730 		TEE_MemMove(params[2].memref.buffer, b2, params[2].memref.size);
731 		TEE_MemMove(params[3].memref.buffer, b3, params[3].memref.size);
732 	}
733 out:
734 	TEE_Free(b2);
735 	TEE_Free(b3);
736 	return res;
737 }
738 
ta_entry_ae_decrypt_final(uint32_t param_type,TEE_Param params[4])739 TEE_Result ta_entry_ae_decrypt_final(uint32_t param_type, TEE_Param params[4])
740 {
741 	TEE_OperationHandle op = op_handle_lookup(params[0].value.a);
742 	TEE_Result res = TEE_ERROR_OUT_OF_MEMORY;
743 	void *b2 = NULL;
744 	void *b3 = NULL;
745 
746 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
747 			  (TEE_PARAM_TYPE_VALUE_INPUT,
748 			   TEE_PARAM_TYPE_MEMREF_INPUT,
749 			   TEE_PARAM_TYPE_MEMREF_OUTPUT,
750 			   TEE_PARAM_TYPE_MEMREF_INPUT));
751 
752 	b2 = TEE_Malloc(params[2].memref.size, 0);
753 	b3 = TEE_Malloc(params[3].memref.size, 0);
754 	if (!b2 || !b3)
755 		goto out;
756 
757 	TEE_MemMove(b3, params[3].memref.buffer, params[3].memref.size);
758 	res = TEE_AEDecryptFinal(op, params[1].memref.buffer,
759 				 params[1].memref.size, b2,
760 				 &params[2].memref.size, b3,
761 				 params[3].memref.size);
762 	if (!res)
763 		TEE_MemMove(params[2].memref.buffer, b2, params[2].memref.size);
764 out:
765 	TEE_Free(b2);
766 	TEE_Free(b3);
767 
768 	return res;
769 }
770 
ta_entry_get_object_buffer_attribute(uint32_t param_type,TEE_Param params[4])771 TEE_Result ta_entry_get_object_buffer_attribute(uint32_t param_type,
772 						TEE_Param params[4])
773 {
774 	TEE_ObjectHandle o = obj_handle_lookup(params[0].value.a);
775 
776 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
777 			  (TEE_PARAM_TYPE_VALUE_INPUT,
778 			   TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE,
779 			   TEE_PARAM_TYPE_NONE));
780 
781 	return TEE_GetObjectBufferAttribute(o, params[0].value.b,
782 			params[1].memref.buffer, &params[1].memref.size);
783 }
784 
ta_entry_get_object_value_attribute(uint32_t param_type,TEE_Param params[4])785 TEE_Result ta_entry_get_object_value_attribute(uint32_t param_type,
786 					       TEE_Param params[4])
787 {
788 	TEE_ObjectHandle o = obj_handle_lookup(params[0].value.a);
789 
790 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
791 			  (TEE_PARAM_TYPE_VALUE_INPUT,
792 			   TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE,
793 			   TEE_PARAM_TYPE_NONE));
794 
795 	return TEE_GetObjectValueAttribute(o, params[0].value.b,
796 				   &params[1].value.a, &params[1].value.b);
797 }
798 
ta_entry_is_algo_supported(uint32_t param_type,TEE_Param params[TEE_NUM_PARAMS])799 TEE_Result ta_entry_is_algo_supported(uint32_t param_type,
800 				      TEE_Param params[TEE_NUM_PARAMS])
801 {
802 	ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
803 			  (TEE_PARAM_TYPE_VALUE_INPUT,
804 			   TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE,
805 			   TEE_PARAM_TYPE_NONE));
806 
807 	params[1].value.a = TEE_IsAlgorithmSupported(params[0].value.a,
808 						     params[0].value.b);
809 
810 	return TEE_SUCCESS;
811 }
812