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) 20a83ee50aSSadiq Hussain 218f07fe6fSJerome Forissier static const void *tee_api_instance_data; 22b0104773SPascal Brand 23b0104773SPascal Brand /* System API - Internal Client API */ 24b0104773SPascal Brand 25ef305e54SJens Wiklander static TEE_Result copy_param(struct utee_params *up, uint32_t param_types, 26ef305e54SJens Wiklander const TEE_Param params[TEE_NUM_PARAMS], 27ef305e54SJens Wiklander void **tmp_buf, size_t *tmp_len, 28ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS]) 29e86f1266SJens Wiklander { 30ef305e54SJens Wiklander size_t n = 0; 31ef305e54SJens Wiklander uint8_t *tb = NULL; 32ef305e54SJens Wiklander size_t tbl = 0; 33ef305e54SJens Wiklander size_t tmp_align = sizeof(vaddr_t) * 2; 34ef305e54SJens Wiklander bool is_tmp_mem[TEE_NUM_PARAMS] = { false }; 35ef305e54SJens Wiklander void *b = NULL; 36ef305e54SJens Wiklander size_t s = 0; 37ef305e54SJens Wiklander const uint32_t flags = TEE_MEMORY_ACCESS_READ; 38ef305e54SJens Wiklander 39ef305e54SJens Wiklander /* 40ef305e54SJens Wiklander * If a memory parameter points to TA private memory we need to 41ef305e54SJens Wiklander * allocate a temporary buffer to avoid exposing the memory 42ef305e54SJens Wiklander * directly to the called TA. 43ef305e54SJens Wiklander */ 44ef305e54SJens Wiklander 45ef305e54SJens Wiklander *tmp_buf = NULL; 46ef305e54SJens Wiklander *tmp_len = 0; 47ef305e54SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 48ef305e54SJens Wiklander tmp_va[n] = NULL; 49ef305e54SJens Wiklander switch (TEE_PARAM_TYPE_GET(param_types, n)) { 50ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 51ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 52ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 53ef305e54SJens Wiklander b = params[n].memref.buffer; 54ef305e54SJens Wiklander s = params[n].memref.size; 55ef305e54SJens Wiklander /* 56ef305e54SJens Wiklander * We're only allocating temporary memory if the 57ef305e54SJens Wiklander * buffer is completely within TA memory. If it's 58ef305e54SJens Wiklander * NULL, empty, partially outside or completely 59ef305e54SJens Wiklander * outside TA memory there's nothing more we need 60ef305e54SJens Wiklander * to do here. If there's security/permissions 61ef305e54SJens Wiklander * problem we'll get an error in the 62ef305e54SJens Wiklander * invoke_command/open_session below. 63ef305e54SJens Wiklander */ 64ef305e54SJens Wiklander if (b && s && 65ef305e54SJens Wiklander !TEE_CheckMemoryAccessRights(flags, b, s)) { 66ef305e54SJens Wiklander is_tmp_mem[n] = true; 67ef305e54SJens Wiklander tbl += ROUNDUP(s, tmp_align); 68ef305e54SJens Wiklander } 69ef305e54SJens Wiklander break; 70ef305e54SJens Wiklander default: 71ef305e54SJens Wiklander break; 72ef305e54SJens Wiklander } 73ef305e54SJens Wiklander } 74ef305e54SJens Wiklander 75ef305e54SJens Wiklander if (tbl) { 76ef305e54SJens Wiklander tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER); 77ef305e54SJens Wiklander if (!tb) 78ef305e54SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 79ef305e54SJens Wiklander *tmp_buf = tb; 80ef305e54SJens Wiklander *tmp_len = tbl; 81ef305e54SJens Wiklander } 82e86f1266SJens Wiklander 83e86f1266SJens Wiklander up->types = param_types; 84e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 85e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(param_types, n)) { 86e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 87e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 88e86f1266SJens Wiklander up->vals[n * 2] = params[n].value.a; 89e86f1266SJens Wiklander up->vals[n * 2 + 1] = params[n].value.b; 90e86f1266SJens Wiklander break; 91e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 92e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 93ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 94ef305e54SJens Wiklander s = params[n].memref.size; 95ef305e54SJens Wiklander if (is_tmp_mem[n]) { 96ef305e54SJens Wiklander b = tb; 97ef305e54SJens Wiklander tmp_va[n] = tb; 98ef305e54SJens Wiklander tb += ROUNDUP(s, tmp_align); 99ef305e54SJens Wiklander if (TEE_PARAM_TYPE_GET(param_types, n) != 100ef305e54SJens Wiklander TEE_PARAM_TYPE_MEMREF_OUTPUT) 101ef305e54SJens Wiklander memcpy(b, params[n].memref.buffer, s); 102ef305e54SJens Wiklander } else { 103ef305e54SJens Wiklander b = params[n].memref.buffer; 104ef305e54SJens Wiklander } 105ef305e54SJens Wiklander up->vals[n * 2] = (vaddr_t)b; 106ef305e54SJens Wiklander up->vals[n * 2 + 1] = s; 107e86f1266SJens Wiklander break; 108e86f1266SJens Wiklander default: 109e86f1266SJens Wiklander up->vals[n * 2] = 0; 110e86f1266SJens Wiklander up->vals[n * 2 + 1] = 0; 111e86f1266SJens Wiklander break; 112e86f1266SJens Wiklander } 113e86f1266SJens Wiklander } 114ef305e54SJens Wiklander 115ef305e54SJens Wiklander return TEE_SUCCESS; 116e86f1266SJens Wiklander } 117e86f1266SJens Wiklander 118ef305e54SJens Wiklander static void update_out_param(TEE_Param params[TEE_NUM_PARAMS], 119ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS], 120ef305e54SJens Wiklander const struct utee_params *up) 121e86f1266SJens Wiklander { 122e86f1266SJens Wiklander size_t n; 123e86f1266SJens Wiklander uint32_t types = up->types; 124e86f1266SJens Wiklander 125e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 126e86f1266SJens Wiklander uintptr_t a = up->vals[n * 2]; 127e86f1266SJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 128e86f1266SJens Wiklander 129e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 130e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 131e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 132e86f1266SJens Wiklander params[n].value.a = a; 133e86f1266SJens Wiklander params[n].value.b = b; 134e86f1266SJens Wiklander break; 135e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 136e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 137ef305e54SJens Wiklander if (tmp_va[n]) 138ef305e54SJens Wiklander memcpy(params[n].memref.buffer, tmp_va[n], 139ef305e54SJens Wiklander MIN(b, params[n].memref.size)); 140e86f1266SJens Wiklander params[n].memref.size = b; 141e86f1266SJens Wiklander break; 142e86f1266SJens Wiklander default: 143e86f1266SJens Wiklander break; 144e86f1266SJens Wiklander } 145e86f1266SJens Wiklander } 146e86f1266SJens Wiklander } 147e86f1266SJens Wiklander 148b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination, 149b0104773SPascal Brand uint32_t cancellationRequestTimeout, 15068540524SIgor Opaniuk uint32_t paramTypes, 15168540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 152b0104773SPascal Brand TEE_TASessionHandle *session, 153b0104773SPascal Brand uint32_t *returnOrigin) 154b0104773SPascal Brand { 155ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 156e86f1266SJens Wiklander struct utee_params up; 157ef305e54SJens Wiklander uint32_t s = 0; 158ef305e54SJens Wiklander void *tmp_buf = NULL; 159ef305e54SJens Wiklander size_t tmp_len = 0; 160ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 161b0104773SPascal Brand 1626915bbbbSJens Wiklander if (paramTypes) 1636915bbbbSJens Wiklander __utee_check_inout_annotation(params, 1646915bbbbSJens Wiklander sizeof(TEE_Param) * 1656915bbbbSJens Wiklander TEE_NUM_PARAMS); 1666915bbbbSJens Wiklander __utee_check_out_annotation(session, sizeof(*session)); 1676915bbbbSJens Wiklander 168ef305e54SJens Wiklander res = copy_param(&up, paramTypes, params, &tmp_buf, &tmp_len, tmp_va); 169ef305e54SJens Wiklander if (res) 170ef305e54SJens Wiklander goto out; 1712c028fdeSJerome Forissier res = _utee_open_ta_session(destination, cancellationRequestTimeout, 172e86f1266SJens Wiklander &up, &s, returnOrigin); 173ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 174ef305e54SJens Wiklander if (tmp_buf) { 175ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 176ef305e54SJens Wiklander 177ef305e54SJens Wiklander if (res2) 178ef305e54SJens Wiklander TEE_Panic(res2); 179ef305e54SJens Wiklander } 180ef305e54SJens Wiklander 181ef305e54SJens Wiklander out: 182b0104773SPascal Brand /* 183b0104773SPascal Brand * Specification says that *session must hold TEE_HANDLE_NULL is 184b0104773SPascal Brand * TEE_SUCCESS isn't returned. Set it here explicitly in case 185b0104773SPascal Brand * the syscall fails before out parameters has been updated. 186b0104773SPascal Brand */ 187b0104773SPascal Brand if (res != TEE_SUCCESS) 188e86f1266SJens Wiklander s = TEE_HANDLE_NULL; 189b0104773SPascal Brand 190e86f1266SJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 191b0104773SPascal Brand return res; 192b0104773SPascal Brand } 193b0104773SPascal Brand 194b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session) 195b0104773SPascal Brand { 196b0104773SPascal Brand if (session != TEE_HANDLE_NULL) { 1972c028fdeSJerome Forissier TEE_Result res = _utee_close_ta_session((uintptr_t)session); 198e86f1266SJens Wiklander 199b0104773SPascal Brand if (res != TEE_SUCCESS) 200b0104773SPascal Brand TEE_Panic(res); 201b0104773SPascal Brand } 202b0104773SPascal Brand } 203b0104773SPascal Brand 204b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, 205b0104773SPascal Brand uint32_t cancellationRequestTimeout, 206b0104773SPascal Brand uint32_t commandID, uint32_t paramTypes, 20768540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 20868540524SIgor Opaniuk uint32_t *returnOrigin) 209b0104773SPascal Brand { 210ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 211ef305e54SJens Wiklander uint32_t ret_origin = TEE_ORIGIN_TEE; 212e86f1266SJens Wiklander struct utee_params up; 213ef305e54SJens Wiklander void *tmp_buf = NULL; 214ef305e54SJens Wiklander size_t tmp_len = 0; 215ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 216c15e5835SCedric Chaumont 2176915bbbbSJens Wiklander if (paramTypes) 2186915bbbbSJens Wiklander __utee_check_inout_annotation(params, 2196915bbbbSJens Wiklander sizeof(TEE_Param) * 2206915bbbbSJens Wiklander TEE_NUM_PARAMS); 2216915bbbbSJens Wiklander if (returnOrigin) 2226915bbbbSJens Wiklander __utee_check_out_annotation(returnOrigin, 2236915bbbbSJens Wiklander sizeof(*returnOrigin)); 2246915bbbbSJens Wiklander 225ef305e54SJens Wiklander res = copy_param(&up, paramTypes, params, &tmp_buf, &tmp_len, tmp_va); 226ef305e54SJens Wiklander if (res) 227ef305e54SJens Wiklander goto out; 2282c028fdeSJerome Forissier res = _utee_invoke_ta_command((uintptr_t)session, 229e86f1266SJens Wiklander cancellationRequestTimeout, 230e86f1266SJens Wiklander commandID, &up, &ret_origin); 231ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 232ef305e54SJens Wiklander if (tmp_buf) { 233ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 2346709c3eaSCedric Chaumont 235ef305e54SJens Wiklander if (res2) 236ef305e54SJens Wiklander TEE_Panic(res2); 237ef305e54SJens Wiklander } 238ef305e54SJens Wiklander 239ef305e54SJens Wiklander out: 2406709c3eaSCedric Chaumont if (returnOrigin != NULL) 2416709c3eaSCedric Chaumont *returnOrigin = ret_origin; 2426709c3eaSCedric Chaumont 2436709c3eaSCedric Chaumont if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 2446709c3eaSCedric Chaumont return res; 2456709c3eaSCedric Chaumont 246c15e5835SCedric Chaumont if (res != TEE_SUCCESS && 247c15e5835SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 248c15e5835SCedric Chaumont res != TEE_ERROR_TARGET_DEAD) 249c15e5835SCedric Chaumont TEE_Panic(res); 250c15e5835SCedric Chaumont 251c15e5835SCedric Chaumont return res; 252b0104773SPascal Brand } 253b0104773SPascal Brand 254b0104773SPascal Brand /* System API - Cancellations */ 255b0104773SPascal Brand 256b0104773SPascal Brand bool TEE_GetCancellationFlag(void) 257b0104773SPascal Brand { 258e86f1266SJens Wiklander uint32_t c; 2592c028fdeSJerome Forissier TEE_Result res = _utee_get_cancellation_flag(&c); 260e86f1266SJens Wiklander 261b0104773SPascal Brand if (res != TEE_SUCCESS) 262e86f1266SJens Wiklander c = 0; 263e86f1266SJens Wiklander return !!c; 264b0104773SPascal Brand } 265b0104773SPascal Brand 266b0104773SPascal Brand bool TEE_UnmaskCancellation(void) 267b0104773SPascal Brand { 268e86f1266SJens Wiklander uint32_t old_mask; 2692c028fdeSJerome Forissier TEE_Result res = _utee_unmask_cancellation(&old_mask); 270b0104773SPascal Brand 271b0104773SPascal Brand if (res != TEE_SUCCESS) 272b0104773SPascal Brand TEE_Panic(res); 273e86f1266SJens Wiklander return !!old_mask; 274b0104773SPascal Brand } 275b0104773SPascal Brand 276b0104773SPascal Brand bool TEE_MaskCancellation(void) 277b0104773SPascal Brand { 278e86f1266SJens Wiklander uint32_t old_mask; 2792c028fdeSJerome Forissier TEE_Result res = _utee_mask_cancellation(&old_mask); 280b0104773SPascal Brand 281b0104773SPascal Brand if (res != TEE_SUCCESS) 282b0104773SPascal Brand TEE_Panic(res); 283e86f1266SJens Wiklander return !!old_mask; 284b0104773SPascal Brand } 285b0104773SPascal Brand 286b0104773SPascal Brand /* System API - Memory Management */ 287b0104773SPascal Brand 288b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer, 28979a3c601SCedric Chaumont uint32_t size) 290b0104773SPascal Brand { 291b0104773SPascal Brand TEE_Result res; 292b0104773SPascal Brand 293b0104773SPascal Brand if (size == 0) 294b0104773SPascal Brand return TEE_SUCCESS; 295b0104773SPascal Brand 296b0104773SPascal Brand /* Check access rights against memory mapping */ 2972c028fdeSJerome Forissier res = _utee_check_access_rights(accessFlags, buffer, size); 298b0104773SPascal Brand if (res != TEE_SUCCESS) 299b0104773SPascal Brand goto out; 300b0104773SPascal Brand 301b0104773SPascal Brand /* 302b0104773SPascal Brand * Check access rights against input parameters 303b0104773SPascal Brand * Previous legacy code was removed and will need to be restored 304b0104773SPascal Brand */ 305b0104773SPascal Brand 306b0104773SPascal Brand res = TEE_SUCCESS; 307b0104773SPascal Brand out: 308b0104773SPascal Brand return res; 309b0104773SPascal Brand } 310b0104773SPascal Brand 3118f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData) 312b0104773SPascal Brand { 313b0104773SPascal Brand tee_api_instance_data = instanceData; 314b0104773SPascal Brand } 315b0104773SPascal Brand 3168f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void) 317b0104773SPascal Brand { 318b0104773SPascal Brand return tee_api_instance_data; 319b0104773SPascal Brand } 320b0104773SPascal Brand 321b0104773SPascal Brand void *TEE_MemMove(void *dest, const void *src, uint32_t size) 322b0104773SPascal Brand { 323b0104773SPascal Brand return memmove(dest, src, size); 324b0104773SPascal Brand } 325b0104773SPascal Brand 326b0104773SPascal Brand int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size) 327b0104773SPascal Brand { 32865551e69SJerome Forissier return consttime_memcmp(buffer1, buffer2, size); 329b0104773SPascal Brand } 330b0104773SPascal Brand 331*32c75600SJens Wiklander void TEE_MemFill(void *buff, uint32_t x, uint32_t size) 332b0104773SPascal Brand { 333*32c75600SJens Wiklander memset(buff, x, size); 334b0104773SPascal Brand } 335b0104773SPascal Brand 336b0104773SPascal Brand /* Date & Time API */ 337b0104773SPascal Brand 338b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time) 339b0104773SPascal Brand { 3402c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time); 341b0104773SPascal Brand 342b0104773SPascal Brand if (res != TEE_SUCCESS) 343b36311adSJerome Forissier TEE_Panic(res); 344b0104773SPascal Brand } 345b0104773SPascal Brand 346b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout) 347b0104773SPascal Brand { 3482c028fdeSJerome Forissier TEE_Result res = _utee_wait(timeout); 349b0104773SPascal Brand 350b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL) 351b0104773SPascal Brand TEE_Panic(res); 352b0104773SPascal Brand 353b0104773SPascal Brand return res; 354b0104773SPascal Brand } 355b0104773SPascal Brand 356b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time) 357b0104773SPascal Brand { 358b64d6909SCedric Chaumont TEE_Result res; 359b64d6909SCedric Chaumont 3602c028fdeSJerome Forissier res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time); 361b64d6909SCedric Chaumont 362b64d6909SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) { 363b64d6909SCedric Chaumont time->seconds = 0; 364b64d6909SCedric Chaumont time->millis = 0; 365b64d6909SCedric Chaumont } 366b64d6909SCedric Chaumont 367b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 368b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NOT_SET && 369b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NEEDS_RESET && 370b64d6909SCedric Chaumont res != TEE_ERROR_OVERFLOW && 371b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY) 372b64d6909SCedric Chaumont TEE_Panic(res); 373b64d6909SCedric Chaumont 374b64d6909SCedric Chaumont return res; 375b0104773SPascal Brand } 376b0104773SPascal Brand 377b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time) 378b0104773SPascal Brand { 379b64d6909SCedric Chaumont TEE_Result res; 380b64d6909SCedric Chaumont 3812c028fdeSJerome Forissier res = _utee_set_ta_time(time); 382b64d6909SCedric Chaumont 383b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 384b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 385b64d6909SCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE) 386b64d6909SCedric Chaumont TEE_Panic(res); 387b64d6909SCedric Chaumont 388b64d6909SCedric Chaumont return res; 389b0104773SPascal Brand } 390b0104773SPascal Brand 391b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time) 392b0104773SPascal Brand { 3932c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time); 394b0104773SPascal Brand 395b0104773SPascal Brand if (res != TEE_SUCCESS) 396b36311adSJerome Forissier TEE_Panic(res); 397b0104773SPascal Brand } 398b0104773SPascal Brand 39979a3c601SCedric Chaumont void *TEE_Malloc(uint32_t len, uint32_t hint) 400b0104773SPascal Brand { 401a83ee50aSSadiq Hussain if (!len) 402a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 403a83ee50aSSadiq Hussain 40496c1d8c5SJens Wiklander if (hint == TEE_MALLOC_FILL_ZERO) 40596c1d8c5SJens Wiklander return calloc(1, len); 40696c1d8c5SJens Wiklander else if (hint == TEE_USER_MEM_HINT_NO_FILL_ZERO) 40796c1d8c5SJens Wiklander return malloc(len); 40896c1d8c5SJens Wiklander 40996c1d8c5SJens Wiklander EMSG("Invalid hint %#" PRIx32, hint); 41096c1d8c5SJens Wiklander 41196c1d8c5SJens Wiklander return NULL; 412b0104773SPascal Brand } 413b0104773SPascal Brand 414c0ce02edSJens Wiklander void *TEE_Realloc(void *buffer, uint32_t newSize) 415b0104773SPascal Brand { 416a83ee50aSSadiq Hussain if (!newSize) { 417a83ee50aSSadiq Hussain TEE_Free(buffer); 418a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 419a83ee50aSSadiq Hussain } 420a83ee50aSSadiq Hussain 421a83ee50aSSadiq Hussain if (buffer == TEE_NULL_SIZED_VA) 422a83ee50aSSadiq Hussain return calloc(1, newSize); 423a83ee50aSSadiq Hussain 42496c1d8c5SJens Wiklander return realloc(buffer, newSize); 425b0104773SPascal Brand } 426b0104773SPascal Brand 427b0104773SPascal Brand void TEE_Free(void *buffer) 428b0104773SPascal Brand { 429a83ee50aSSadiq Hussain if (buffer != TEE_NULL_SIZED_VA) 43096c1d8c5SJens Wiklander free(buffer); 431b0104773SPascal Brand } 432fa530828SPascal Brand 433fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ 434fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len) 435fa530828SPascal Brand { 4362c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHECLEAN); 437fa530828SPascal Brand } 438fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len) 439fa530828SPascal Brand { 4402c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEFLUSH); 441fa530828SPascal Brand } 442fa530828SPascal Brand 443fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len) 444fa530828SPascal Brand { 4452c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); 446fa530828SPascal Brand } 447