11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 4b0104773SPascal Brand */ 5b0104773SPascal Brand #include <stdlib.h> 6b0104773SPascal Brand #include <string.h> 765551e69SJerome Forissier #include <string_ext.h> 8b0104773SPascal Brand #include <tee_api.h> 996c1d8c5SJens Wiklander #include <tee_internal_api_extensions.h> 10ef305e54SJens Wiklander #include <types_ext.h> 11b0104773SPascal Brand #include <user_ta_header.h> 1296c1d8c5SJens Wiklander #include <utee_syscalls.h> 13e86f1266SJens Wiklander #include "tee_api_private.h" 14b0104773SPascal Brand 15a83ee50aSSadiq Hussain /* 16a83ee50aSSadiq Hussain * return a known non-NULL invalid pointer when the 17a83ee50aSSadiq Hussain * requested size is zero 18a83ee50aSSadiq Hussain */ 19a83ee50aSSadiq Hussain #define TEE_NULL_SIZED_VA ((void *)1) 20*e64b7b2eSJens Wiklander #define TEE_NULL_SIZED_NO_SHARE_VA ((void *)2) 21*e64b7b2eSJens Wiklander 22*e64b7b2eSJens Wiklander /* 23*e64b7b2eSJens Wiklander * Workaround build error in Teaclave TrustZone SDK 24*e64b7b2eSJens Wiklander * 25*e64b7b2eSJens Wiklander * These are supposed to be provided by ta/arch/arm/user_ta_header.c, but 26*e64b7b2eSJens Wiklander * Teaclave TrustZone SDK seems to roll their own in Rust. 27*e64b7b2eSJens Wiklander */ 28*e64b7b2eSJens Wiklander uint8_t __ta_no_share_heap[0] __weak; 29*e64b7b2eSJens Wiklander const size_t __ta_no_share_heap_size __weak; 30*e64b7b2eSJens Wiklander struct malloc_ctx *__ta_no_share_malloc_ctx __weak; 31a83ee50aSSadiq Hussain 328f07fe6fSJerome Forissier static const void *tee_api_instance_data; 33b0104773SPascal Brand 34b0104773SPascal Brand /* System API - Internal Client API */ 35b0104773SPascal Brand 367509620bSJens Wiklander static void copy_param(struct utee_params *up, uint32_t param_types, 377509620bSJens Wiklander const TEE_Param params[TEE_NUM_PARAMS]) 387509620bSJens Wiklander { 397509620bSJens Wiklander size_t n = 0; 407509620bSJens Wiklander uint64_t a = 0; 417509620bSJens Wiklander uint64_t b = 0; 427509620bSJens Wiklander 437509620bSJens Wiklander up->types = param_types; 447509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 457509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 467509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 477509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 487509620bSJens Wiklander a = params[n].value.a; 497509620bSJens Wiklander b = params[n].value.b; 507509620bSJens Wiklander break; 517509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 527509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 537509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 547509620bSJens Wiklander a = (vaddr_t)params[n].memref.buffer; 557509620bSJens Wiklander b = params[n].memref.size; 567509620bSJens Wiklander break; 577509620bSJens Wiklander default: 587509620bSJens Wiklander a = 0; 597509620bSJens Wiklander b = 0; 607509620bSJens Wiklander } 617509620bSJens Wiklander up->vals[n * 2] = a; 627509620bSJens Wiklander up->vals[n * 2 + 1] = b; 637509620bSJens Wiklander } 647509620bSJens Wiklander } 657509620bSJens Wiklander 667509620bSJens Wiklander static void copy_gp11_param(struct utee_params *up, uint32_t param_types, 677509620bSJens Wiklander const __GP11_TEE_Param params[TEE_NUM_PARAMS]) 687509620bSJens Wiklander { 697509620bSJens Wiklander size_t n = 0; 707509620bSJens Wiklander uint64_t a = 0; 717509620bSJens Wiklander uint64_t b = 0; 727509620bSJens Wiklander 737509620bSJens Wiklander up->types = param_types; 747509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 757509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 767509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 777509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 787509620bSJens Wiklander a = params[n].value.a; 797509620bSJens Wiklander b = params[n].value.b; 807509620bSJens Wiklander break; 817509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 827509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 837509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 847509620bSJens Wiklander a = (vaddr_t)params[n].memref.buffer; 857509620bSJens Wiklander b = params[n].memref.size; 867509620bSJens Wiklander break; 877509620bSJens Wiklander default: 887509620bSJens Wiklander a = 0; 897509620bSJens Wiklander b = 0; 907509620bSJens Wiklander } 917509620bSJens Wiklander up->vals[n * 2] = a; 927509620bSJens Wiklander up->vals[n * 2 + 1] = b; 937509620bSJens Wiklander } 947509620bSJens Wiklander } 957509620bSJens Wiklander 967509620bSJens Wiklander static TEE_Result map_tmp_param(struct utee_params *up, void **tmp_buf, 977509620bSJens Wiklander size_t *tmp_len, void *tmp_va[TEE_NUM_PARAMS]) 98e86f1266SJens Wiklander { 99ef305e54SJens Wiklander size_t n = 0; 100ef305e54SJens Wiklander uint8_t *tb = NULL; 101ef305e54SJens Wiklander size_t tbl = 0; 102ef305e54SJens Wiklander size_t tmp_align = sizeof(vaddr_t) * 2; 103ef305e54SJens Wiklander bool is_tmp_mem[TEE_NUM_PARAMS] = { false }; 104ef305e54SJens Wiklander void *b = NULL; 105ef305e54SJens Wiklander size_t s = 0; 106ef305e54SJens Wiklander const uint32_t flags = TEE_MEMORY_ACCESS_READ; 107ef305e54SJens Wiklander 108ef305e54SJens Wiklander /* 109ef305e54SJens Wiklander * If a memory parameter points to TA private memory we need to 110ef305e54SJens Wiklander * allocate a temporary buffer to avoid exposing the memory 111ef305e54SJens Wiklander * directly to the called TA. 112ef305e54SJens Wiklander */ 113ef305e54SJens Wiklander 114ef305e54SJens Wiklander *tmp_buf = NULL; 115ef305e54SJens Wiklander *tmp_len = 0; 116ef305e54SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 117ef305e54SJens Wiklander tmp_va[n] = NULL; 1187509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 119ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 120ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 121ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 1227509620bSJens Wiklander b = (void *)(vaddr_t)up->vals[n * 2]; 1237509620bSJens Wiklander s = up->vals[n * 2 + 1]; 124ef305e54SJens Wiklander /* 125ef305e54SJens Wiklander * We're only allocating temporary memory if the 126ef305e54SJens Wiklander * buffer is completely within TA memory. If it's 127ef305e54SJens Wiklander * NULL, empty, partially outside or completely 128ef305e54SJens Wiklander * outside TA memory there's nothing more we need 129ef305e54SJens Wiklander * to do here. If there's security/permissions 130ef305e54SJens Wiklander * problem we'll get an error in the 131ef305e54SJens Wiklander * invoke_command/open_session below. 132ef305e54SJens Wiklander */ 133ef305e54SJens Wiklander if (b && s && 134ef305e54SJens Wiklander !TEE_CheckMemoryAccessRights(flags, b, s)) { 135ef305e54SJens Wiklander is_tmp_mem[n] = true; 136ef305e54SJens Wiklander tbl += ROUNDUP(s, tmp_align); 137ef305e54SJens Wiklander } 138ef305e54SJens Wiklander break; 139ef305e54SJens Wiklander default: 140ef305e54SJens Wiklander break; 141ef305e54SJens Wiklander } 142ef305e54SJens Wiklander } 143ef305e54SJens Wiklander 144ef305e54SJens Wiklander if (tbl) { 145ef305e54SJens Wiklander tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER); 146ef305e54SJens Wiklander if (!tb) 147ef305e54SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 148ef305e54SJens Wiklander *tmp_buf = tb; 149ef305e54SJens Wiklander *tmp_len = tbl; 150ef305e54SJens Wiklander } 151e86f1266SJens Wiklander 152e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 1537509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 154e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 155e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 156ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 1577509620bSJens Wiklander if (!is_tmp_mem[n]) 1587509620bSJens Wiklander break; 1597509620bSJens Wiklander s = up->vals[n * 2 + 1]; 1607509620bSJens Wiklander b = (void *)(vaddr_t)up->vals[n * 2]; 161ef305e54SJens Wiklander tmp_va[n] = tb; 162ef305e54SJens Wiklander tb += ROUNDUP(s, tmp_align); 1637509620bSJens Wiklander up->vals[n * 2] = (vaddr_t)tmp_va[n]; 1647509620bSJens Wiklander if (TEE_PARAM_TYPE_GET(up->types, n) != 165ef305e54SJens Wiklander TEE_PARAM_TYPE_MEMREF_OUTPUT) 1667509620bSJens Wiklander memcpy(tmp_va[n], b, s); 167e86f1266SJens Wiklander break; 168e86f1266SJens Wiklander default: 169e86f1266SJens Wiklander break; 170e86f1266SJens Wiklander } 171e86f1266SJens Wiklander } 172ef305e54SJens Wiklander 173ef305e54SJens Wiklander return TEE_SUCCESS; 1747509620bSJens Wiklander 175e86f1266SJens Wiklander } 176e86f1266SJens Wiklander 177ef305e54SJens Wiklander static void update_out_param(TEE_Param params[TEE_NUM_PARAMS], 178ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS], 179ef305e54SJens Wiklander const struct utee_params *up) 180e86f1266SJens Wiklander { 181e86f1266SJens Wiklander size_t n; 182e86f1266SJens Wiklander uint32_t types = up->types; 183e86f1266SJens Wiklander 184e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 185e86f1266SJens Wiklander uintptr_t a = up->vals[n * 2]; 186e86f1266SJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 187e86f1266SJens Wiklander 188e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 189e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 190e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 191e86f1266SJens Wiklander params[n].value.a = a; 192e86f1266SJens Wiklander params[n].value.b = b; 193e86f1266SJens Wiklander break; 194e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 195e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 196ef305e54SJens Wiklander if (tmp_va[n]) 197ef305e54SJens Wiklander memcpy(params[n].memref.buffer, tmp_va[n], 198ef305e54SJens Wiklander MIN(b, params[n].memref.size)); 199e86f1266SJens Wiklander params[n].memref.size = b; 200e86f1266SJens Wiklander break; 201e86f1266SJens Wiklander default: 202e86f1266SJens Wiklander break; 203e86f1266SJens Wiklander } 204e86f1266SJens Wiklander } 205e86f1266SJens Wiklander } 206e86f1266SJens Wiklander 2077509620bSJens Wiklander static void update_out_gp11_param(__GP11_TEE_Param params[TEE_NUM_PARAMS], 2087509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS], 2097509620bSJens Wiklander const struct utee_params *up) 2107509620bSJens Wiklander { 2117509620bSJens Wiklander size_t n = 0; 2127509620bSJens Wiklander uint32_t types = up->types; 2137509620bSJens Wiklander 2147509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 2157509620bSJens Wiklander uintptr_t a = up->vals[n * 2]; 2167509620bSJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 2177509620bSJens Wiklander 2187509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 2197509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 2207509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 2217509620bSJens Wiklander params[n].value.a = a; 2227509620bSJens Wiklander params[n].value.b = b; 2237509620bSJens Wiklander break; 2247509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 2257509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 2267509620bSJens Wiklander if (tmp_va[n]) 2277509620bSJens Wiklander memcpy(params[n].memref.buffer, tmp_va[n], 2287509620bSJens Wiklander MIN(b, params[n].memref.size)); 2297509620bSJens Wiklander params[n].memref.size = b; 2307509620bSJens Wiklander break; 2317509620bSJens Wiklander default: 2327509620bSJens Wiklander break; 2337509620bSJens Wiklander } 2347509620bSJens Wiklander } 2357509620bSJens Wiklander } 2367509620bSJens Wiklander 237c8bf6a25SJens Wiklander static bool bufs_intersect(void *buf1, size_t sz1, void *buf2, size_t sz2) 238c8bf6a25SJens Wiklander { 239c8bf6a25SJens Wiklander vaddr_t b1 = (vaddr_t)buf1; 240c8bf6a25SJens Wiklander vaddr_t b2 = (vaddr_t)buf2; 241c8bf6a25SJens Wiklander vaddr_t e1 = b1 + sz1 - 1; 242c8bf6a25SJens Wiklander vaddr_t e2 = b2 + sz2 - 1; 243c8bf6a25SJens Wiklander 244c8bf6a25SJens Wiklander if (!sz1 || !sz2) 245c8bf6a25SJens Wiklander return false; 246c8bf6a25SJens Wiklander 247c8bf6a25SJens Wiklander if (e1 < b2 || e2 < b1) 248c8bf6a25SJens Wiklander return false; 249c8bf6a25SJens Wiklander 250c8bf6a25SJens Wiklander return true; 251c8bf6a25SJens Wiklander } 252c8bf6a25SJens Wiklander 253c8bf6a25SJens Wiklander static TEE_Result check_mem_access_rights_params(uint32_t flags, void *buf, 254c8bf6a25SJens Wiklander size_t len) 255c8bf6a25SJens Wiklander { 256c8bf6a25SJens Wiklander size_t n = 0; 257c8bf6a25SJens Wiklander 258c8bf6a25SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 259c8bf6a25SJens Wiklander uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER; 260c8bf6a25SJens Wiklander 261c8bf6a25SJens Wiklander switch (TEE_PARAM_TYPE_GET(ta_param_types, n)) { 262c8bf6a25SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 263c8bf6a25SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 264c8bf6a25SJens Wiklander f |= TEE_MEMORY_ACCESS_WRITE; 265c8bf6a25SJens Wiklander fallthrough; 266c8bf6a25SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 267c8bf6a25SJens Wiklander f |= TEE_MEMORY_ACCESS_READ; 268c8bf6a25SJens Wiklander if (bufs_intersect(buf, len, 269c8bf6a25SJens Wiklander ta_params[n].memref.buffer, 270c8bf6a25SJens Wiklander ta_params[n].memref.size)) { 271c8bf6a25SJens Wiklander if ((flags & f) != flags) 272c8bf6a25SJens Wiklander return TEE_ERROR_ACCESS_DENIED; 273c8bf6a25SJens Wiklander } 274c8bf6a25SJens Wiklander break; 275c8bf6a25SJens Wiklander default: 276c8bf6a25SJens Wiklander break; 277c8bf6a25SJens Wiklander } 278c8bf6a25SJens Wiklander } 279c8bf6a25SJens Wiklander 280c8bf6a25SJens Wiklander return TEE_SUCCESS; 281c8bf6a25SJens Wiklander } 282c8bf6a25SJens Wiklander 283*e64b7b2eSJens Wiklander static bool buf_overlaps_no_share_heap(void *buf, size_t size) 284*e64b7b2eSJens Wiklander { 285*e64b7b2eSJens Wiklander struct malloc_ctx *ctx = __ta_no_share_malloc_ctx; 286*e64b7b2eSJens Wiklander 287*e64b7b2eSJens Wiklander return ctx && raw_malloc_buffer_overlaps_heap(ctx, buf, size); 288*e64b7b2eSJens Wiklander } 289*e64b7b2eSJens Wiklander 29030e5e0beSJens Wiklander static void check_invoke_param(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS]) 29130e5e0beSJens Wiklander { 29230e5e0beSJens Wiklander size_t n = 0; 29330e5e0beSJens Wiklander 29430e5e0beSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 29530e5e0beSJens Wiklander uint32_t f = TEE_MEMORY_ACCESS_ANY_OWNER; 29630e5e0beSJens Wiklander void *buf = params[n].memref.buffer; 29730e5e0beSJens Wiklander size_t size = params[n].memref.size; 29830e5e0beSJens Wiklander 29930e5e0beSJens Wiklander switch (TEE_PARAM_TYPE_GET(pt, n)) { 30030e5e0beSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 30130e5e0beSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 30230e5e0beSJens Wiklander f |= TEE_MEMORY_ACCESS_WRITE; 30330e5e0beSJens Wiklander fallthrough; 30430e5e0beSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 30530e5e0beSJens Wiklander f |= TEE_MEMORY_ACCESS_READ; 30630e5e0beSJens Wiklander if (check_mem_access_rights_params(f, buf, size)) 30730e5e0beSJens Wiklander TEE_Panic(0); 308*e64b7b2eSJens Wiklander if (buf_overlaps_no_share_heap(buf, size)) 309*e64b7b2eSJens Wiklander TEE_Panic(0); 31030e5e0beSJens Wiklander break; 31130e5e0beSJens Wiklander default: 31230e5e0beSJens Wiklander break; 31330e5e0beSJens Wiklander } 31430e5e0beSJens Wiklander } 31530e5e0beSJens Wiklander } 31630e5e0beSJens Wiklander 317b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination, 318b0104773SPascal Brand uint32_t cancellationRequestTimeout, 31968540524SIgor Opaniuk uint32_t paramTypes, 32068540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 321b0104773SPascal Brand TEE_TASessionHandle *session, 322b0104773SPascal Brand uint32_t *returnOrigin) 323b0104773SPascal Brand { 324ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 3257509620bSJens Wiklander struct utee_params up = { }; 326ef305e54SJens Wiklander uint32_t s = 0; 327ef305e54SJens Wiklander void *tmp_buf = NULL; 328ef305e54SJens Wiklander size_t tmp_len = 0; 329ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 330b0104773SPascal Brand 33130e5e0beSJens Wiklander if (paramTypes) { 3326915bbbbSJens Wiklander __utee_check_inout_annotation(params, 3336915bbbbSJens Wiklander sizeof(TEE_Param) * 3346915bbbbSJens Wiklander TEE_NUM_PARAMS); 33530e5e0beSJens Wiklander check_invoke_param(paramTypes, params); 33630e5e0beSJens Wiklander } 3376915bbbbSJens Wiklander __utee_check_out_annotation(session, sizeof(*session)); 3386915bbbbSJens Wiklander 3397509620bSJens Wiklander copy_param(&up, paramTypes, params); 3407509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 341ef305e54SJens Wiklander if (res) 342ef305e54SJens Wiklander goto out; 3432c028fdeSJerome Forissier res = _utee_open_ta_session(destination, cancellationRequestTimeout, 344e86f1266SJens Wiklander &up, &s, returnOrigin); 345ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 346ef305e54SJens Wiklander if (tmp_buf) { 347ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 348ef305e54SJens Wiklander 349ef305e54SJens Wiklander if (res2) 350ef305e54SJens Wiklander TEE_Panic(res2); 351ef305e54SJens Wiklander } 352ef305e54SJens Wiklander 353ef305e54SJens Wiklander out: 354b0104773SPascal Brand /* 355b0104773SPascal Brand * Specification says that *session must hold TEE_HANDLE_NULL is 356b0104773SPascal Brand * TEE_SUCCESS isn't returned. Set it here explicitly in case 357b0104773SPascal Brand * the syscall fails before out parameters has been updated. 358b0104773SPascal Brand */ 359b0104773SPascal Brand if (res != TEE_SUCCESS) 360e86f1266SJens Wiklander s = TEE_HANDLE_NULL; 361b0104773SPascal Brand 362e86f1266SJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 363b0104773SPascal Brand return res; 364b0104773SPascal Brand } 365b0104773SPascal Brand 3667509620bSJens Wiklander TEE_Result __GP11_TEE_OpenTASession(const TEE_UUID *destination, 3677509620bSJens Wiklander uint32_t cancellationRequestTimeout, 3687509620bSJens Wiklander uint32_t paramTypes, 3697509620bSJens Wiklander __GP11_TEE_Param params[TEE_NUM_PARAMS], 3707509620bSJens Wiklander TEE_TASessionHandle *session, 3717509620bSJens Wiklander uint32_t *returnOrigin) 3727509620bSJens Wiklander { 3737509620bSJens Wiklander TEE_Result res = TEE_SUCCESS; 3747509620bSJens Wiklander struct utee_params up = { }; 3757509620bSJens Wiklander uint32_t s = 0; 3767509620bSJens Wiklander void *tmp_buf = NULL; 3777509620bSJens Wiklander size_t tmp_len = 0; 3787509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 3797509620bSJens Wiklander 3807509620bSJens Wiklander if (paramTypes) 3817509620bSJens Wiklander __utee_check_inout_annotation(params, 3827509620bSJens Wiklander sizeof(__GP11_TEE_Param) * 3837509620bSJens Wiklander TEE_NUM_PARAMS); 3847509620bSJens Wiklander __utee_check_out_annotation(session, sizeof(*session)); 3857509620bSJens Wiklander 3867509620bSJens Wiklander copy_gp11_param(&up, paramTypes, params); 3877509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 3887509620bSJens Wiklander if (res) 3897509620bSJens Wiklander goto out; 3907509620bSJens Wiklander res = _utee_open_ta_session(destination, cancellationRequestTimeout, 3917509620bSJens Wiklander &up, &s, returnOrigin); 3927509620bSJens Wiklander update_out_gp11_param(params, tmp_va, &up); 3937509620bSJens Wiklander if (tmp_buf) { 3947509620bSJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 3957509620bSJens Wiklander 3967509620bSJens Wiklander if (res2) 3977509620bSJens Wiklander TEE_Panic(res2); 3987509620bSJens Wiklander } 3997509620bSJens Wiklander 4007509620bSJens Wiklander out: 4017509620bSJens Wiklander /* 4027509620bSJens Wiklander * Specification says that *session must hold TEE_HANDLE_NULL if 4037509620bSJens Wiklander * TEE_SUCCESS isn't returned. Set it here explicitly in case 4047509620bSJens Wiklander * the syscall fails before out parameters has been updated. 4057509620bSJens Wiklander */ 4067509620bSJens Wiklander if (res != TEE_SUCCESS) 4077509620bSJens Wiklander s = TEE_HANDLE_NULL; 4087509620bSJens Wiklander 4097509620bSJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 4107509620bSJens Wiklander return res; 4117509620bSJens Wiklander } 4127509620bSJens Wiklander 413b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session) 414b0104773SPascal Brand { 415b0104773SPascal Brand if (session != TEE_HANDLE_NULL) { 4162c028fdeSJerome Forissier TEE_Result res = _utee_close_ta_session((uintptr_t)session); 417e86f1266SJens Wiklander 418b0104773SPascal Brand if (res != TEE_SUCCESS) 419b0104773SPascal Brand TEE_Panic(res); 420b0104773SPascal Brand } 421b0104773SPascal Brand } 422b0104773SPascal Brand 423b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, 424b0104773SPascal Brand uint32_t cancellationRequestTimeout, 425b0104773SPascal Brand uint32_t commandID, uint32_t paramTypes, 42668540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 42768540524SIgor Opaniuk uint32_t *returnOrigin) 428b0104773SPascal Brand { 429ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 430ef305e54SJens Wiklander uint32_t ret_origin = TEE_ORIGIN_TEE; 4317509620bSJens Wiklander struct utee_params up = { }; 432ef305e54SJens Wiklander void *tmp_buf = NULL; 433ef305e54SJens Wiklander size_t tmp_len = 0; 434ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 435c15e5835SCedric Chaumont 43630e5e0beSJens Wiklander if (paramTypes) { 4376915bbbbSJens Wiklander __utee_check_inout_annotation(params, 4386915bbbbSJens Wiklander sizeof(TEE_Param) * 4396915bbbbSJens Wiklander TEE_NUM_PARAMS); 44030e5e0beSJens Wiklander check_invoke_param(paramTypes, params); 44130e5e0beSJens Wiklander } 4426915bbbbSJens Wiklander if (returnOrigin) 4436915bbbbSJens Wiklander __utee_check_out_annotation(returnOrigin, 4446915bbbbSJens Wiklander sizeof(*returnOrigin)); 4456915bbbbSJens Wiklander 4467509620bSJens Wiklander copy_param(&up, paramTypes, params); 4477509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 448ef305e54SJens Wiklander if (res) 449ef305e54SJens Wiklander goto out; 4502c028fdeSJerome Forissier res = _utee_invoke_ta_command((uintptr_t)session, 451e86f1266SJens Wiklander cancellationRequestTimeout, 452e86f1266SJens Wiklander commandID, &up, &ret_origin); 453ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 454ef305e54SJens Wiklander if (tmp_buf) { 455ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 4566709c3eaSCedric Chaumont 457ef305e54SJens Wiklander if (res2) 458ef305e54SJens Wiklander TEE_Panic(res2); 459ef305e54SJens Wiklander } 460ef305e54SJens Wiklander 461ef305e54SJens Wiklander out: 4626709c3eaSCedric Chaumont if (returnOrigin != NULL) 4636709c3eaSCedric Chaumont *returnOrigin = ret_origin; 4646709c3eaSCedric Chaumont 4656709c3eaSCedric Chaumont if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 4666709c3eaSCedric Chaumont return res; 4676709c3eaSCedric Chaumont 468c15e5835SCedric Chaumont if (res != TEE_SUCCESS && 469c15e5835SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 470c15e5835SCedric Chaumont res != TEE_ERROR_TARGET_DEAD) 471c15e5835SCedric Chaumont TEE_Panic(res); 472c15e5835SCedric Chaumont 473c15e5835SCedric Chaumont return res; 474b0104773SPascal Brand } 475b0104773SPascal Brand 4767509620bSJens Wiklander TEE_Result __GP11_TEE_InvokeTACommand(TEE_TASessionHandle session, 4777509620bSJens Wiklander uint32_t cancellationRequestTimeout, 4787509620bSJens Wiklander uint32_t commandID, uint32_t paramTypes, 4797509620bSJens Wiklander __GP11_TEE_Param params[TEE_NUM_PARAMS], 4807509620bSJens Wiklander uint32_t *returnOrigin) 4817509620bSJens Wiklander { 4827509620bSJens Wiklander TEE_Result res = TEE_SUCCESS; 4837509620bSJens Wiklander uint32_t ret_origin = TEE_ORIGIN_TEE; 4847509620bSJens Wiklander struct utee_params up = { }; 4857509620bSJens Wiklander void *tmp_buf = NULL; 4867509620bSJens Wiklander size_t tmp_len = 0; 4877509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 4887509620bSJens Wiklander 4897509620bSJens Wiklander if (paramTypes) 4907509620bSJens Wiklander __utee_check_inout_annotation(params, 4917509620bSJens Wiklander sizeof(__GP11_TEE_Param) * 4927509620bSJens Wiklander TEE_NUM_PARAMS); 4937509620bSJens Wiklander if (returnOrigin) 4947509620bSJens Wiklander __utee_check_out_annotation(returnOrigin, 4957509620bSJens Wiklander sizeof(*returnOrigin)); 4967509620bSJens Wiklander 4977509620bSJens Wiklander copy_gp11_param(&up, paramTypes, params); 4987509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 4997509620bSJens Wiklander if (res) 5007509620bSJens Wiklander goto out; 5017509620bSJens Wiklander res = _utee_invoke_ta_command((uintptr_t)session, 5027509620bSJens Wiklander cancellationRequestTimeout, 5037509620bSJens Wiklander commandID, &up, &ret_origin); 5047509620bSJens Wiklander update_out_gp11_param(params, tmp_va, &up); 5057509620bSJens Wiklander if (tmp_buf) { 5067509620bSJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 5077509620bSJens Wiklander 5087509620bSJens Wiklander if (res2) 5097509620bSJens Wiklander TEE_Panic(res2); 5107509620bSJens Wiklander } 5117509620bSJens Wiklander 5127509620bSJens Wiklander out: 5137509620bSJens Wiklander if (returnOrigin) 5147509620bSJens Wiklander *returnOrigin = ret_origin; 5157509620bSJens Wiklander 5167509620bSJens Wiklander if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 5177509620bSJens Wiklander return res; 5187509620bSJens Wiklander 5197509620bSJens Wiklander if (res != TEE_SUCCESS && 5207509620bSJens Wiklander res != TEE_ERROR_OUT_OF_MEMORY && 5217509620bSJens Wiklander res != TEE_ERROR_TARGET_DEAD) 5227509620bSJens Wiklander TEE_Panic(res); 5237509620bSJens Wiklander 5247509620bSJens Wiklander return res; 5257509620bSJens Wiklander } 5267509620bSJens Wiklander 527b0104773SPascal Brand /* System API - Cancellations */ 528b0104773SPascal Brand 529b0104773SPascal Brand bool TEE_GetCancellationFlag(void) 530b0104773SPascal Brand { 531e86f1266SJens Wiklander uint32_t c; 5322c028fdeSJerome Forissier TEE_Result res = _utee_get_cancellation_flag(&c); 533e86f1266SJens Wiklander 534b0104773SPascal Brand if (res != TEE_SUCCESS) 535e86f1266SJens Wiklander c = 0; 536e86f1266SJens Wiklander return !!c; 537b0104773SPascal Brand } 538b0104773SPascal Brand 539b0104773SPascal Brand bool TEE_UnmaskCancellation(void) 540b0104773SPascal Brand { 541e86f1266SJens Wiklander uint32_t old_mask; 5422c028fdeSJerome Forissier TEE_Result res = _utee_unmask_cancellation(&old_mask); 543b0104773SPascal Brand 544b0104773SPascal Brand if (res != TEE_SUCCESS) 545b0104773SPascal Brand TEE_Panic(res); 546e86f1266SJens Wiklander return !!old_mask; 547b0104773SPascal Brand } 548b0104773SPascal Brand 549b0104773SPascal Brand bool TEE_MaskCancellation(void) 550b0104773SPascal Brand { 551e86f1266SJens Wiklander uint32_t old_mask; 5522c028fdeSJerome Forissier TEE_Result res = _utee_mask_cancellation(&old_mask); 553b0104773SPascal Brand 554b0104773SPascal Brand if (res != TEE_SUCCESS) 555b0104773SPascal Brand TEE_Panic(res); 556e86f1266SJens Wiklander return !!old_mask; 557b0104773SPascal Brand } 558b0104773SPascal Brand 559b0104773SPascal Brand /* System API - Memory Management */ 560b0104773SPascal Brand 561b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer, 562cd3a8caeSJens Wiklander size_t size) 563b0104773SPascal Brand { 564c8bf6a25SJens Wiklander uint32_t flags = accessFlags; 565b0104773SPascal Brand 566c8bf6a25SJens Wiklander if (!size) 567b0104773SPascal Brand return TEE_SUCCESS; 568b0104773SPascal Brand 569c8bf6a25SJens Wiklander /* 570c8bf6a25SJens Wiklander * Check access rights against memory mapping. If this check is 571c8bf6a25SJens Wiklander * OK the size can't cause an overflow when added with buffer. 572c8bf6a25SJens Wiklander */ 573c8bf6a25SJens Wiklander if (_utee_check_access_rights(accessFlags, buffer, size)) 574c8bf6a25SJens Wiklander return TEE_ERROR_ACCESS_DENIED; 575b0104773SPascal Brand 576b0104773SPascal Brand /* 577c8bf6a25SJens Wiklander * Check access rights against input parameters. 578c8bf6a25SJens Wiklander * 579c8bf6a25SJens Wiklander * Clear eventual extension flags like TEE_MEMORY_ACCESS_NONSECURE 580c8bf6a25SJens Wiklander * and TEE_MEMORY_ACCESS_SECURE. 581b0104773SPascal Brand */ 582c8bf6a25SJens Wiklander flags &= TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE | 583c8bf6a25SJens Wiklander TEE_MEMORY_ACCESS_ANY_OWNER; 584c8bf6a25SJens Wiklander if (check_mem_access_rights_params(flags, buffer, size)) 585c8bf6a25SJens Wiklander return TEE_ERROR_ACCESS_DENIED; 586b0104773SPascal Brand 587c8bf6a25SJens Wiklander if (malloc_buffer_overlaps_heap(buffer, size) && 588c8bf6a25SJens Wiklander !malloc_buffer_is_within_alloced(buffer, size)) 589c8bf6a25SJens Wiklander return TEE_ERROR_ACCESS_DENIED; 590c8bf6a25SJens Wiklander 591c8bf6a25SJens Wiklander return TEE_SUCCESS; 592b0104773SPascal Brand } 593b0104773SPascal Brand 594cd3a8caeSJens Wiklander TEE_Result __GP11_TEE_CheckMemoryAccessRights(uint32_t accessFlags, 595cd3a8caeSJens Wiklander void *buffer, uint32_t size) 596cd3a8caeSJens Wiklander { 597cd3a8caeSJens Wiklander return TEE_CheckMemoryAccessRights(accessFlags, buffer, size); 598cd3a8caeSJens Wiklander } 599cd3a8caeSJens Wiklander 6008f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData) 601b0104773SPascal Brand { 602b0104773SPascal Brand tee_api_instance_data = instanceData; 603b0104773SPascal Brand } 604b0104773SPascal Brand 6058f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void) 606b0104773SPascal Brand { 607b0104773SPascal Brand return tee_api_instance_data; 608b0104773SPascal Brand } 609b0104773SPascal Brand 6101d0ed95aSJens Wiklander void *TEE_MemMove(void *dest, const void *src, size_t size) 611b0104773SPascal Brand { 612b0104773SPascal Brand return memmove(dest, src, size); 613b0104773SPascal Brand } 614b0104773SPascal Brand 6151d0ed95aSJens Wiklander void *__GP11_TEE_MemMove(void *dest, const void *src, uint32_t size) 6161d0ed95aSJens Wiklander { 6171d0ed95aSJens Wiklander return TEE_MemMove(dest, src, size); 6181d0ed95aSJens Wiklander } 6191d0ed95aSJens Wiklander 6201d0ed95aSJens Wiklander int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, size_t size) 621b0104773SPascal Brand { 62265551e69SJerome Forissier return consttime_memcmp(buffer1, buffer2, size); 623b0104773SPascal Brand } 624b0104773SPascal Brand 6251d0ed95aSJens Wiklander int32_t __GP11_TEE_MemCompare(const void *buffer1, const void *buffer2, 6261d0ed95aSJens Wiklander uint32_t size) 6271d0ed95aSJens Wiklander { 6281d0ed95aSJens Wiklander return TEE_MemCompare(buffer1, buffer2, size); 6291d0ed95aSJens Wiklander } 6301d0ed95aSJens Wiklander 6311d0ed95aSJens Wiklander void TEE_MemFill(void *buff, uint32_t x, size_t size) 632b0104773SPascal Brand { 63332c75600SJens Wiklander memset(buff, x, size); 634b0104773SPascal Brand } 635b0104773SPascal Brand 6361d0ed95aSJens Wiklander void __GP11_TEE_MemFill(void *buff, uint32_t x, uint32_t size) 6371d0ed95aSJens Wiklander { 6381d0ed95aSJens Wiklander TEE_MemFill(buff, x, size); 6391d0ed95aSJens Wiklander } 6401d0ed95aSJens Wiklander 641b0104773SPascal Brand /* Date & Time API */ 642b0104773SPascal Brand 643b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time) 644b0104773SPascal Brand { 6452c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time); 646b0104773SPascal Brand 647b0104773SPascal Brand if (res != TEE_SUCCESS) 648b36311adSJerome Forissier TEE_Panic(res); 649b0104773SPascal Brand } 650b0104773SPascal Brand 651b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout) 652b0104773SPascal Brand { 6532c028fdeSJerome Forissier TEE_Result res = _utee_wait(timeout); 654b0104773SPascal Brand 655b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL) 656b0104773SPascal Brand TEE_Panic(res); 657b0104773SPascal Brand 658b0104773SPascal Brand return res; 659b0104773SPascal Brand } 660b0104773SPascal Brand 661b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time) 662b0104773SPascal Brand { 663b64d6909SCedric Chaumont TEE_Result res; 664b64d6909SCedric Chaumont 6652c028fdeSJerome Forissier res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time); 666b64d6909SCedric Chaumont 667b64d6909SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) { 668b64d6909SCedric Chaumont time->seconds = 0; 669b64d6909SCedric Chaumont time->millis = 0; 670b64d6909SCedric Chaumont } 671b64d6909SCedric Chaumont 672b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 673b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NOT_SET && 674b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NEEDS_RESET && 675b64d6909SCedric Chaumont res != TEE_ERROR_OVERFLOW && 676b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY) 677b64d6909SCedric Chaumont TEE_Panic(res); 678b64d6909SCedric Chaumont 679b64d6909SCedric Chaumont return res; 680b0104773SPascal Brand } 681b0104773SPascal Brand 682b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time) 683b0104773SPascal Brand { 684b64d6909SCedric Chaumont TEE_Result res; 685b64d6909SCedric Chaumont 6862c028fdeSJerome Forissier res = _utee_set_ta_time(time); 687b64d6909SCedric Chaumont 688b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 689b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 690b64d6909SCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE) 691b64d6909SCedric Chaumont TEE_Panic(res); 692b64d6909SCedric Chaumont 693b64d6909SCedric Chaumont return res; 694b0104773SPascal Brand } 695b0104773SPascal Brand 696b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time) 697b0104773SPascal Brand { 6982c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time); 699b0104773SPascal Brand 700b0104773SPascal Brand if (res != TEE_SUCCESS) 701b36311adSJerome Forissier TEE_Panic(res); 702b0104773SPascal Brand } 703b0104773SPascal Brand 70411285ebcSJens Wiklander void *TEE_Malloc(size_t len, uint32_t hint) 705b0104773SPascal Brand { 70611285ebcSJens Wiklander switch (hint) { 70711285ebcSJens Wiklander case TEE_MALLOC_FILL_ZERO: 708a83ee50aSSadiq Hussain if (!len) 709a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 71096c1d8c5SJens Wiklander return calloc(1, len); 71111285ebcSJens Wiklander 71211285ebcSJens Wiklander case TEE_MALLOC_NO_FILL: 71311285ebcSJens Wiklander TEE_Panic(0); 71411285ebcSJens Wiklander break; 71511285ebcSJens Wiklander 716*e64b7b2eSJens Wiklander case TEE_MALLOC_NO_SHARE: 717*e64b7b2eSJens Wiklander if (!len) 718*e64b7b2eSJens Wiklander return TEE_NULL_SIZED_NO_SHARE_VA; 719*e64b7b2eSJens Wiklander if (!__ta_no_share_malloc_ctx) 720*e64b7b2eSJens Wiklander return NULL; 721*e64b7b2eSJens Wiklander return raw_calloc(0, 0, 1, len, __ta_no_share_malloc_ctx); 722*e64b7b2eSJens Wiklander 72311285ebcSJens Wiklander case TEE_MALLOC_NO_FILL | TEE_MALLOC_NO_SHARE: 724*e64b7b2eSJens Wiklander if (!len) 725*e64b7b2eSJens Wiklander return TEE_NULL_SIZED_NO_SHARE_VA; 726*e64b7b2eSJens Wiklander if (!__ta_no_share_malloc_ctx) 727*e64b7b2eSJens Wiklander return NULL; 728*e64b7b2eSJens Wiklander return raw_malloc(0, 0, len, __ta_no_share_malloc_ctx); 72911285ebcSJens Wiklander 73011285ebcSJens Wiklander case TEE_USER_MEM_HINT_NO_FILL_ZERO: 73111285ebcSJens Wiklander if (!len) 73211285ebcSJens Wiklander return TEE_NULL_SIZED_VA; 73396c1d8c5SJens Wiklander return malloc(len); 73496c1d8c5SJens Wiklander 73511285ebcSJens Wiklander default: 73611285ebcSJens Wiklander break; 73711285ebcSJens Wiklander } 73811285ebcSJens Wiklander 73996c1d8c5SJens Wiklander EMSG("Invalid hint %#" PRIx32, hint); 74096c1d8c5SJens Wiklander 74196c1d8c5SJens Wiklander return NULL; 742b0104773SPascal Brand } 743b0104773SPascal Brand 74411285ebcSJens Wiklander void *__GP11_TEE_Malloc(uint32_t size, uint32_t hint) 74511285ebcSJens Wiklander { 74611285ebcSJens Wiklander return TEE_Malloc(size, hint); 74711285ebcSJens Wiklander } 74811285ebcSJens Wiklander 749*e64b7b2eSJens Wiklander static bool addr_is_in_no_share_heap(void *p) 750*e64b7b2eSJens Wiklander { 751*e64b7b2eSJens Wiklander return buf_overlaps_no_share_heap(p, 1); 752*e64b7b2eSJens Wiklander } 753*e64b7b2eSJens Wiklander 75411285ebcSJens Wiklander void *TEE_Realloc(void *buffer, size_t newSize) 755b0104773SPascal Brand { 756a83ee50aSSadiq Hussain if (!newSize) { 757a83ee50aSSadiq Hussain TEE_Free(buffer); 758*e64b7b2eSJens Wiklander 759*e64b7b2eSJens Wiklander if (addr_is_in_no_share_heap(buffer)) 760*e64b7b2eSJens Wiklander return TEE_NULL_SIZED_NO_SHARE_VA; 761*e64b7b2eSJens Wiklander else 762a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 763a83ee50aSSadiq Hussain } 764a83ee50aSSadiq Hussain 765a83ee50aSSadiq Hussain if (buffer == TEE_NULL_SIZED_VA) 766a83ee50aSSadiq Hussain return calloc(1, newSize); 767*e64b7b2eSJens Wiklander if (buffer == TEE_NULL_SIZED_NO_SHARE_VA) { 768*e64b7b2eSJens Wiklander if (!__ta_no_share_malloc_ctx) 769*e64b7b2eSJens Wiklander return NULL; 770*e64b7b2eSJens Wiklander return raw_calloc(0, 0, 1, newSize, __ta_no_share_malloc_ctx); 771*e64b7b2eSJens Wiklander } 772a83ee50aSSadiq Hussain 773*e64b7b2eSJens Wiklander if (addr_is_in_no_share_heap(buffer)) 774*e64b7b2eSJens Wiklander return raw_realloc(buffer, 0, 0, newSize, 775*e64b7b2eSJens Wiklander __ta_no_share_malloc_ctx); 776*e64b7b2eSJens Wiklander else 77796c1d8c5SJens Wiklander return realloc(buffer, newSize); 778b0104773SPascal Brand } 779b0104773SPascal Brand 78011285ebcSJens Wiklander void *__GP11_TEE_Realloc(void *buffer, uint32_t newSize) 78111285ebcSJens Wiklander { 78211285ebcSJens Wiklander return TEE_Realloc(buffer, newSize); 78311285ebcSJens Wiklander } 78411285ebcSJens Wiklander 785b0104773SPascal Brand void TEE_Free(void *buffer) 786b0104773SPascal Brand { 787*e64b7b2eSJens Wiklander if (buffer != TEE_NULL_SIZED_VA && 788*e64b7b2eSJens Wiklander buffer != TEE_NULL_SIZED_NO_SHARE_VA) { 789*e64b7b2eSJens Wiklander if (addr_is_in_no_share_heap(buffer)) 790*e64b7b2eSJens Wiklander raw_free(buffer, __ta_no_share_malloc_ctx, false); 791*e64b7b2eSJens Wiklander else 79296c1d8c5SJens Wiklander free(buffer); 793b0104773SPascal Brand } 794*e64b7b2eSJens Wiklander } 795fa530828SPascal Brand 796fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ 797fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len) 798fa530828SPascal Brand { 7992c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHECLEAN); 800fa530828SPascal Brand } 801fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len) 802fa530828SPascal Brand { 8032c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEFLUSH); 804fa530828SPascal Brand } 805fa530828SPascal Brand 806fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len) 807fa530828SPascal Brand { 8082c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); 809fa530828SPascal Brand } 810