1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2014, STMicroelectronics International N.V.
4 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <string_ext.h>
8 #include <tee_api.h>
9 #include <tee_internal_api_extensions.h>
10 #include <types_ext.h>
11 #include <user_ta_header.h>
12 #include <utee_syscalls.h>
13 #include "tee_api_private.h"
14
15 /*
16 * return a known non-NULL invalid pointer when the
17 * requested size is zero
18 */
19 #define TEE_NULL_SIZED_VA ((void *)1)
20 #define TEE_NULL_SIZED_NO_SHARE_VA ((void *)2)
21
22 /*
23 * Workaround build error in Teaclave TrustZone SDK
24 *
25 * These are supposed to be provided by ta/arch/arm/user_ta_header.c, but
26 * Teaclave TrustZone SDK seems to roll their own in Rust.
27 */
28 uint8_t __ta_no_share_heap[0] __weak;
29 const size_t __ta_no_share_heap_size __weak;
30 struct malloc_ctx *__ta_no_share_malloc_ctx __weak;
31
32 static const void *tee_api_instance_data;
33
34 /* System API - Internal Client API */
35
copy_param(struct utee_params * up,uint32_t param_types,const TEE_Param params[TEE_NUM_PARAMS])36 static void copy_param(struct utee_params *up, uint32_t param_types,
37 const TEE_Param params[TEE_NUM_PARAMS])
38 {
39 size_t n = 0;
40 uint64_t a = 0;
41 uint64_t b = 0;
42
43 up->types = param_types;
44 for (n = 0; n < TEE_NUM_PARAMS; n++) {
45 switch (TEE_PARAM_TYPE_GET(up->types, n)) {
46 case TEE_PARAM_TYPE_VALUE_INPUT:
47 case TEE_PARAM_TYPE_VALUE_INOUT:
48 a = params[n].value.a;
49 b = params[n].value.b;
50 break;
51 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
52 case TEE_PARAM_TYPE_MEMREF_INOUT:
53 case TEE_PARAM_TYPE_MEMREF_INPUT:
54 a = (vaddr_t)params[n].memref.buffer;
55 b = params[n].memref.size;
56 break;
57 default:
58 a = 0;
59 b = 0;
60 }
61 up->vals[n * 2] = a;
62 up->vals[n * 2 + 1] = b;
63 }
64 }
65
copy_gp11_param(struct utee_params * up,uint32_t param_types,const __GP11_TEE_Param params[TEE_NUM_PARAMS])66 static void copy_gp11_param(struct utee_params *up, uint32_t param_types,
67 const __GP11_TEE_Param params[TEE_NUM_PARAMS])
68 {
69 size_t n = 0;
70 uint64_t a = 0;
71 uint64_t b = 0;
72
73 up->types = param_types;
74 for (n = 0; n < TEE_NUM_PARAMS; n++) {
75 switch (TEE_PARAM_TYPE_GET(up->types, n)) {
76 case TEE_PARAM_TYPE_VALUE_INPUT:
77 case TEE_PARAM_TYPE_VALUE_INOUT:
78 a = params[n].value.a;
79 b = params[n].value.b;
80 break;
81 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
82 case TEE_PARAM_TYPE_MEMREF_INOUT:
83 case TEE_PARAM_TYPE_MEMREF_INPUT:
84 a = (vaddr_t)params[n].memref.buffer;
85 b = params[n].memref.size;
86 break;
87 default:
88 a = 0;
89 b = 0;
90 }
91 up->vals[n * 2] = a;
92 up->vals[n * 2 + 1] = b;
93 }
94 }
95
map_tmp_param(struct utee_params * up,void ** tmp_buf,size_t * tmp_len,void * tmp_va[TEE_NUM_PARAMS])96 static TEE_Result map_tmp_param(struct utee_params *up, void **tmp_buf,
97 size_t *tmp_len, void *tmp_va[TEE_NUM_PARAMS])
98 {
99 size_t n = 0;
100 uint8_t *tb = NULL;
101 size_t tbl = 0;
102 size_t tmp_align = sizeof(vaddr_t) * 2;
103 bool is_tmp_mem[TEE_NUM_PARAMS] = { false };
104 void *b = NULL;
105 size_t s = 0;
106 const uint32_t flags = TEE_MEMORY_ACCESS_READ;
107
108 /*
109 * If a memory parameter points to TA private memory we need to
110 * allocate a temporary buffer to avoid exposing the memory
111 * directly to the called TA.
112 */
113
114 *tmp_buf = NULL;
115 *tmp_len = 0;
116 for (n = 0; n < TEE_NUM_PARAMS; n++) {
117 tmp_va[n] = NULL;
118 switch (TEE_PARAM_TYPE_GET(up->types, n)) {
119 case TEE_PARAM_TYPE_MEMREF_INPUT:
120 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
121 case TEE_PARAM_TYPE_MEMREF_INOUT:
122 b = (void *)(vaddr_t)up->vals[n * 2];
123 s = up->vals[n * 2 + 1];
124 /*
125 * We're only allocating temporary memory if the
126 * buffer is completely within TA memory. If it's
127 * NULL, empty, partially outside or completely
128 * outside TA memory there's nothing more we need
129 * to do here. If there's security/permissions
130 * problem we'll get an error in the
131 * invoke_command/open_session below.
132 */
133 if (b && s &&
134 !TEE_CheckMemoryAccessRights(flags, b, s)) {
135 is_tmp_mem[n] = true;
136 tbl += ROUNDUP2(s, tmp_align);
137 }
138 break;
139 default:
140 break;
141 }
142 }
143
144 if (tbl) {
145 tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER);
146 if (!tb)
147 return TEE_ERROR_OUT_OF_MEMORY;
148 *tmp_buf = tb;
149 *tmp_len = tbl;
150 }
151
152 for (n = 0; n < TEE_NUM_PARAMS; n++) {
153 switch (TEE_PARAM_TYPE_GET(up->types, n)) {
154 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
155 case TEE_PARAM_TYPE_MEMREF_INOUT:
156 case TEE_PARAM_TYPE_MEMREF_INPUT:
157 if (!is_tmp_mem[n])
158 break;
159 s = up->vals[n * 2 + 1];
160 b = (void *)(vaddr_t)up->vals[n * 2];
161 tmp_va[n] = tb;
162 tb += ROUNDUP2(s, tmp_align);
163 up->vals[n * 2] = (vaddr_t)tmp_va[n];
164 if (TEE_PARAM_TYPE_GET(up->types, n) !=
165 TEE_PARAM_TYPE_MEMREF_OUTPUT)
166 memcpy(tmp_va[n], b, s);
167 break;
168 default:
169 break;
170 }
171 }
172
173 return TEE_SUCCESS;
174
175 }
176
update_out_param(TEE_Param params[TEE_NUM_PARAMS],void * tmp_va[TEE_NUM_PARAMS],const struct utee_params * up)177 static void update_out_param(TEE_Param params[TEE_NUM_PARAMS],
178 void *tmp_va[TEE_NUM_PARAMS],
179 const struct utee_params *up)
180 {
181 size_t n;
182 uint32_t types = up->types;
183
184 for (n = 0; n < TEE_NUM_PARAMS; n++) {
185 uintptr_t a = up->vals[n * 2];
186 uintptr_t b = up->vals[n * 2 + 1];
187
188 switch (TEE_PARAM_TYPE_GET(types, n)) {
189 case TEE_PARAM_TYPE_VALUE_OUTPUT:
190 case TEE_PARAM_TYPE_VALUE_INOUT:
191 params[n].value.a = a;
192 params[n].value.b = b;
193 break;
194 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
195 case TEE_PARAM_TYPE_MEMREF_INOUT:
196 if (tmp_va[n])
197 memcpy(params[n].memref.buffer, tmp_va[n],
198 MIN(b, params[n].memref.size));
199 params[n].memref.size = b;
200 break;
201 default:
202 break;
203 }
204 }
205 }
206
update_out_gp11_param(__GP11_TEE_Param params[TEE_NUM_PARAMS],void * tmp_va[TEE_NUM_PARAMS],const struct utee_params * up)207 static void update_out_gp11_param(__GP11_TEE_Param params[TEE_NUM_PARAMS],
208 void *tmp_va[TEE_NUM_PARAMS],
209 const struct utee_params *up)
210 {
211 size_t n = 0;
212 uint32_t types = up->types;
213
214 for (n = 0; n < TEE_NUM_PARAMS; n++) {
215 uintptr_t a = up->vals[n * 2];
216 uintptr_t b = up->vals[n * 2 + 1];
217
218 switch (TEE_PARAM_TYPE_GET(types, n)) {
219 case TEE_PARAM_TYPE_VALUE_OUTPUT:
220 case TEE_PARAM_TYPE_VALUE_INOUT:
221 params[n].value.a = a;
222 params[n].value.b = b;
223 break;
224 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
225 case TEE_PARAM_TYPE_MEMREF_INOUT:
226 if (tmp_va[n])
227 memcpy(params[n].memref.buffer, tmp_va[n],
228 MIN(b, params[n].memref.size));
229 params[n].memref.size = b;
230 break;
231 default:
232 break;
233 }
234 }
235 }
236
bufs_intersect(void * buf1,size_t sz1,void * buf2,size_t sz2)237 static bool bufs_intersect(void *buf1, size_t sz1, void *buf2, size_t sz2)
238 {
239 vaddr_t b1 = (vaddr_t)buf1;
240 vaddr_t b2 = (vaddr_t)buf2;
241 vaddr_t e1 = b1 + sz1 - 1;
242 vaddr_t e2 = b2 + sz2 - 1;
243
244 if (!sz1 || !sz2)
245 return false;
246
247 if (e1 < b2 || e2 < b1)
248 return false;
249
250 return true;
251 }
252
check_mem_access_rights_params(uint32_t flags,void * buf,size_t len)253 static TEE_Result check_mem_access_rights_params(uint32_t flags, void *buf,
254 size_t len)
255 {
256 size_t n = 0;
257
258 for (n = 0; n < TEE_NUM_PARAMS; n++) {
259 uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER;
260
261 switch (TEE_PARAM_TYPE_GET(ta_param_types, n)) {
262 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
263 case TEE_PARAM_TYPE_MEMREF_INOUT:
264 f |= TEE_MEMORY_ACCESS_WRITE;
265 fallthrough;
266 case TEE_PARAM_TYPE_MEMREF_INPUT:
267 f |= TEE_MEMORY_ACCESS_READ;
268 if (bufs_intersect(buf, len,
269 ta_params[n].memref.buffer,
270 ta_params[n].memref.size)) {
271 if ((flags & f) != flags)
272 return TEE_ERROR_ACCESS_DENIED;
273 }
274 break;
275 default:
276 break;
277 }
278 }
279
280 return TEE_SUCCESS;
281 }
282
buf_overlaps_no_share_heap(void * buf,size_t size)283 static bool buf_overlaps_no_share_heap(void *buf, size_t size)
284 {
285 struct malloc_ctx *ctx = __ta_no_share_malloc_ctx;
286
287 return ctx && raw_malloc_buffer_overlaps_heap(ctx, buf, size);
288 }
289
check_invoke_param(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])290 static void check_invoke_param(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS])
291 {
292 size_t n = 0;
293
294 for (n = 0; n < TEE_NUM_PARAMS; n++) {
295 uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER;
296 void *buf = params[n].memref.buffer;
297 size_t size = params[n].memref.size;
298
299 switch (TEE_PARAM_TYPE_GET(pt, n)) {
300 case TEE_PARAM_TYPE_MEMREF_OUTPUT:
301 case TEE_PARAM_TYPE_MEMREF_INOUT:
302 f |= TEE_MEMORY_ACCESS_WRITE;
303 fallthrough;
304 case TEE_PARAM_TYPE_MEMREF_INPUT:
305 f |= TEE_MEMORY_ACCESS_READ;
306 if (check_mem_access_rights_params(f, buf, size))
307 TEE_Panic(0);
308 if (buf_overlaps_no_share_heap(buf, size))
309 TEE_Panic(0);
310 break;
311 default:
312 break;
313 }
314 }
315 }
316
TEE_OpenTASession(const TEE_UUID * destination,uint32_t cancellationRequestTimeout,uint32_t paramTypes,TEE_Param params[TEE_NUM_PARAMS],TEE_TASessionHandle * session,uint32_t * returnOrigin)317 TEE_Result TEE_OpenTASession(const TEE_UUID *destination,
318 uint32_t cancellationRequestTimeout,
319 uint32_t paramTypes,
320 TEE_Param params[TEE_NUM_PARAMS],
321 TEE_TASessionHandle *session,
322 uint32_t *returnOrigin)
323 {
324 TEE_Result res = TEE_SUCCESS;
325 struct utee_params up = { };
326 uint32_t s = 0;
327 void *tmp_buf = NULL;
328 size_t tmp_len = 0;
329 void *tmp_va[TEE_NUM_PARAMS] = { NULL };
330
331 if (paramTypes) {
332 __utee_check_inout_annotation(params,
333 sizeof(TEE_Param) *
334 TEE_NUM_PARAMS);
335 check_invoke_param(paramTypes, params);
336 }
337 __utee_check_out_annotation(session, sizeof(*session));
338
339 copy_param(&up, paramTypes, params);
340 res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
341 if (res)
342 goto out;
343 res = _utee_open_ta_session(destination, cancellationRequestTimeout,
344 &up, &s, returnOrigin);
345 update_out_param(params, tmp_va, &up);
346 if (tmp_buf) {
347 TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
348
349 if (res2)
350 TEE_Panic(res2);
351 }
352
353 out:
354 /*
355 * Specification says that *session must hold TEE_HANDLE_NULL is
356 * TEE_SUCCESS isn't returned. Set it here explicitly in case
357 * the syscall fails before out parameters has been updated.
358 */
359 if (res != TEE_SUCCESS)
360 s = TEE_HANDLE_NULL;
361
362 *session = (TEE_TASessionHandle)(uintptr_t)s;
363 return res;
364 }
365
__GP11_TEE_OpenTASession(const TEE_UUID * destination,uint32_t cancellationRequestTimeout,uint32_t paramTypes,__GP11_TEE_Param params[TEE_NUM_PARAMS],TEE_TASessionHandle * session,uint32_t * returnOrigin)366 TEE_Result __GP11_TEE_OpenTASession(const TEE_UUID *destination,
367 uint32_t cancellationRequestTimeout,
368 uint32_t paramTypes,
369 __GP11_TEE_Param params[TEE_NUM_PARAMS],
370 TEE_TASessionHandle *session,
371 uint32_t *returnOrigin)
372 {
373 TEE_Result res = TEE_SUCCESS;
374 struct utee_params up = { };
375 uint32_t s = 0;
376 void *tmp_buf = NULL;
377 size_t tmp_len = 0;
378 void *tmp_va[TEE_NUM_PARAMS] = { NULL };
379
380 if (paramTypes)
381 __utee_check_inout_annotation(params,
382 sizeof(__GP11_TEE_Param) *
383 TEE_NUM_PARAMS);
384 __utee_check_out_annotation(session, sizeof(*session));
385
386 copy_gp11_param(&up, paramTypes, params);
387 res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
388 if (res)
389 goto out;
390 res = _utee_open_ta_session(destination, cancellationRequestTimeout,
391 &up, &s, returnOrigin);
392 update_out_gp11_param(params, tmp_va, &up);
393 if (tmp_buf) {
394 TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
395
396 if (res2)
397 TEE_Panic(res2);
398 }
399
400 out:
401 /*
402 * Specification says that *session must hold TEE_HANDLE_NULL if
403 * TEE_SUCCESS isn't returned. Set it here explicitly in case
404 * the syscall fails before out parameters has been updated.
405 */
406 if (res != TEE_SUCCESS)
407 s = TEE_HANDLE_NULL;
408
409 *session = (TEE_TASessionHandle)(uintptr_t)s;
410 return res;
411 }
412
TEE_CloseTASession(TEE_TASessionHandle session)413 void TEE_CloseTASession(TEE_TASessionHandle session)
414 {
415 if (session != TEE_HANDLE_NULL) {
416 TEE_Result res = _utee_close_ta_session((uintptr_t)session);
417
418 if (res != TEE_SUCCESS)
419 TEE_Panic(res);
420 }
421 }
422
TEE_InvokeTACommand(TEE_TASessionHandle session,uint32_t cancellationRequestTimeout,uint32_t commandID,uint32_t paramTypes,TEE_Param params[TEE_NUM_PARAMS],uint32_t * returnOrigin)423 TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
424 uint32_t cancellationRequestTimeout,
425 uint32_t commandID, uint32_t paramTypes,
426 TEE_Param params[TEE_NUM_PARAMS],
427 uint32_t *returnOrigin)
428 {
429 TEE_Result res = TEE_SUCCESS;
430 uint32_t ret_origin = TEE_ORIGIN_TEE;
431 struct utee_params up = { };
432 void *tmp_buf = NULL;
433 size_t tmp_len = 0;
434 void *tmp_va[TEE_NUM_PARAMS] = { NULL };
435
436 if (paramTypes) {
437 __utee_check_inout_annotation(params,
438 sizeof(TEE_Param) *
439 TEE_NUM_PARAMS);
440 check_invoke_param(paramTypes, params);
441 }
442 if (returnOrigin)
443 __utee_check_out_annotation(returnOrigin,
444 sizeof(*returnOrigin));
445
446 copy_param(&up, paramTypes, params);
447 res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
448 if (res)
449 goto out;
450 res = _utee_invoke_ta_command((uintptr_t)session,
451 cancellationRequestTimeout,
452 commandID, &up, &ret_origin);
453 update_out_param(params, tmp_va, &up);
454 if (tmp_buf) {
455 TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
456
457 if (res2)
458 TEE_Panic(res2);
459 }
460
461 out:
462 if (returnOrigin != NULL)
463 *returnOrigin = ret_origin;
464
465 if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
466 return res;
467
468 if (res != TEE_SUCCESS &&
469 res != TEE_ERROR_OUT_OF_MEMORY &&
470 res != TEE_ERROR_TARGET_DEAD)
471 TEE_Panic(res);
472
473 return res;
474 }
475
__GP11_TEE_InvokeTACommand(TEE_TASessionHandle session,uint32_t cancellationRequestTimeout,uint32_t commandID,uint32_t paramTypes,__GP11_TEE_Param params[TEE_NUM_PARAMS],uint32_t * returnOrigin)476 TEE_Result __GP11_TEE_InvokeTACommand(TEE_TASessionHandle session,
477 uint32_t cancellationRequestTimeout,
478 uint32_t commandID, uint32_t paramTypes,
479 __GP11_TEE_Param params[TEE_NUM_PARAMS],
480 uint32_t *returnOrigin)
481 {
482 TEE_Result res = TEE_SUCCESS;
483 uint32_t ret_origin = TEE_ORIGIN_TEE;
484 struct utee_params up = { };
485 void *tmp_buf = NULL;
486 size_t tmp_len = 0;
487 void *tmp_va[TEE_NUM_PARAMS] = { NULL };
488
489 if (paramTypes)
490 __utee_check_inout_annotation(params,
491 sizeof(__GP11_TEE_Param) *
492 TEE_NUM_PARAMS);
493 if (returnOrigin)
494 __utee_check_out_annotation(returnOrigin,
495 sizeof(*returnOrigin));
496
497 copy_gp11_param(&up, paramTypes, params);
498 res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va);
499 if (res)
500 goto out;
501 res = _utee_invoke_ta_command((uintptr_t)session,
502 cancellationRequestTimeout,
503 commandID, &up, &ret_origin);
504 update_out_gp11_param(params, tmp_va, &up);
505 if (tmp_buf) {
506 TEE_Result res2 = tee_unmap(tmp_buf, tmp_len);
507
508 if (res2)
509 TEE_Panic(res2);
510 }
511
512 out:
513 if (returnOrigin)
514 *returnOrigin = ret_origin;
515
516 if (ret_origin == TEE_ORIGIN_TRUSTED_APP)
517 return res;
518
519 if (res != TEE_SUCCESS &&
520 res != TEE_ERROR_OUT_OF_MEMORY &&
521 res != TEE_ERROR_TARGET_DEAD)
522 TEE_Panic(res);
523
524 return res;
525 }
526
527 /* System API - Cancellations */
528
TEE_GetCancellationFlag(void)529 bool TEE_GetCancellationFlag(void)
530 {
531 uint32_t c;
532 TEE_Result res = _utee_get_cancellation_flag(&c);
533
534 if (res != TEE_SUCCESS)
535 c = 0;
536 return !!c;
537 }
538
TEE_UnmaskCancellation(void)539 bool TEE_UnmaskCancellation(void)
540 {
541 uint32_t old_mask;
542 TEE_Result res = _utee_unmask_cancellation(&old_mask);
543
544 if (res != TEE_SUCCESS)
545 TEE_Panic(res);
546 return !!old_mask;
547 }
548
TEE_MaskCancellation(void)549 bool TEE_MaskCancellation(void)
550 {
551 uint32_t old_mask;
552 TEE_Result res = _utee_mask_cancellation(&old_mask);
553
554 if (res != TEE_SUCCESS)
555 TEE_Panic(res);
556 return !!old_mask;
557 }
558
559 /* System API - Memory Management */
560
TEE_CheckMemoryAccessRights(uint32_t accessFlags,void * buffer,size_t size)561 TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer,
562 size_t size)
563 {
564 uint32_t flags = accessFlags;
565
566 if (!size)
567 return TEE_SUCCESS;
568
569 /*
570 * Check access rights against memory mapping. If this check is
571 * OK the size can't cause an overflow when added with buffer.
572 */
573 if (_utee_check_access_rights(accessFlags, buffer, size))
574 return TEE_ERROR_ACCESS_DENIED;
575
576 /*
577 * Check access rights against input parameters.
578 *
579 * Clear eventual extension flags like TEE_MEMORY_ACCESS_NONSECURE
580 * and TEE_MEMORY_ACCESS_SECURE.
581 */
582 flags &= TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE |
583 TEE_MEMORY_ACCESS_ANY_OWNER;
584 if (check_mem_access_rights_params(flags, buffer, size))
585 return TEE_ERROR_ACCESS_DENIED;
586
587 if (malloc_buffer_overlaps_heap(buffer, size) &&
588 !malloc_buffer_is_within_alloced(buffer, size))
589 return TEE_ERROR_ACCESS_DENIED;
590
591 return TEE_SUCCESS;
592 }
593
__GP11_TEE_CheckMemoryAccessRights(uint32_t accessFlags,void * buffer,uint32_t size)594 TEE_Result __GP11_TEE_CheckMemoryAccessRights(uint32_t accessFlags,
595 void *buffer, uint32_t size)
596 {
597 return TEE_CheckMemoryAccessRights(accessFlags, buffer, size);
598 }
599
TEE_SetInstanceData(const void * instanceData)600 void TEE_SetInstanceData(const void *instanceData)
601 {
602 tee_api_instance_data = instanceData;
603 }
604
TEE_GetInstanceData(void)605 const void *TEE_GetInstanceData(void)
606 {
607 return tee_api_instance_data;
608 }
609
TEE_MemMove(void * dest,const void * src,size_t size)610 void TEE_MemMove(void *dest, const void *src, size_t size)
611 {
612 memmove(dest, src, size);
613 }
614
__GP11_TEE_MemMove(void * dest,const void * src,uint32_t size)615 void __GP11_TEE_MemMove(void *dest, const void *src, uint32_t size)
616 {
617 TEE_MemMove(dest, src, size);
618 }
619
TEE_MemCompare(const void * buffer1,const void * buffer2,size_t size)620 int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, size_t size)
621 {
622 return consttime_memcmp(buffer1, buffer2, size);
623 }
624
__GP11_TEE_MemCompare(const void * buffer1,const void * buffer2,uint32_t size)625 int32_t __GP11_TEE_MemCompare(const void *buffer1, const void *buffer2,
626 uint32_t size)
627 {
628 return TEE_MemCompare(buffer1, buffer2, size);
629 }
630
TEE_MemFill(void * buff,uint32_t x,size_t size)631 void TEE_MemFill(void *buff, uint32_t x, size_t size)
632 {
633 memset(buff, x, size);
634 }
635
__GP11_TEE_MemFill(void * buff,uint32_t x,uint32_t size)636 void __GP11_TEE_MemFill(void *buff, uint32_t x, uint32_t size)
637 {
638 TEE_MemFill(buff, x, size);
639 }
640
641 /* Date & Time API */
642
TEE_GetSystemTime(TEE_Time * time)643 void TEE_GetSystemTime(TEE_Time *time)
644 {
645 TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time);
646
647 if (res != TEE_SUCCESS)
648 TEE_Panic(res);
649 }
650
TEE_Wait(uint32_t timeout)651 TEE_Result TEE_Wait(uint32_t timeout)
652 {
653 TEE_Result res = _utee_wait(timeout);
654
655 if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL)
656 TEE_Panic(res);
657
658 return res;
659 }
660
TEE_GetTAPersistentTime(TEE_Time * time)661 TEE_Result TEE_GetTAPersistentTime(TEE_Time *time)
662 {
663 TEE_Result res;
664
665 res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time);
666
667 if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) {
668 time->seconds = 0;
669 time->millis = 0;
670 }
671
672 if (res != TEE_SUCCESS &&
673 res != TEE_ERROR_TIME_NOT_SET &&
674 res != TEE_ERROR_TIME_NEEDS_RESET &&
675 res != TEE_ERROR_OVERFLOW &&
676 res != TEE_ERROR_OUT_OF_MEMORY)
677 TEE_Panic(res);
678
679 return res;
680 }
681
TEE_SetTAPersistentTime(const TEE_Time * time)682 TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time)
683 {
684 TEE_Result res;
685
686 res = _utee_set_ta_time(time);
687
688 if (res != TEE_SUCCESS &&
689 res != TEE_ERROR_OUT_OF_MEMORY &&
690 res != TEE_ERROR_STORAGE_NO_SPACE)
691 TEE_Panic(res);
692
693 return res;
694 }
695
TEE_GetREETime(TEE_Time * time)696 void TEE_GetREETime(TEE_Time *time)
697 {
698 TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time);
699
700 if (res != TEE_SUCCESS)
701 TEE_Panic(res);
702 }
703
TEE_Malloc(size_t len,uint32_t hint)704 void *TEE_Malloc(size_t len, uint32_t hint)
705 {
706 switch (hint) {
707 case TEE_MALLOC_FILL_ZERO:
708 if (!len)
709 return TEE_NULL_SIZED_VA;
710 return calloc(1, len);
711
712 case TEE_MALLOC_NO_FILL:
713 TEE_Panic(0);
714 break;
715
716 case TEE_MALLOC_NO_SHARE:
717 if (!len)
718 return TEE_NULL_SIZED_NO_SHARE_VA;
719 if (!__ta_no_share_malloc_ctx)
720 return NULL;
721 return raw_calloc(0, 0, 1, len, __ta_no_share_malloc_ctx);
722
723 case TEE_MALLOC_NO_FILL | TEE_MALLOC_NO_SHARE:
724 if (!len)
725 return TEE_NULL_SIZED_NO_SHARE_VA;
726 if (!__ta_no_share_malloc_ctx)
727 return NULL;
728 return raw_malloc(0, 0, len, __ta_no_share_malloc_ctx);
729
730 case TEE_USER_MEM_HINT_NO_FILL_ZERO:
731 if (!len)
732 return TEE_NULL_SIZED_VA;
733 return malloc(len);
734
735 default:
736 break;
737 }
738
739 EMSG("Invalid hint %#" PRIx32, hint);
740
741 return NULL;
742 }
743
__GP11_TEE_Malloc(uint32_t size,uint32_t hint)744 void *__GP11_TEE_Malloc(uint32_t size, uint32_t hint)
745 {
746 return TEE_Malloc(size, hint);
747 }
748
addr_is_in_no_share_heap(void * p)749 static bool addr_is_in_no_share_heap(void *p)
750 {
751 return buf_overlaps_no_share_heap(p, 1);
752 }
753
TEE_Realloc(void * buffer,size_t newSize)754 void *TEE_Realloc(void *buffer, size_t newSize)
755 {
756 bool no_share = (buffer == TEE_NULL_SIZED_NO_SHARE_VA ||
757 addr_is_in_no_share_heap(buffer));
758 void *p = NULL;
759
760 if (buffer != TEE_NULL_SIZED_NO_SHARE_VA && buffer != TEE_NULL_SIZED_VA)
761 p = buffer;
762
763 if (!newSize) {
764 TEE_Free(p);
765 if (no_share)
766 return TEE_NULL_SIZED_NO_SHARE_VA;
767 else
768 return TEE_NULL_SIZED_VA;
769 }
770
771 if (no_share) {
772 if (!__ta_no_share_malloc_ctx)
773 return NULL;
774 return raw_malloc_flags(MAF_ZERO_INIT, p, 0, 0,
775 MALLOC_DEFAULT_ALIGNMENT, 1, newSize,
776 __ta_no_share_malloc_ctx);
777 }
778
779 return malloc_flags(MAF_ZERO_INIT, p, 1, newSize);
780 }
781
__GP11_TEE_Realloc(void * buffer,uint32_t newSize)782 void *__GP11_TEE_Realloc(void *buffer, uint32_t newSize)
783 {
784 return TEE_Realloc(buffer, newSize);
785 }
786
TEE_Free(void * buffer)787 void TEE_Free(void *buffer)
788 {
789 if (buffer != TEE_NULL_SIZED_VA &&
790 buffer != TEE_NULL_SIZED_NO_SHARE_VA) {
791 if (addr_is_in_no_share_heap(buffer))
792 raw_free(buffer, __ta_no_share_malloc_ctx, false);
793 else
794 free(buffer);
795 }
796 }
797
798 /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */
TEE_CacheClean(char * buf,size_t len)799 TEE_Result TEE_CacheClean(char *buf, size_t len)
800 {
801 return _utee_cache_operation(buf, len, TEE_CACHECLEAN);
802 }
TEE_CacheFlush(char * buf,size_t len)803 TEE_Result TEE_CacheFlush(char *buf, size_t len)
804 {
805 return _utee_cache_operation(buf, len, TEE_CACHEFLUSH);
806 }
807
TEE_CacheInvalidate(char * buf,size_t len)808 TEE_Result TEE_CacheInvalidate(char *buf, size_t len)
809 {
810 return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE);
811 }
812