1 /* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <stdlib.h> 28 #include <string.h> 29 30 #include <tee_api.h> 31 #include <utee_syscalls.h> 32 #include <user_ta_header.h> 33 #include "tee_user_mem.h" 34 #include "tee_api_private.h" 35 36 static void *tee_api_instance_data; 37 38 /* System API - Internal Client API */ 39 40 void __utee_from_param(struct utee_params *up, uint32_t param_types, 41 const TEE_Param params[TEE_NUM_PARAMS]) 42 { 43 size_t n; 44 45 up->types = param_types; 46 for (n = 0; n < TEE_NUM_PARAMS; n++) { 47 switch (TEE_PARAM_TYPE_GET(param_types, n)) { 48 case TEE_PARAM_TYPE_VALUE_INPUT: 49 case TEE_PARAM_TYPE_VALUE_OUTPUT: 50 case TEE_PARAM_TYPE_VALUE_INOUT: 51 up->vals[n * 2] = params[n].value.a; 52 up->vals[n * 2 + 1] = params[n].value.b; 53 break; 54 case TEE_PARAM_TYPE_MEMREF_INPUT: 55 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 56 case TEE_PARAM_TYPE_MEMREF_INOUT: 57 up->vals[n * 2] = (uintptr_t)params[n].memref.buffer; 58 up->vals[n * 2 + 1] = params[n].memref.size; 59 break; 60 default: 61 up->vals[n * 2] = 0; 62 up->vals[n * 2 + 1] = 0; 63 break; 64 } 65 } 66 } 67 68 void __utee_to_param(TEE_Param params[TEE_NUM_PARAMS], 69 uint32_t *param_types, const struct utee_params *up) 70 { 71 size_t n; 72 uint32_t types = up->types; 73 74 for (n = 0; n < TEE_NUM_PARAMS; n++) { 75 uintptr_t a = up->vals[n * 2]; 76 uintptr_t b = up->vals[n * 2 + 1]; 77 78 switch (TEE_PARAM_TYPE_GET(types, n)) { 79 case TEE_PARAM_TYPE_VALUE_INPUT: 80 case TEE_PARAM_TYPE_VALUE_OUTPUT: 81 case TEE_PARAM_TYPE_VALUE_INOUT: 82 params[n].value.a = a; 83 params[n].value.b = b; 84 break; 85 case TEE_PARAM_TYPE_MEMREF_INPUT: 86 case TEE_PARAM_TYPE_MEMREF_OUTPUT: 87 case TEE_PARAM_TYPE_MEMREF_INOUT: 88 params[n].memref.buffer = (void *)a; 89 params[n].memref.size = b; 90 break; 91 default: 92 break; 93 } 94 } 95 96 if (param_types) 97 *param_types = types; 98 } 99 100 TEE_Result TEE_OpenTASession(const TEE_UUID *destination, 101 uint32_t cancellationRequestTimeout, 102 uint32_t paramTypes, 103 TEE_Param params[TEE_NUM_PARAMS], 104 TEE_TASessionHandle *session, 105 uint32_t *returnOrigin) 106 { 107 TEE_Result res; 108 struct utee_params up; 109 uint32_t s; 110 111 __utee_from_param(&up, paramTypes, params); 112 res = utee_open_ta_session(destination, cancellationRequestTimeout, 113 &up, &s, returnOrigin); 114 __utee_to_param(params, NULL, &up); 115 /* 116 * Specification says that *session must hold TEE_HANDLE_NULL is 117 * TEE_SUCCESS isn't returned. Set it here explicitly in case 118 * the syscall fails before out parameters has been updated. 119 */ 120 if (res != TEE_SUCCESS) 121 s = TEE_HANDLE_NULL; 122 123 *session = (TEE_TASessionHandle)(uintptr_t)s; 124 return res; 125 } 126 127 void TEE_CloseTASession(TEE_TASessionHandle session) 128 { 129 if (session != TEE_HANDLE_NULL) { 130 TEE_Result res = utee_close_ta_session((uintptr_t)session); 131 132 if (res != TEE_SUCCESS) 133 TEE_Panic(res); 134 } 135 } 136 137 TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, 138 uint32_t cancellationRequestTimeout, 139 uint32_t commandID, uint32_t paramTypes, 140 TEE_Param params[TEE_NUM_PARAMS], 141 uint32_t *returnOrigin) 142 { 143 TEE_Result res; 144 uint32_t ret_origin; 145 struct utee_params up; 146 147 __utee_from_param(&up, paramTypes, params); 148 res = utee_invoke_ta_command((uintptr_t)session, 149 cancellationRequestTimeout, 150 commandID, &up, &ret_origin); 151 __utee_to_param(params, NULL, &up); 152 153 if (returnOrigin != NULL) 154 *returnOrigin = ret_origin; 155 156 if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 157 return res; 158 159 if (res != TEE_SUCCESS && 160 res != TEE_ERROR_OUT_OF_MEMORY && 161 res != TEE_ERROR_TARGET_DEAD) 162 TEE_Panic(res); 163 164 return res; 165 } 166 167 /* System API - Cancellations */ 168 169 bool TEE_GetCancellationFlag(void) 170 { 171 uint32_t c; 172 TEE_Result res = utee_get_cancellation_flag(&c); 173 174 if (res != TEE_SUCCESS) 175 c = 0; 176 return !!c; 177 } 178 179 bool TEE_UnmaskCancellation(void) 180 { 181 uint32_t old_mask; 182 TEE_Result res = utee_unmask_cancellation(&old_mask); 183 184 if (res != TEE_SUCCESS) 185 TEE_Panic(res); 186 return !!old_mask; 187 } 188 189 bool TEE_MaskCancellation(void) 190 { 191 uint32_t old_mask; 192 TEE_Result res = utee_mask_cancellation(&old_mask); 193 194 if (res != TEE_SUCCESS) 195 TEE_Panic(res); 196 return !!old_mask; 197 } 198 199 /* System API - Memory Management */ 200 201 TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer, 202 uint32_t size) 203 { 204 TEE_Result res; 205 206 if (size == 0) 207 return TEE_SUCCESS; 208 209 /* Check access rights against memory mapping */ 210 res = utee_check_access_rights(accessFlags, buffer, size); 211 if (res != TEE_SUCCESS) 212 goto out; 213 214 /* 215 * Check access rights against input parameters 216 * Previous legacy code was removed and will need to be restored 217 */ 218 219 res = TEE_SUCCESS; 220 out: 221 return res; 222 } 223 224 void TEE_SetInstanceData(void *instanceData) 225 { 226 tee_api_instance_data = instanceData; 227 } 228 229 void *TEE_GetInstanceData(void) 230 { 231 return tee_api_instance_data; 232 } 233 234 void *TEE_MemMove(void *dest, const void *src, uint32_t size) 235 { 236 return memmove(dest, src, size); 237 } 238 239 int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size) 240 { 241 return memcmp(buffer1, buffer2, size); 242 } 243 244 void *TEE_MemFill(void *buff, uint32_t x, uint32_t size) 245 { 246 return memset(buff, x, size); 247 } 248 249 /* Date & Time API */ 250 251 void TEE_GetSystemTime(TEE_Time *time) 252 { 253 TEE_Result res = utee_get_time(UTEE_TIME_CAT_SYSTEM, time); 254 255 if (res != TEE_SUCCESS) 256 TEE_Panic(0); 257 } 258 259 TEE_Result TEE_Wait(uint32_t timeout) 260 { 261 TEE_Result res = utee_wait(timeout); 262 263 if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL) 264 TEE_Panic(res); 265 266 return res; 267 } 268 269 TEE_Result TEE_GetTAPersistentTime(TEE_Time *time) 270 { 271 TEE_Result res; 272 273 res = utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time); 274 275 if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) { 276 time->seconds = 0; 277 time->millis = 0; 278 } 279 280 if (res != TEE_SUCCESS && 281 res != TEE_ERROR_TIME_NOT_SET && 282 res != TEE_ERROR_TIME_NEEDS_RESET && 283 res != TEE_ERROR_OVERFLOW && 284 res != TEE_ERROR_OUT_OF_MEMORY) 285 TEE_Panic(res); 286 287 return res; 288 } 289 290 TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time) 291 { 292 TEE_Result res; 293 294 res = utee_set_ta_time(time); 295 296 if (res != TEE_SUCCESS && 297 res != TEE_ERROR_OUT_OF_MEMORY && 298 res != TEE_ERROR_STORAGE_NO_SPACE) 299 TEE_Panic(res); 300 301 return res; 302 } 303 304 void TEE_GetREETime(TEE_Time *time) 305 { 306 TEE_Result res = utee_get_time(UTEE_TIME_CAT_REE, time); 307 308 if (res != TEE_SUCCESS) 309 TEE_Panic(0); 310 } 311 312 void *TEE_Malloc(uint32_t len, uint32_t hint) 313 { 314 return tee_user_mem_alloc(len, hint); 315 } 316 317 void *TEE_Realloc(void *buffer, uint32_t newSize) 318 { 319 /* 320 * GP TEE Internal API specifies newSize as 'uint32_t'. 321 * use unsigned 'size_t' type. it is at least 32bit! 322 */ 323 return tee_user_mem_realloc(buffer, (size_t) newSize); 324 } 325 326 void TEE_Free(void *buffer) 327 { 328 tee_user_mem_free(buffer); 329 } 330 331 /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ 332 TEE_Result TEE_CacheClean(char *buf, size_t len) 333 { 334 return utee_cache_operation(buf, len, TEE_CACHECLEAN); 335 } 336 TEE_Result TEE_CacheFlush(char *buf, size_t len) 337 { 338 return utee_cache_operation(buf, len, TEE_CACHEFLUSH); 339 } 340 341 TEE_Result TEE_CacheInvalidate(char *buf, size_t len) 342 { 343 return utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); 344 } 345