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 158f07fe6fSJerome Forissier static const void *tee_api_instance_data; 16b0104773SPascal Brand 17b0104773SPascal Brand /* System API - Internal Client API */ 18b0104773SPascal Brand 19ef305e54SJens Wiklander static TEE_Result copy_param(struct utee_params *up, uint32_t param_types, 20ef305e54SJens Wiklander const TEE_Param params[TEE_NUM_PARAMS], 21ef305e54SJens Wiklander void **tmp_buf, size_t *tmp_len, 22ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS]) 23e86f1266SJens Wiklander { 24ef305e54SJens Wiklander size_t n = 0; 25ef305e54SJens Wiklander uint8_t *tb = NULL; 26ef305e54SJens Wiklander size_t tbl = 0; 27ef305e54SJens Wiklander size_t tmp_align = sizeof(vaddr_t) * 2; 28ef305e54SJens Wiklander bool is_tmp_mem[TEE_NUM_PARAMS] = { false }; 29ef305e54SJens Wiklander void *b = NULL; 30ef305e54SJens Wiklander size_t s = 0; 31ef305e54SJens Wiklander const uint32_t flags = TEE_MEMORY_ACCESS_READ; 32ef305e54SJens Wiklander 33ef305e54SJens Wiklander /* 34ef305e54SJens Wiklander * If a memory parameter points to TA private memory we need to 35ef305e54SJens Wiklander * allocate a temporary buffer to avoid exposing the memory 36ef305e54SJens Wiklander * directly to the called TA. 37ef305e54SJens Wiklander */ 38ef305e54SJens Wiklander 39ef305e54SJens Wiklander *tmp_buf = NULL; 40ef305e54SJens Wiklander *tmp_len = 0; 41ef305e54SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 42ef305e54SJens Wiklander tmp_va[n] = NULL; 43ef305e54SJens Wiklander switch (TEE_PARAM_TYPE_GET(param_types, n)) { 44ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 45ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 46ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 47ef305e54SJens Wiklander b = params[n].memref.buffer; 48ef305e54SJens Wiklander s = params[n].memref.size; 49ef305e54SJens Wiklander /* 50ef305e54SJens Wiklander * We're only allocating temporary memory if the 51ef305e54SJens Wiklander * buffer is completely within TA memory. If it's 52ef305e54SJens Wiklander * NULL, empty, partially outside or completely 53ef305e54SJens Wiklander * outside TA memory there's nothing more we need 54ef305e54SJens Wiklander * to do here. If there's security/permissions 55ef305e54SJens Wiklander * problem we'll get an error in the 56ef305e54SJens Wiklander * invoke_command/open_session below. 57ef305e54SJens Wiklander */ 58ef305e54SJens Wiklander if (b && s && 59ef305e54SJens Wiklander !TEE_CheckMemoryAccessRights(flags, b, s)) { 60ef305e54SJens Wiklander is_tmp_mem[n] = true; 61ef305e54SJens Wiklander tbl += ROUNDUP(s, tmp_align); 62ef305e54SJens Wiklander } 63ef305e54SJens Wiklander break; 64ef305e54SJens Wiklander default: 65ef305e54SJens Wiklander break; 66ef305e54SJens Wiklander } 67ef305e54SJens Wiklander } 68ef305e54SJens Wiklander 69ef305e54SJens Wiklander if (tbl) { 70ef305e54SJens Wiklander tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER); 71ef305e54SJens Wiklander if (!tb) 72ef305e54SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 73ef305e54SJens Wiklander *tmp_buf = tb; 74ef305e54SJens Wiklander *tmp_len = tbl; 75ef305e54SJens Wiklander } 76e86f1266SJens Wiklander 77e86f1266SJens Wiklander up->types = param_types; 78e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 79e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(param_types, n)) { 80e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 81e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 82e86f1266SJens Wiklander up->vals[n * 2] = params[n].value.a; 83e86f1266SJens Wiklander up->vals[n * 2 + 1] = params[n].value.b; 84e86f1266SJens Wiklander break; 85e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 86e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 87ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 88ef305e54SJens Wiklander s = params[n].memref.size; 89ef305e54SJens Wiklander if (is_tmp_mem[n]) { 90ef305e54SJens Wiklander b = tb; 91ef305e54SJens Wiklander tmp_va[n] = tb; 92ef305e54SJens Wiklander tb += ROUNDUP(s, tmp_align); 93ef305e54SJens Wiklander if (TEE_PARAM_TYPE_GET(param_types, n) != 94ef305e54SJens Wiklander TEE_PARAM_TYPE_MEMREF_OUTPUT) 95ef305e54SJens Wiklander memcpy(b, params[n].memref.buffer, s); 96ef305e54SJens Wiklander } else { 97ef305e54SJens Wiklander b = params[n].memref.buffer; 98ef305e54SJens Wiklander } 99ef305e54SJens Wiklander up->vals[n * 2] = (vaddr_t)b; 100ef305e54SJens Wiklander up->vals[n * 2 + 1] = s; 101e86f1266SJens Wiklander break; 102e86f1266SJens Wiklander default: 103e86f1266SJens Wiklander up->vals[n * 2] = 0; 104e86f1266SJens Wiklander up->vals[n * 2 + 1] = 0; 105e86f1266SJens Wiklander break; 106e86f1266SJens Wiklander } 107e86f1266SJens Wiklander } 108ef305e54SJens Wiklander 109ef305e54SJens Wiklander return TEE_SUCCESS; 110e86f1266SJens Wiklander } 111e86f1266SJens Wiklander 112ef305e54SJens Wiklander static void update_out_param(TEE_Param params[TEE_NUM_PARAMS], 113ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS], 114ef305e54SJens Wiklander const struct utee_params *up) 115e86f1266SJens Wiklander { 116e86f1266SJens Wiklander size_t n; 117e86f1266SJens Wiklander uint32_t types = up->types; 118e86f1266SJens Wiklander 119e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 120e86f1266SJens Wiklander uintptr_t a = up->vals[n * 2]; 121e86f1266SJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 122e86f1266SJens Wiklander 123e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 124e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 125e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 126e86f1266SJens Wiklander params[n].value.a = a; 127e86f1266SJens Wiklander params[n].value.b = b; 128e86f1266SJens Wiklander break; 129e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 130e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 131ef305e54SJens Wiklander if (tmp_va[n]) 132ef305e54SJens Wiklander memcpy(params[n].memref.buffer, tmp_va[n], 133ef305e54SJens Wiklander MIN(b, params[n].memref.size)); 134e86f1266SJens Wiklander params[n].memref.size = b; 135e86f1266SJens Wiklander break; 136e86f1266SJens Wiklander default: 137e86f1266SJens Wiklander break; 138e86f1266SJens Wiklander } 139e86f1266SJens Wiklander } 140e86f1266SJens Wiklander } 141e86f1266SJens Wiklander 142b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination, 143b0104773SPascal Brand uint32_t cancellationRequestTimeout, 14468540524SIgor Opaniuk uint32_t paramTypes, 14568540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 146b0104773SPascal Brand TEE_TASessionHandle *session, 147b0104773SPascal Brand uint32_t *returnOrigin) 148b0104773SPascal Brand { 149ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 150e86f1266SJens Wiklander struct utee_params up; 151ef305e54SJens Wiklander uint32_t s = 0; 152ef305e54SJens Wiklander void *tmp_buf = NULL; 153ef305e54SJens Wiklander size_t tmp_len = 0; 154ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 155b0104773SPascal Brand 156ef305e54SJens Wiklander res = copy_param(&up, paramTypes, params, &tmp_buf, &tmp_len, tmp_va); 157ef305e54SJens Wiklander if (res) 158ef305e54SJens Wiklander goto out; 159*2c028fdeSJerome Forissier res = _utee_open_ta_session(destination, cancellationRequestTimeout, 160e86f1266SJens Wiklander &up, &s, returnOrigin); 161ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 162ef305e54SJens Wiklander if (tmp_buf) { 163ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 164ef305e54SJens Wiklander 165ef305e54SJens Wiklander if (res2) 166ef305e54SJens Wiklander TEE_Panic(res2); 167ef305e54SJens Wiklander } 168ef305e54SJens Wiklander 169ef305e54SJens Wiklander out: 170b0104773SPascal Brand /* 171b0104773SPascal Brand * Specification says that *session must hold TEE_HANDLE_NULL is 172b0104773SPascal Brand * TEE_SUCCESS isn't returned. Set it here explicitly in case 173b0104773SPascal Brand * the syscall fails before out parameters has been updated. 174b0104773SPascal Brand */ 175b0104773SPascal Brand if (res != TEE_SUCCESS) 176e86f1266SJens Wiklander s = TEE_HANDLE_NULL; 177b0104773SPascal Brand 178e86f1266SJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 179b0104773SPascal Brand return res; 180b0104773SPascal Brand } 181b0104773SPascal Brand 182b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session) 183b0104773SPascal Brand { 184b0104773SPascal Brand if (session != TEE_HANDLE_NULL) { 185*2c028fdeSJerome Forissier TEE_Result res = _utee_close_ta_session((uintptr_t)session); 186e86f1266SJens Wiklander 187b0104773SPascal Brand if (res != TEE_SUCCESS) 188b0104773SPascal Brand TEE_Panic(res); 189b0104773SPascal Brand } 190b0104773SPascal Brand } 191b0104773SPascal Brand 192b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, 193b0104773SPascal Brand uint32_t cancellationRequestTimeout, 194b0104773SPascal Brand uint32_t commandID, uint32_t paramTypes, 19568540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 19668540524SIgor Opaniuk uint32_t *returnOrigin) 197b0104773SPascal Brand { 198ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 199ef305e54SJens Wiklander uint32_t ret_origin = TEE_ORIGIN_TEE; 200e86f1266SJens Wiklander struct utee_params up; 201ef305e54SJens Wiklander void *tmp_buf = NULL; 202ef305e54SJens Wiklander size_t tmp_len = 0; 203ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 204c15e5835SCedric Chaumont 205ef305e54SJens Wiklander res = copy_param(&up, paramTypes, params, &tmp_buf, &tmp_len, tmp_va); 206ef305e54SJens Wiklander if (res) 207ef305e54SJens Wiklander goto out; 208*2c028fdeSJerome Forissier res = _utee_invoke_ta_command((uintptr_t)session, 209e86f1266SJens Wiklander cancellationRequestTimeout, 210e86f1266SJens Wiklander commandID, &up, &ret_origin); 211ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 212ef305e54SJens Wiklander if (tmp_buf) { 213ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 2146709c3eaSCedric Chaumont 215ef305e54SJens Wiklander if (res2) 216ef305e54SJens Wiklander TEE_Panic(res2); 217ef305e54SJens Wiklander } 218ef305e54SJens Wiklander 219ef305e54SJens Wiklander out: 2206709c3eaSCedric Chaumont if (returnOrigin != NULL) 2216709c3eaSCedric Chaumont *returnOrigin = ret_origin; 2226709c3eaSCedric Chaumont 2236709c3eaSCedric Chaumont if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 2246709c3eaSCedric Chaumont return res; 2256709c3eaSCedric Chaumont 226c15e5835SCedric Chaumont if (res != TEE_SUCCESS && 227c15e5835SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 228c15e5835SCedric Chaumont res != TEE_ERROR_TARGET_DEAD) 229c15e5835SCedric Chaumont TEE_Panic(res); 230c15e5835SCedric Chaumont 231c15e5835SCedric Chaumont return res; 232b0104773SPascal Brand } 233b0104773SPascal Brand 234b0104773SPascal Brand /* System API - Cancellations */ 235b0104773SPascal Brand 236b0104773SPascal Brand bool TEE_GetCancellationFlag(void) 237b0104773SPascal Brand { 238e86f1266SJens Wiklander uint32_t c; 239*2c028fdeSJerome Forissier TEE_Result res = _utee_get_cancellation_flag(&c); 240e86f1266SJens Wiklander 241b0104773SPascal Brand if (res != TEE_SUCCESS) 242e86f1266SJens Wiklander c = 0; 243e86f1266SJens Wiklander return !!c; 244b0104773SPascal Brand } 245b0104773SPascal Brand 246b0104773SPascal Brand bool TEE_UnmaskCancellation(void) 247b0104773SPascal Brand { 248e86f1266SJens Wiklander uint32_t old_mask; 249*2c028fdeSJerome Forissier TEE_Result res = _utee_unmask_cancellation(&old_mask); 250b0104773SPascal Brand 251b0104773SPascal Brand if (res != TEE_SUCCESS) 252b0104773SPascal Brand TEE_Panic(res); 253e86f1266SJens Wiklander return !!old_mask; 254b0104773SPascal Brand } 255b0104773SPascal Brand 256b0104773SPascal Brand bool TEE_MaskCancellation(void) 257b0104773SPascal Brand { 258e86f1266SJens Wiklander uint32_t old_mask; 259*2c028fdeSJerome Forissier TEE_Result res = _utee_mask_cancellation(&old_mask); 260b0104773SPascal Brand 261b0104773SPascal Brand if (res != TEE_SUCCESS) 262b0104773SPascal Brand TEE_Panic(res); 263e86f1266SJens Wiklander return !!old_mask; 264b0104773SPascal Brand } 265b0104773SPascal Brand 266b0104773SPascal Brand /* System API - Memory Management */ 267b0104773SPascal Brand 268b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer, 26979a3c601SCedric Chaumont uint32_t size) 270b0104773SPascal Brand { 271b0104773SPascal Brand TEE_Result res; 272b0104773SPascal Brand 273b0104773SPascal Brand if (size == 0) 274b0104773SPascal Brand return TEE_SUCCESS; 275b0104773SPascal Brand 276b0104773SPascal Brand /* Check access rights against memory mapping */ 277*2c028fdeSJerome Forissier res = _utee_check_access_rights(accessFlags, buffer, size); 278b0104773SPascal Brand if (res != TEE_SUCCESS) 279b0104773SPascal Brand goto out; 280b0104773SPascal Brand 281b0104773SPascal Brand /* 282b0104773SPascal Brand * Check access rights against input parameters 283b0104773SPascal Brand * Previous legacy code was removed and will need to be restored 284b0104773SPascal Brand */ 285b0104773SPascal Brand 286b0104773SPascal Brand res = TEE_SUCCESS; 287b0104773SPascal Brand out: 288b0104773SPascal Brand return res; 289b0104773SPascal Brand } 290b0104773SPascal Brand 2918f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData) 292b0104773SPascal Brand { 293b0104773SPascal Brand tee_api_instance_data = instanceData; 294b0104773SPascal Brand } 295b0104773SPascal Brand 2968f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void) 297b0104773SPascal Brand { 298b0104773SPascal Brand return tee_api_instance_data; 299b0104773SPascal Brand } 300b0104773SPascal Brand 301b0104773SPascal Brand void *TEE_MemMove(void *dest, const void *src, uint32_t size) 302b0104773SPascal Brand { 303b0104773SPascal Brand return memmove(dest, src, size); 304b0104773SPascal Brand } 305b0104773SPascal Brand 306b0104773SPascal Brand int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size) 307b0104773SPascal Brand { 30865551e69SJerome Forissier return consttime_memcmp(buffer1, buffer2, size); 309b0104773SPascal Brand } 310b0104773SPascal Brand 311b0104773SPascal Brand void *TEE_MemFill(void *buff, uint32_t x, uint32_t size) 312b0104773SPascal Brand { 313b0104773SPascal Brand return memset(buff, x, size); 314b0104773SPascal Brand } 315b0104773SPascal Brand 316b0104773SPascal Brand /* Date & Time API */ 317b0104773SPascal Brand 318b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time) 319b0104773SPascal Brand { 320*2c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time); 321b0104773SPascal Brand 322b0104773SPascal Brand if (res != TEE_SUCCESS) 323b36311adSJerome Forissier TEE_Panic(res); 324b0104773SPascal Brand } 325b0104773SPascal Brand 326b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout) 327b0104773SPascal Brand { 328*2c028fdeSJerome Forissier TEE_Result res = _utee_wait(timeout); 329b0104773SPascal Brand 330b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL) 331b0104773SPascal Brand TEE_Panic(res); 332b0104773SPascal Brand 333b0104773SPascal Brand return res; 334b0104773SPascal Brand } 335b0104773SPascal Brand 336b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time) 337b0104773SPascal Brand { 338b64d6909SCedric Chaumont TEE_Result res; 339b64d6909SCedric Chaumont 340*2c028fdeSJerome Forissier res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time); 341b64d6909SCedric Chaumont 342b64d6909SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) { 343b64d6909SCedric Chaumont time->seconds = 0; 344b64d6909SCedric Chaumont time->millis = 0; 345b64d6909SCedric Chaumont } 346b64d6909SCedric Chaumont 347b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 348b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NOT_SET && 349b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NEEDS_RESET && 350b64d6909SCedric Chaumont res != TEE_ERROR_OVERFLOW && 351b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY) 352b64d6909SCedric Chaumont TEE_Panic(res); 353b64d6909SCedric Chaumont 354b64d6909SCedric Chaumont return res; 355b0104773SPascal Brand } 356b0104773SPascal Brand 357b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time) 358b0104773SPascal Brand { 359b64d6909SCedric Chaumont TEE_Result res; 360b64d6909SCedric Chaumont 361*2c028fdeSJerome Forissier res = _utee_set_ta_time(time); 362b64d6909SCedric Chaumont 363b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 364b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 365b64d6909SCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE) 366b64d6909SCedric Chaumont TEE_Panic(res); 367b64d6909SCedric Chaumont 368b64d6909SCedric Chaumont return res; 369b0104773SPascal Brand } 370b0104773SPascal Brand 371b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time) 372b0104773SPascal Brand { 373*2c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time); 374b0104773SPascal Brand 375b0104773SPascal Brand if (res != TEE_SUCCESS) 376b36311adSJerome Forissier TEE_Panic(res); 377b0104773SPascal Brand } 378b0104773SPascal Brand 37979a3c601SCedric Chaumont void *TEE_Malloc(uint32_t len, uint32_t hint) 380b0104773SPascal Brand { 38196c1d8c5SJens Wiklander if (hint == TEE_MALLOC_FILL_ZERO) 38296c1d8c5SJens Wiklander return calloc(1, len); 38396c1d8c5SJens Wiklander else if (hint == TEE_USER_MEM_HINT_NO_FILL_ZERO) 38496c1d8c5SJens Wiklander return malloc(len); 38596c1d8c5SJens Wiklander 38696c1d8c5SJens Wiklander EMSG("Invalid hint %#" PRIx32, hint); 38796c1d8c5SJens Wiklander 38896c1d8c5SJens Wiklander return NULL; 389b0104773SPascal Brand } 390b0104773SPascal Brand 391c0ce02edSJens Wiklander void *TEE_Realloc(void *buffer, uint32_t newSize) 392b0104773SPascal Brand { 39396c1d8c5SJens Wiklander return realloc(buffer, newSize); 394b0104773SPascal Brand } 395b0104773SPascal Brand 396b0104773SPascal Brand void TEE_Free(void *buffer) 397b0104773SPascal Brand { 39896c1d8c5SJens Wiklander free(buffer); 399b0104773SPascal Brand } 400fa530828SPascal Brand 401fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ 402fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len) 403fa530828SPascal Brand { 404*2c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHECLEAN); 405fa530828SPascal Brand } 406fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len) 407fa530828SPascal Brand { 408*2c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEFLUSH); 409fa530828SPascal Brand } 410fa530828SPascal Brand 411fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len) 412fa530828SPascal Brand { 413*2c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); 414fa530828SPascal Brand } 415