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, ¶ms[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, ¶ms[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, ¶ms[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, ¶ms[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, ¶ms[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, ¶ms[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, ¶ms[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, ¶ms[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 ¶ms[2].memref.size, b3,
728 ¶ms[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 ¶ms[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, ¶ms[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 ¶ms[1].value.a, ¶ms[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