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> 7*65551e69SJerome Forissier #include <string_ext.h> 8b0104773SPascal Brand 9b0104773SPascal Brand #include <tee_api.h> 1096c1d8c5SJens Wiklander #include <tee_internal_api_extensions.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 19e86f1266SJens Wiklander void __utee_from_param(struct utee_params *up, uint32_t param_types, 20e86f1266SJens Wiklander const TEE_Param params[TEE_NUM_PARAMS]) 21e86f1266SJens Wiklander { 22e86f1266SJens Wiklander size_t n; 23e86f1266SJens Wiklander 24e86f1266SJens Wiklander up->types = param_types; 25e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 26e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(param_types, n)) { 27e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 28e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 29e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 30e86f1266SJens Wiklander up->vals[n * 2] = params[n].value.a; 31e86f1266SJens Wiklander up->vals[n * 2 + 1] = params[n].value.b; 32e86f1266SJens Wiklander break; 33e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 34e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 35e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 36e86f1266SJens Wiklander up->vals[n * 2] = (uintptr_t)params[n].memref.buffer; 37e86f1266SJens Wiklander up->vals[n * 2 + 1] = params[n].memref.size; 38e86f1266SJens Wiklander break; 39e86f1266SJens Wiklander default: 40e86f1266SJens Wiklander up->vals[n * 2] = 0; 41e86f1266SJens Wiklander up->vals[n * 2 + 1] = 0; 42e86f1266SJens Wiklander break; 43e86f1266SJens Wiklander } 44e86f1266SJens Wiklander } 45e86f1266SJens Wiklander } 46e86f1266SJens Wiklander 47e86f1266SJens Wiklander void __utee_to_param(TEE_Param params[TEE_NUM_PARAMS], 48e86f1266SJens Wiklander uint32_t *param_types, const struct utee_params *up) 49e86f1266SJens Wiklander { 50e86f1266SJens Wiklander size_t n; 51e86f1266SJens Wiklander uint32_t types = up->types; 52e86f1266SJens Wiklander 53e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 54e86f1266SJens Wiklander uintptr_t a = up->vals[n * 2]; 55e86f1266SJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 56e86f1266SJens Wiklander 57e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 58e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 59e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 60e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 61e86f1266SJens Wiklander params[n].value.a = a; 62e86f1266SJens Wiklander params[n].value.b = b; 63e86f1266SJens Wiklander break; 64e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 65e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 66e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 67e86f1266SJens Wiklander params[n].memref.buffer = (void *)a; 68e86f1266SJens Wiklander params[n].memref.size = b; 69e86f1266SJens Wiklander break; 70e86f1266SJens Wiklander default: 71e86f1266SJens Wiklander break; 72e86f1266SJens Wiklander } 73e86f1266SJens Wiklander } 74e86f1266SJens Wiklander 75e86f1266SJens Wiklander if (param_types) 76e86f1266SJens Wiklander *param_types = types; 77e86f1266SJens Wiklander } 78e86f1266SJens Wiklander 79b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination, 80b0104773SPascal Brand uint32_t cancellationRequestTimeout, 8168540524SIgor Opaniuk uint32_t paramTypes, 8268540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 83b0104773SPascal Brand TEE_TASessionHandle *session, 84b0104773SPascal Brand uint32_t *returnOrigin) 85b0104773SPascal Brand { 86b0104773SPascal Brand TEE_Result res; 87e86f1266SJens Wiklander struct utee_params up; 88e86f1266SJens Wiklander uint32_t s; 89b0104773SPascal Brand 90e86f1266SJens Wiklander __utee_from_param(&up, paramTypes, params); 91b0104773SPascal Brand res = utee_open_ta_session(destination, cancellationRequestTimeout, 92e86f1266SJens Wiklander &up, &s, returnOrigin); 93e86f1266SJens Wiklander __utee_to_param(params, NULL, &up); 94b0104773SPascal Brand /* 95b0104773SPascal Brand * Specification says that *session must hold TEE_HANDLE_NULL is 96b0104773SPascal Brand * TEE_SUCCESS isn't returned. Set it here explicitly in case 97b0104773SPascal Brand * the syscall fails before out parameters has been updated. 98b0104773SPascal Brand */ 99b0104773SPascal Brand if (res != TEE_SUCCESS) 100e86f1266SJens Wiklander s = TEE_HANDLE_NULL; 101b0104773SPascal Brand 102e86f1266SJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 103b0104773SPascal Brand return res; 104b0104773SPascal Brand } 105b0104773SPascal Brand 106b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session) 107b0104773SPascal Brand { 108b0104773SPascal Brand if (session != TEE_HANDLE_NULL) { 109e86f1266SJens Wiklander TEE_Result res = utee_close_ta_session((uintptr_t)session); 110e86f1266SJens Wiklander 111b0104773SPascal Brand if (res != TEE_SUCCESS) 112b0104773SPascal Brand TEE_Panic(res); 113b0104773SPascal Brand } 114b0104773SPascal Brand } 115b0104773SPascal Brand 116b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, 117b0104773SPascal Brand uint32_t cancellationRequestTimeout, 118b0104773SPascal Brand uint32_t commandID, uint32_t paramTypes, 11968540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 12068540524SIgor Opaniuk uint32_t *returnOrigin) 121b0104773SPascal Brand { 122c15e5835SCedric Chaumont TEE_Result res; 1236709c3eaSCedric Chaumont uint32_t ret_origin; 124e86f1266SJens Wiklander struct utee_params up; 125c15e5835SCedric Chaumont 126e86f1266SJens Wiklander __utee_from_param(&up, paramTypes, params); 127e86f1266SJens Wiklander res = utee_invoke_ta_command((uintptr_t)session, 128e86f1266SJens Wiklander cancellationRequestTimeout, 129e86f1266SJens Wiklander commandID, &up, &ret_origin); 130e86f1266SJens Wiklander __utee_to_param(params, NULL, &up); 1316709c3eaSCedric Chaumont 1326709c3eaSCedric Chaumont if (returnOrigin != NULL) 1336709c3eaSCedric Chaumont *returnOrigin = ret_origin; 1346709c3eaSCedric Chaumont 1356709c3eaSCedric Chaumont if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 1366709c3eaSCedric Chaumont return res; 1376709c3eaSCedric Chaumont 138c15e5835SCedric Chaumont if (res != TEE_SUCCESS && 139c15e5835SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 140c15e5835SCedric Chaumont res != TEE_ERROR_TARGET_DEAD) 141c15e5835SCedric Chaumont TEE_Panic(res); 142c15e5835SCedric Chaumont 143c15e5835SCedric Chaumont return res; 144b0104773SPascal Brand } 145b0104773SPascal Brand 146b0104773SPascal Brand /* System API - Cancellations */ 147b0104773SPascal Brand 148b0104773SPascal Brand bool TEE_GetCancellationFlag(void) 149b0104773SPascal Brand { 150e86f1266SJens Wiklander uint32_t c; 151b0104773SPascal Brand TEE_Result res = utee_get_cancellation_flag(&c); 152e86f1266SJens Wiklander 153b0104773SPascal Brand if (res != TEE_SUCCESS) 154e86f1266SJens Wiklander c = 0; 155e86f1266SJens Wiklander return !!c; 156b0104773SPascal Brand } 157b0104773SPascal Brand 158b0104773SPascal Brand bool TEE_UnmaskCancellation(void) 159b0104773SPascal Brand { 160e86f1266SJens Wiklander uint32_t old_mask; 161b0104773SPascal Brand TEE_Result res = utee_unmask_cancellation(&old_mask); 162b0104773SPascal Brand 163b0104773SPascal Brand if (res != TEE_SUCCESS) 164b0104773SPascal Brand TEE_Panic(res); 165e86f1266SJens Wiklander return !!old_mask; 166b0104773SPascal Brand } 167b0104773SPascal Brand 168b0104773SPascal Brand bool TEE_MaskCancellation(void) 169b0104773SPascal Brand { 170e86f1266SJens Wiklander uint32_t old_mask; 171b0104773SPascal Brand TEE_Result res = utee_mask_cancellation(&old_mask); 172b0104773SPascal Brand 173b0104773SPascal Brand if (res != TEE_SUCCESS) 174b0104773SPascal Brand TEE_Panic(res); 175e86f1266SJens Wiklander return !!old_mask; 176b0104773SPascal Brand } 177b0104773SPascal Brand 178b0104773SPascal Brand /* System API - Memory Management */ 179b0104773SPascal Brand 180b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer, 18179a3c601SCedric Chaumont uint32_t size) 182b0104773SPascal Brand { 183b0104773SPascal Brand TEE_Result res; 184b0104773SPascal Brand 185b0104773SPascal Brand if (size == 0) 186b0104773SPascal Brand return TEE_SUCCESS; 187b0104773SPascal Brand 188b0104773SPascal Brand /* Check access rights against memory mapping */ 189b0104773SPascal Brand res = utee_check_access_rights(accessFlags, buffer, size); 190b0104773SPascal Brand if (res != TEE_SUCCESS) 191b0104773SPascal Brand goto out; 192b0104773SPascal Brand 193b0104773SPascal Brand /* 194b0104773SPascal Brand * Check access rights against input parameters 195b0104773SPascal Brand * Previous legacy code was removed and will need to be restored 196b0104773SPascal Brand */ 197b0104773SPascal Brand 198b0104773SPascal Brand res = TEE_SUCCESS; 199b0104773SPascal Brand out: 200b0104773SPascal Brand return res; 201b0104773SPascal Brand } 202b0104773SPascal Brand 2038f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData) 204b0104773SPascal Brand { 205b0104773SPascal Brand tee_api_instance_data = instanceData; 206b0104773SPascal Brand } 207b0104773SPascal Brand 2088f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void) 209b0104773SPascal Brand { 210b0104773SPascal Brand return tee_api_instance_data; 211b0104773SPascal Brand } 212b0104773SPascal Brand 213b0104773SPascal Brand void *TEE_MemMove(void *dest, const void *src, uint32_t size) 214b0104773SPascal Brand { 215b0104773SPascal Brand return memmove(dest, src, size); 216b0104773SPascal Brand } 217b0104773SPascal Brand 218b0104773SPascal Brand int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size) 219b0104773SPascal Brand { 220*65551e69SJerome Forissier return consttime_memcmp(buffer1, buffer2, size); 221b0104773SPascal Brand } 222b0104773SPascal Brand 223b0104773SPascal Brand void *TEE_MemFill(void *buff, uint32_t x, uint32_t size) 224b0104773SPascal Brand { 225b0104773SPascal Brand return memset(buff, x, size); 226b0104773SPascal Brand } 227b0104773SPascal Brand 228b0104773SPascal Brand /* Date & Time API */ 229b0104773SPascal Brand 230b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time) 231b0104773SPascal Brand { 232b0104773SPascal Brand TEE_Result res = utee_get_time(UTEE_TIME_CAT_SYSTEM, time); 233b0104773SPascal Brand 234b0104773SPascal Brand if (res != TEE_SUCCESS) 235b36311adSJerome Forissier TEE_Panic(res); 236b0104773SPascal Brand } 237b0104773SPascal Brand 238b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout) 239b0104773SPascal Brand { 240b0104773SPascal Brand TEE_Result res = utee_wait(timeout); 241b0104773SPascal Brand 242b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL) 243b0104773SPascal Brand TEE_Panic(res); 244b0104773SPascal Brand 245b0104773SPascal Brand return res; 246b0104773SPascal Brand } 247b0104773SPascal Brand 248b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time) 249b0104773SPascal Brand { 250b64d6909SCedric Chaumont TEE_Result res; 251b64d6909SCedric Chaumont 252b64d6909SCedric Chaumont res = utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time); 253b64d6909SCedric Chaumont 254b64d6909SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) { 255b64d6909SCedric Chaumont time->seconds = 0; 256b64d6909SCedric Chaumont time->millis = 0; 257b64d6909SCedric Chaumont } 258b64d6909SCedric Chaumont 259b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 260b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NOT_SET && 261b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NEEDS_RESET && 262b64d6909SCedric Chaumont res != TEE_ERROR_OVERFLOW && 263b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY) 264b64d6909SCedric Chaumont TEE_Panic(res); 265b64d6909SCedric Chaumont 266b64d6909SCedric Chaumont return res; 267b0104773SPascal Brand } 268b0104773SPascal Brand 269b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time) 270b0104773SPascal Brand { 271b64d6909SCedric Chaumont TEE_Result res; 272b64d6909SCedric Chaumont 273b64d6909SCedric Chaumont res = utee_set_ta_time(time); 274b64d6909SCedric Chaumont 275b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 276b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 277b64d6909SCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE) 278b64d6909SCedric Chaumont TEE_Panic(res); 279b64d6909SCedric Chaumont 280b64d6909SCedric Chaumont return res; 281b0104773SPascal Brand } 282b0104773SPascal Brand 283b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time) 284b0104773SPascal Brand { 285b0104773SPascal Brand TEE_Result res = utee_get_time(UTEE_TIME_CAT_REE, time); 286b0104773SPascal Brand 287b0104773SPascal Brand if (res != TEE_SUCCESS) 288b36311adSJerome Forissier TEE_Panic(res); 289b0104773SPascal Brand } 290b0104773SPascal Brand 29179a3c601SCedric Chaumont void *TEE_Malloc(uint32_t len, uint32_t hint) 292b0104773SPascal Brand { 29396c1d8c5SJens Wiklander if (hint == TEE_MALLOC_FILL_ZERO) 29496c1d8c5SJens Wiklander return calloc(1, len); 29596c1d8c5SJens Wiklander else if (hint == TEE_USER_MEM_HINT_NO_FILL_ZERO) 29696c1d8c5SJens Wiklander return malloc(len); 29796c1d8c5SJens Wiklander 29896c1d8c5SJens Wiklander EMSG("Invalid hint %#" PRIx32, hint); 29996c1d8c5SJens Wiklander 30096c1d8c5SJens Wiklander return NULL; 301b0104773SPascal Brand } 302b0104773SPascal Brand 303c0ce02edSJens Wiklander void *TEE_Realloc(void *buffer, uint32_t newSize) 304b0104773SPascal Brand { 30596c1d8c5SJens Wiklander return realloc(buffer, newSize); 306b0104773SPascal Brand } 307b0104773SPascal Brand 308b0104773SPascal Brand void TEE_Free(void *buffer) 309b0104773SPascal Brand { 31096c1d8c5SJens Wiklander free(buffer); 311b0104773SPascal Brand } 312fa530828SPascal Brand 313fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ 314fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len) 315fa530828SPascal Brand { 316fa530828SPascal Brand return utee_cache_operation(buf, len, TEE_CACHECLEAN); 317fa530828SPascal Brand } 318fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len) 319fa530828SPascal Brand { 320fa530828SPascal Brand return utee_cache_operation(buf, len, TEE_CACHEFLUSH); 321fa530828SPascal Brand } 322fa530828SPascal Brand 323fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len) 324fa530828SPascal Brand { 325fa530828SPascal Brand return utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); 326fa530828SPascal Brand } 327