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