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