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 15a83ee50aSSadiq Hussain /* 16a83ee50aSSadiq Hussain * return a known non-NULL invalid pointer when the 17a83ee50aSSadiq Hussain * requested size is zero 18a83ee50aSSadiq Hussain */ 19a83ee50aSSadiq Hussain #define TEE_NULL_SIZED_VA ((void *)1) 20a83ee50aSSadiq Hussain 218f07fe6fSJerome Forissier static const void *tee_api_instance_data; 22b0104773SPascal Brand 23b0104773SPascal Brand /* System API - Internal Client API */ 24b0104773SPascal Brand 257509620bSJens Wiklander static void copy_param(struct utee_params *up, uint32_t param_types, 267509620bSJens Wiklander const TEE_Param params[TEE_NUM_PARAMS]) 277509620bSJens Wiklander { 287509620bSJens Wiklander size_t n = 0; 297509620bSJens Wiklander uint64_t a = 0; 307509620bSJens Wiklander uint64_t b = 0; 317509620bSJens Wiklander 327509620bSJens Wiklander up->types = param_types; 337509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 347509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 357509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 367509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 377509620bSJens Wiklander a = params[n].value.a; 387509620bSJens Wiklander b = params[n].value.b; 397509620bSJens Wiklander break; 407509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 417509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 427509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 437509620bSJens Wiklander a = (vaddr_t)params[n].memref.buffer; 447509620bSJens Wiklander b = params[n].memref.size; 457509620bSJens Wiklander break; 467509620bSJens Wiklander default: 477509620bSJens Wiklander a = 0; 487509620bSJens Wiklander b = 0; 497509620bSJens Wiklander } 507509620bSJens Wiklander up->vals[n * 2] = a; 517509620bSJens Wiklander up->vals[n * 2 + 1] = b; 527509620bSJens Wiklander } 537509620bSJens Wiklander } 547509620bSJens Wiklander 557509620bSJens Wiklander static void copy_gp11_param(struct utee_params *up, uint32_t param_types, 567509620bSJens Wiklander const __GP11_TEE_Param params[TEE_NUM_PARAMS]) 577509620bSJens Wiklander { 587509620bSJens Wiklander size_t n = 0; 597509620bSJens Wiklander uint64_t a = 0; 607509620bSJens Wiklander uint64_t b = 0; 617509620bSJens Wiklander 627509620bSJens Wiklander up->types = param_types; 637509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 647509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 657509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 667509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 677509620bSJens Wiklander a = params[n].value.a; 687509620bSJens Wiklander b = params[n].value.b; 697509620bSJens Wiklander break; 707509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 717509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 727509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 737509620bSJens Wiklander a = (vaddr_t)params[n].memref.buffer; 747509620bSJens Wiklander b = params[n].memref.size; 757509620bSJens Wiklander break; 767509620bSJens Wiklander default: 777509620bSJens Wiklander a = 0; 787509620bSJens Wiklander b = 0; 797509620bSJens Wiklander } 807509620bSJens Wiklander up->vals[n * 2] = a; 817509620bSJens Wiklander up->vals[n * 2 + 1] = b; 827509620bSJens Wiklander } 837509620bSJens Wiklander } 847509620bSJens Wiklander 857509620bSJens Wiklander static TEE_Result map_tmp_param(struct utee_params *up, void **tmp_buf, 867509620bSJens Wiklander size_t *tmp_len, void *tmp_va[TEE_NUM_PARAMS]) 87e86f1266SJens Wiklander { 88ef305e54SJens Wiklander size_t n = 0; 89ef305e54SJens Wiklander uint8_t *tb = NULL; 90ef305e54SJens Wiklander size_t tbl = 0; 91ef305e54SJens Wiklander size_t tmp_align = sizeof(vaddr_t) * 2; 92ef305e54SJens Wiklander bool is_tmp_mem[TEE_NUM_PARAMS] = { false }; 93ef305e54SJens Wiklander void *b = NULL; 94ef305e54SJens Wiklander size_t s = 0; 95ef305e54SJens Wiklander const uint32_t flags = TEE_MEMORY_ACCESS_READ; 96ef305e54SJens Wiklander 97ef305e54SJens Wiklander /* 98ef305e54SJens Wiklander * If a memory parameter points to TA private memory we need to 99ef305e54SJens Wiklander * allocate a temporary buffer to avoid exposing the memory 100ef305e54SJens Wiklander * directly to the called TA. 101ef305e54SJens Wiklander */ 102ef305e54SJens Wiklander 103ef305e54SJens Wiklander *tmp_buf = NULL; 104ef305e54SJens Wiklander *tmp_len = 0; 105ef305e54SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 106ef305e54SJens Wiklander tmp_va[n] = NULL; 1077509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 108ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 109ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 110ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 1117509620bSJens Wiklander b = (void *)(vaddr_t)up->vals[n * 2]; 1127509620bSJens Wiklander s = up->vals[n * 2 + 1]; 113ef305e54SJens Wiklander /* 114ef305e54SJens Wiklander * We're only allocating temporary memory if the 115ef305e54SJens Wiklander * buffer is completely within TA memory. If it's 116ef305e54SJens Wiklander * NULL, empty, partially outside or completely 117ef305e54SJens Wiklander * outside TA memory there's nothing more we need 118ef305e54SJens Wiklander * to do here. If there's security/permissions 119ef305e54SJens Wiklander * problem we'll get an error in the 120ef305e54SJens Wiklander * invoke_command/open_session below. 121ef305e54SJens Wiklander */ 122ef305e54SJens Wiklander if (b && s && 123ef305e54SJens Wiklander !TEE_CheckMemoryAccessRights(flags, b, s)) { 124ef305e54SJens Wiklander is_tmp_mem[n] = true; 125ef305e54SJens Wiklander tbl += ROUNDUP(s, tmp_align); 126ef305e54SJens Wiklander } 127ef305e54SJens Wiklander break; 128ef305e54SJens Wiklander default: 129ef305e54SJens Wiklander break; 130ef305e54SJens Wiklander } 131ef305e54SJens Wiklander } 132ef305e54SJens Wiklander 133ef305e54SJens Wiklander if (tbl) { 134ef305e54SJens Wiklander tb = tee_map_zi(tbl, TEE_MEMORY_ACCESS_ANY_OWNER); 135ef305e54SJens Wiklander if (!tb) 136ef305e54SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 137ef305e54SJens Wiklander *tmp_buf = tb; 138ef305e54SJens Wiklander *tmp_len = tbl; 139ef305e54SJens Wiklander } 140e86f1266SJens Wiklander 141e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 1427509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 143e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 144e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 145ef305e54SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 1467509620bSJens Wiklander if (!is_tmp_mem[n]) 1477509620bSJens Wiklander break; 1487509620bSJens Wiklander s = up->vals[n * 2 + 1]; 1497509620bSJens Wiklander b = (void *)(vaddr_t)up->vals[n * 2]; 150ef305e54SJens Wiklander tmp_va[n] = tb; 151ef305e54SJens Wiklander tb += ROUNDUP(s, tmp_align); 1527509620bSJens Wiklander up->vals[n * 2] = (vaddr_t)tmp_va[n]; 1537509620bSJens Wiklander if (TEE_PARAM_TYPE_GET(up->types, n) != 154ef305e54SJens Wiklander TEE_PARAM_TYPE_MEMREF_OUTPUT) 1557509620bSJens Wiklander memcpy(tmp_va[n], b, s); 156e86f1266SJens Wiklander break; 157e86f1266SJens Wiklander default: 158e86f1266SJens Wiklander break; 159e86f1266SJens Wiklander } 160e86f1266SJens Wiklander } 161ef305e54SJens Wiklander 162ef305e54SJens Wiklander return TEE_SUCCESS; 1637509620bSJens Wiklander 164e86f1266SJens Wiklander } 165e86f1266SJens Wiklander 166ef305e54SJens Wiklander static void update_out_param(TEE_Param params[TEE_NUM_PARAMS], 167ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS], 168ef305e54SJens Wiklander const struct utee_params *up) 169e86f1266SJens Wiklander { 170e86f1266SJens Wiklander size_t n; 171e86f1266SJens Wiklander uint32_t types = up->types; 172e86f1266SJens Wiklander 173e86f1266SJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 174e86f1266SJens Wiklander uintptr_t a = up->vals[n * 2]; 175e86f1266SJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 176e86f1266SJens Wiklander 177e86f1266SJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 178e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 179e86f1266SJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 180e86f1266SJens Wiklander params[n].value.a = a; 181e86f1266SJens Wiklander params[n].value.b = b; 182e86f1266SJens Wiklander break; 183e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 184e86f1266SJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 185ef305e54SJens Wiklander if (tmp_va[n]) 186ef305e54SJens Wiklander memcpy(params[n].memref.buffer, tmp_va[n], 187ef305e54SJens Wiklander MIN(b, params[n].memref.size)); 188e86f1266SJens Wiklander params[n].memref.size = b; 189e86f1266SJens Wiklander break; 190e86f1266SJens Wiklander default: 191e86f1266SJens Wiklander break; 192e86f1266SJens Wiklander } 193e86f1266SJens Wiklander } 194e86f1266SJens Wiklander } 195e86f1266SJens Wiklander 1967509620bSJens Wiklander static void update_out_gp11_param(__GP11_TEE_Param params[TEE_NUM_PARAMS], 1977509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS], 1987509620bSJens Wiklander const struct utee_params *up) 1997509620bSJens Wiklander { 2007509620bSJens Wiklander size_t n = 0; 2017509620bSJens Wiklander uint32_t types = up->types; 2027509620bSJens Wiklander 2037509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 2047509620bSJens Wiklander uintptr_t a = up->vals[n * 2]; 2057509620bSJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 2067509620bSJens Wiklander 2077509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 2087509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 2097509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 2107509620bSJens Wiklander params[n].value.a = a; 2117509620bSJens Wiklander params[n].value.b = b; 2127509620bSJens Wiklander break; 2137509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 2147509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 2157509620bSJens Wiklander if (tmp_va[n]) 2167509620bSJens Wiklander memcpy(params[n].memref.buffer, tmp_va[n], 2177509620bSJens Wiklander MIN(b, params[n].memref.size)); 2187509620bSJens Wiklander params[n].memref.size = b; 2197509620bSJens Wiklander break; 2207509620bSJens Wiklander default: 2217509620bSJens Wiklander break; 2227509620bSJens Wiklander } 2237509620bSJens Wiklander } 2247509620bSJens Wiklander } 2257509620bSJens Wiklander 226b0104773SPascal Brand TEE_Result TEE_OpenTASession(const TEE_UUID *destination, 227b0104773SPascal Brand uint32_t cancellationRequestTimeout, 22868540524SIgor Opaniuk uint32_t paramTypes, 22968540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 230b0104773SPascal Brand TEE_TASessionHandle *session, 231b0104773SPascal Brand uint32_t *returnOrigin) 232b0104773SPascal Brand { 233ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 2347509620bSJens Wiklander struct utee_params up = { }; 235ef305e54SJens Wiklander uint32_t s = 0; 236ef305e54SJens Wiklander void *tmp_buf = NULL; 237ef305e54SJens Wiklander size_t tmp_len = 0; 238ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 239b0104773SPascal Brand 2406915bbbbSJens Wiklander if (paramTypes) 2416915bbbbSJens Wiklander __utee_check_inout_annotation(params, 2426915bbbbSJens Wiklander sizeof(TEE_Param) * 2436915bbbbSJens Wiklander TEE_NUM_PARAMS); 2446915bbbbSJens Wiklander __utee_check_out_annotation(session, sizeof(*session)); 2456915bbbbSJens Wiklander 2467509620bSJens Wiklander copy_param(&up, paramTypes, params); 2477509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 248ef305e54SJens Wiklander if (res) 249ef305e54SJens Wiklander goto out; 2502c028fdeSJerome Forissier res = _utee_open_ta_session(destination, cancellationRequestTimeout, 251e86f1266SJens Wiklander &up, &s, returnOrigin); 252ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 253ef305e54SJens Wiklander if (tmp_buf) { 254ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 255ef305e54SJens Wiklander 256ef305e54SJens Wiklander if (res2) 257ef305e54SJens Wiklander TEE_Panic(res2); 258ef305e54SJens Wiklander } 259ef305e54SJens Wiklander 260ef305e54SJens Wiklander out: 261b0104773SPascal Brand /* 262b0104773SPascal Brand * Specification says that *session must hold TEE_HANDLE_NULL is 263b0104773SPascal Brand * TEE_SUCCESS isn't returned. Set it here explicitly in case 264b0104773SPascal Brand * the syscall fails before out parameters has been updated. 265b0104773SPascal Brand */ 266b0104773SPascal Brand if (res != TEE_SUCCESS) 267e86f1266SJens Wiklander s = TEE_HANDLE_NULL; 268b0104773SPascal Brand 269e86f1266SJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 270b0104773SPascal Brand return res; 271b0104773SPascal Brand } 272b0104773SPascal Brand 2737509620bSJens Wiklander TEE_Result __GP11_TEE_OpenTASession(const TEE_UUID *destination, 2747509620bSJens Wiklander uint32_t cancellationRequestTimeout, 2757509620bSJens Wiklander uint32_t paramTypes, 2767509620bSJens Wiklander __GP11_TEE_Param params[TEE_NUM_PARAMS], 2777509620bSJens Wiklander TEE_TASessionHandle *session, 2787509620bSJens Wiklander uint32_t *returnOrigin) 2797509620bSJens Wiklander { 2807509620bSJens Wiklander TEE_Result res = TEE_SUCCESS; 2817509620bSJens Wiklander struct utee_params up = { }; 2827509620bSJens Wiklander uint32_t s = 0; 2837509620bSJens Wiklander void *tmp_buf = NULL; 2847509620bSJens Wiklander size_t tmp_len = 0; 2857509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 2867509620bSJens Wiklander 2877509620bSJens Wiklander if (paramTypes) 2887509620bSJens Wiklander __utee_check_inout_annotation(params, 2897509620bSJens Wiklander sizeof(__GP11_TEE_Param) * 2907509620bSJens Wiklander TEE_NUM_PARAMS); 2917509620bSJens Wiklander __utee_check_out_annotation(session, sizeof(*session)); 2927509620bSJens Wiklander 2937509620bSJens Wiklander copy_gp11_param(&up, paramTypes, params); 2947509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 2957509620bSJens Wiklander if (res) 2967509620bSJens Wiklander goto out; 2977509620bSJens Wiklander res = _utee_open_ta_session(destination, cancellationRequestTimeout, 2987509620bSJens Wiklander &up, &s, returnOrigin); 2997509620bSJens Wiklander update_out_gp11_param(params, tmp_va, &up); 3007509620bSJens Wiklander if (tmp_buf) { 3017509620bSJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 3027509620bSJens Wiklander 3037509620bSJens Wiklander if (res2) 3047509620bSJens Wiklander TEE_Panic(res2); 3057509620bSJens Wiklander } 3067509620bSJens Wiklander 3077509620bSJens Wiklander out: 3087509620bSJens Wiklander /* 3097509620bSJens Wiklander * Specification says that *session must hold TEE_HANDLE_NULL if 3107509620bSJens Wiklander * TEE_SUCCESS isn't returned. Set it here explicitly in case 3117509620bSJens Wiklander * the syscall fails before out parameters has been updated. 3127509620bSJens Wiklander */ 3137509620bSJens Wiklander if (res != TEE_SUCCESS) 3147509620bSJens Wiklander s = TEE_HANDLE_NULL; 3157509620bSJens Wiklander 3167509620bSJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 3177509620bSJens Wiklander return res; 3187509620bSJens Wiklander } 3197509620bSJens Wiklander 320b0104773SPascal Brand void TEE_CloseTASession(TEE_TASessionHandle session) 321b0104773SPascal Brand { 322b0104773SPascal Brand if (session != TEE_HANDLE_NULL) { 3232c028fdeSJerome Forissier TEE_Result res = _utee_close_ta_session((uintptr_t)session); 324e86f1266SJens Wiklander 325b0104773SPascal Brand if (res != TEE_SUCCESS) 326b0104773SPascal Brand TEE_Panic(res); 327b0104773SPascal Brand } 328b0104773SPascal Brand } 329b0104773SPascal Brand 330b0104773SPascal Brand TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, 331b0104773SPascal Brand uint32_t cancellationRequestTimeout, 332b0104773SPascal Brand uint32_t commandID, uint32_t paramTypes, 33368540524SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS], 33468540524SIgor Opaniuk uint32_t *returnOrigin) 335b0104773SPascal Brand { 336ef305e54SJens Wiklander TEE_Result res = TEE_SUCCESS; 337ef305e54SJens Wiklander uint32_t ret_origin = TEE_ORIGIN_TEE; 3387509620bSJens Wiklander struct utee_params up = { }; 339ef305e54SJens Wiklander void *tmp_buf = NULL; 340ef305e54SJens Wiklander size_t tmp_len = 0; 341ef305e54SJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 342c15e5835SCedric Chaumont 3436915bbbbSJens Wiklander if (paramTypes) 3446915bbbbSJens Wiklander __utee_check_inout_annotation(params, 3456915bbbbSJens Wiklander sizeof(TEE_Param) * 3466915bbbbSJens Wiklander TEE_NUM_PARAMS); 3476915bbbbSJens Wiklander if (returnOrigin) 3486915bbbbSJens Wiklander __utee_check_out_annotation(returnOrigin, 3496915bbbbSJens Wiklander sizeof(*returnOrigin)); 3506915bbbbSJens Wiklander 3517509620bSJens Wiklander copy_param(&up, paramTypes, params); 3527509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 353ef305e54SJens Wiklander if (res) 354ef305e54SJens Wiklander goto out; 3552c028fdeSJerome Forissier res = _utee_invoke_ta_command((uintptr_t)session, 356e86f1266SJens Wiklander cancellationRequestTimeout, 357e86f1266SJens Wiklander commandID, &up, &ret_origin); 358ef305e54SJens Wiklander update_out_param(params, tmp_va, &up); 359ef305e54SJens Wiklander if (tmp_buf) { 360ef305e54SJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 3616709c3eaSCedric Chaumont 362ef305e54SJens Wiklander if (res2) 363ef305e54SJens Wiklander TEE_Panic(res2); 364ef305e54SJens Wiklander } 365ef305e54SJens Wiklander 366ef305e54SJens Wiklander out: 3676709c3eaSCedric Chaumont if (returnOrigin != NULL) 3686709c3eaSCedric Chaumont *returnOrigin = ret_origin; 3696709c3eaSCedric Chaumont 3706709c3eaSCedric Chaumont if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 3716709c3eaSCedric Chaumont return res; 3726709c3eaSCedric Chaumont 373c15e5835SCedric Chaumont if (res != TEE_SUCCESS && 374c15e5835SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 375c15e5835SCedric Chaumont res != TEE_ERROR_TARGET_DEAD) 376c15e5835SCedric Chaumont TEE_Panic(res); 377c15e5835SCedric Chaumont 378c15e5835SCedric Chaumont return res; 379b0104773SPascal Brand } 380b0104773SPascal Brand 3817509620bSJens Wiklander TEE_Result __GP11_TEE_InvokeTACommand(TEE_TASessionHandle session, 3827509620bSJens Wiklander uint32_t cancellationRequestTimeout, 3837509620bSJens Wiklander uint32_t commandID, uint32_t paramTypes, 3847509620bSJens Wiklander __GP11_TEE_Param params[TEE_NUM_PARAMS], 3857509620bSJens Wiklander uint32_t *returnOrigin) 3867509620bSJens Wiklander { 3877509620bSJens Wiklander TEE_Result res = TEE_SUCCESS; 3887509620bSJens Wiklander uint32_t ret_origin = TEE_ORIGIN_TEE; 3897509620bSJens Wiklander struct utee_params up = { }; 3907509620bSJens Wiklander void *tmp_buf = NULL; 3917509620bSJens Wiklander size_t tmp_len = 0; 3927509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 3937509620bSJens Wiklander 3947509620bSJens Wiklander if (paramTypes) 3957509620bSJens Wiklander __utee_check_inout_annotation(params, 3967509620bSJens Wiklander sizeof(__GP11_TEE_Param) * 3977509620bSJens Wiklander TEE_NUM_PARAMS); 3987509620bSJens Wiklander if (returnOrigin) 3997509620bSJens Wiklander __utee_check_out_annotation(returnOrigin, 4007509620bSJens Wiklander sizeof(*returnOrigin)); 4017509620bSJens Wiklander 4027509620bSJens Wiklander copy_gp11_param(&up, paramTypes, params); 4037509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 4047509620bSJens Wiklander if (res) 4057509620bSJens Wiklander goto out; 4067509620bSJens Wiklander res = _utee_invoke_ta_command((uintptr_t)session, 4077509620bSJens Wiklander cancellationRequestTimeout, 4087509620bSJens Wiklander commandID, &up, &ret_origin); 4097509620bSJens Wiklander update_out_gp11_param(params, tmp_va, &up); 4107509620bSJens Wiklander if (tmp_buf) { 4117509620bSJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 4127509620bSJens Wiklander 4137509620bSJens Wiklander if (res2) 4147509620bSJens Wiklander TEE_Panic(res2); 4157509620bSJens Wiklander } 4167509620bSJens Wiklander 4177509620bSJens Wiklander out: 4187509620bSJens Wiklander if (returnOrigin) 4197509620bSJens Wiklander *returnOrigin = ret_origin; 4207509620bSJens Wiklander 4217509620bSJens Wiklander if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 4227509620bSJens Wiklander return res; 4237509620bSJens Wiklander 4247509620bSJens Wiklander if (res != TEE_SUCCESS && 4257509620bSJens Wiklander res != TEE_ERROR_OUT_OF_MEMORY && 4267509620bSJens Wiklander res != TEE_ERROR_TARGET_DEAD) 4277509620bSJens Wiklander TEE_Panic(res); 4287509620bSJens Wiklander 4297509620bSJens Wiklander return res; 4307509620bSJens Wiklander } 4317509620bSJens Wiklander 432b0104773SPascal Brand /* System API - Cancellations */ 433b0104773SPascal Brand 434b0104773SPascal Brand bool TEE_GetCancellationFlag(void) 435b0104773SPascal Brand { 436e86f1266SJens Wiklander uint32_t c; 4372c028fdeSJerome Forissier TEE_Result res = _utee_get_cancellation_flag(&c); 438e86f1266SJens Wiklander 439b0104773SPascal Brand if (res != TEE_SUCCESS) 440e86f1266SJens Wiklander c = 0; 441e86f1266SJens Wiklander return !!c; 442b0104773SPascal Brand } 443b0104773SPascal Brand 444b0104773SPascal Brand bool TEE_UnmaskCancellation(void) 445b0104773SPascal Brand { 446e86f1266SJens Wiklander uint32_t old_mask; 4472c028fdeSJerome Forissier TEE_Result res = _utee_unmask_cancellation(&old_mask); 448b0104773SPascal Brand 449b0104773SPascal Brand if (res != TEE_SUCCESS) 450b0104773SPascal Brand TEE_Panic(res); 451e86f1266SJens Wiklander return !!old_mask; 452b0104773SPascal Brand } 453b0104773SPascal Brand 454b0104773SPascal Brand bool TEE_MaskCancellation(void) 455b0104773SPascal Brand { 456e86f1266SJens Wiklander uint32_t old_mask; 4572c028fdeSJerome Forissier TEE_Result res = _utee_mask_cancellation(&old_mask); 458b0104773SPascal Brand 459b0104773SPascal Brand if (res != TEE_SUCCESS) 460b0104773SPascal Brand TEE_Panic(res); 461e86f1266SJens Wiklander return !!old_mask; 462b0104773SPascal Brand } 463b0104773SPascal Brand 464b0104773SPascal Brand /* System API - Memory Management */ 465b0104773SPascal Brand 466b0104773SPascal Brand TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void *buffer, 467cd3a8caeSJens Wiklander size_t size) 468b0104773SPascal Brand { 469b0104773SPascal Brand TEE_Result res; 470b0104773SPascal Brand 471b0104773SPascal Brand if (size == 0) 472b0104773SPascal Brand return TEE_SUCCESS; 473b0104773SPascal Brand 474b0104773SPascal Brand /* Check access rights against memory mapping */ 4752c028fdeSJerome Forissier res = _utee_check_access_rights(accessFlags, buffer, size); 476b0104773SPascal Brand if (res != TEE_SUCCESS) 477b0104773SPascal Brand goto out; 478b0104773SPascal Brand 479b0104773SPascal Brand /* 480b0104773SPascal Brand * Check access rights against input parameters 481b0104773SPascal Brand * Previous legacy code was removed and will need to be restored 482b0104773SPascal Brand */ 483b0104773SPascal Brand 484b0104773SPascal Brand res = TEE_SUCCESS; 485b0104773SPascal Brand out: 486b0104773SPascal Brand return res; 487b0104773SPascal Brand } 488b0104773SPascal Brand 489cd3a8caeSJens Wiklander TEE_Result __GP11_TEE_CheckMemoryAccessRights(uint32_t accessFlags, 490cd3a8caeSJens Wiklander void *buffer, uint32_t size) 491cd3a8caeSJens Wiklander { 492cd3a8caeSJens Wiklander return TEE_CheckMemoryAccessRights(accessFlags, buffer, size); 493cd3a8caeSJens Wiklander } 494cd3a8caeSJens Wiklander 4958f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData) 496b0104773SPascal Brand { 497b0104773SPascal Brand tee_api_instance_data = instanceData; 498b0104773SPascal Brand } 499b0104773SPascal Brand 5008f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void) 501b0104773SPascal Brand { 502b0104773SPascal Brand return tee_api_instance_data; 503b0104773SPascal Brand } 504b0104773SPascal Brand 505*1d0ed95aSJens Wiklander void *TEE_MemMove(void *dest, const void *src, size_t size) 506b0104773SPascal Brand { 507b0104773SPascal Brand return memmove(dest, src, size); 508b0104773SPascal Brand } 509b0104773SPascal Brand 510*1d0ed95aSJens Wiklander void *__GP11_TEE_MemMove(void *dest, const void *src, uint32_t size) 511*1d0ed95aSJens Wiklander { 512*1d0ed95aSJens Wiklander return TEE_MemMove(dest, src, size); 513*1d0ed95aSJens Wiklander } 514*1d0ed95aSJens Wiklander 515*1d0ed95aSJens Wiklander int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, size_t size) 516b0104773SPascal Brand { 51765551e69SJerome Forissier return consttime_memcmp(buffer1, buffer2, size); 518b0104773SPascal Brand } 519b0104773SPascal Brand 520*1d0ed95aSJens Wiklander int32_t __GP11_TEE_MemCompare(const void *buffer1, const void *buffer2, 521*1d0ed95aSJens Wiklander uint32_t size) 522*1d0ed95aSJens Wiklander { 523*1d0ed95aSJens Wiklander return TEE_MemCompare(buffer1, buffer2, size); 524*1d0ed95aSJens Wiklander } 525*1d0ed95aSJens Wiklander 526*1d0ed95aSJens Wiklander void TEE_MemFill(void *buff, uint32_t x, size_t size) 527b0104773SPascal Brand { 52832c75600SJens Wiklander memset(buff, x, size); 529b0104773SPascal Brand } 530b0104773SPascal Brand 531*1d0ed95aSJens Wiklander void __GP11_TEE_MemFill(void *buff, uint32_t x, uint32_t size) 532*1d0ed95aSJens Wiklander { 533*1d0ed95aSJens Wiklander TEE_MemFill(buff, x, size); 534*1d0ed95aSJens Wiklander } 535*1d0ed95aSJens Wiklander 536b0104773SPascal Brand /* Date & Time API */ 537b0104773SPascal Brand 538b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time) 539b0104773SPascal Brand { 5402c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time); 541b0104773SPascal Brand 542b0104773SPascal Brand if (res != TEE_SUCCESS) 543b36311adSJerome Forissier TEE_Panic(res); 544b0104773SPascal Brand } 545b0104773SPascal Brand 546b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout) 547b0104773SPascal Brand { 5482c028fdeSJerome Forissier TEE_Result res = _utee_wait(timeout); 549b0104773SPascal Brand 550b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL) 551b0104773SPascal Brand TEE_Panic(res); 552b0104773SPascal Brand 553b0104773SPascal Brand return res; 554b0104773SPascal Brand } 555b0104773SPascal Brand 556b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time) 557b0104773SPascal Brand { 558b64d6909SCedric Chaumont TEE_Result res; 559b64d6909SCedric Chaumont 5602c028fdeSJerome Forissier res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time); 561b64d6909SCedric Chaumont 562b64d6909SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) { 563b64d6909SCedric Chaumont time->seconds = 0; 564b64d6909SCedric Chaumont time->millis = 0; 565b64d6909SCedric Chaumont } 566b64d6909SCedric Chaumont 567b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 568b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NOT_SET && 569b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NEEDS_RESET && 570b64d6909SCedric Chaumont res != TEE_ERROR_OVERFLOW && 571b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY) 572b64d6909SCedric Chaumont TEE_Panic(res); 573b64d6909SCedric Chaumont 574b64d6909SCedric Chaumont return res; 575b0104773SPascal Brand } 576b0104773SPascal Brand 577b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time) 578b0104773SPascal Brand { 579b64d6909SCedric Chaumont TEE_Result res; 580b64d6909SCedric Chaumont 5812c028fdeSJerome Forissier res = _utee_set_ta_time(time); 582b64d6909SCedric Chaumont 583b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 584b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 585b64d6909SCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE) 586b64d6909SCedric Chaumont TEE_Panic(res); 587b64d6909SCedric Chaumont 588b64d6909SCedric Chaumont return res; 589b0104773SPascal Brand } 590b0104773SPascal Brand 591b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time) 592b0104773SPascal Brand { 5932c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time); 594b0104773SPascal Brand 595b0104773SPascal Brand if (res != TEE_SUCCESS) 596b36311adSJerome Forissier TEE_Panic(res); 597b0104773SPascal Brand } 598b0104773SPascal Brand 59911285ebcSJens Wiklander void *TEE_Malloc(size_t len, uint32_t hint) 600b0104773SPascal Brand { 60111285ebcSJens Wiklander switch (hint) { 60211285ebcSJens Wiklander case TEE_MALLOC_FILL_ZERO: 603a83ee50aSSadiq Hussain if (!len) 604a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 60596c1d8c5SJens Wiklander return calloc(1, len); 60611285ebcSJens Wiklander 60711285ebcSJens Wiklander case TEE_MALLOC_NO_FILL: 60811285ebcSJens Wiklander TEE_Panic(0); 60911285ebcSJens Wiklander break; 61011285ebcSJens Wiklander 61111285ebcSJens Wiklander case TEE_MALLOC_NO_FILL | TEE_MALLOC_NO_SHARE: 61211285ebcSJens Wiklander return NULL; /* TEE_MALLOC_NO_SHARE is not yet supported */ 61311285ebcSJens Wiklander 61411285ebcSJens Wiklander case TEE_USER_MEM_HINT_NO_FILL_ZERO: 61511285ebcSJens Wiklander if (!len) 61611285ebcSJens Wiklander return TEE_NULL_SIZED_VA; 61796c1d8c5SJens Wiklander return malloc(len); 61896c1d8c5SJens Wiklander 61911285ebcSJens Wiklander default: 62011285ebcSJens Wiklander break; 62111285ebcSJens Wiklander } 62211285ebcSJens Wiklander 62396c1d8c5SJens Wiklander EMSG("Invalid hint %#" PRIx32, hint); 62496c1d8c5SJens Wiklander 62596c1d8c5SJens Wiklander return NULL; 626b0104773SPascal Brand } 627b0104773SPascal Brand 62811285ebcSJens Wiklander void *__GP11_TEE_Malloc(uint32_t size, uint32_t hint) 62911285ebcSJens Wiklander { 63011285ebcSJens Wiklander return TEE_Malloc(size, hint); 63111285ebcSJens Wiklander } 63211285ebcSJens Wiklander 63311285ebcSJens Wiklander void *TEE_Realloc(void *buffer, size_t newSize) 634b0104773SPascal Brand { 635a83ee50aSSadiq Hussain if (!newSize) { 636a83ee50aSSadiq Hussain TEE_Free(buffer); 637a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 638a83ee50aSSadiq Hussain } 639a83ee50aSSadiq Hussain 640a83ee50aSSadiq Hussain if (buffer == TEE_NULL_SIZED_VA) 641a83ee50aSSadiq Hussain return calloc(1, newSize); 642a83ee50aSSadiq Hussain 64396c1d8c5SJens Wiklander return realloc(buffer, newSize); 644b0104773SPascal Brand } 645b0104773SPascal Brand 64611285ebcSJens Wiklander void *__GP11_TEE_Realloc(void *buffer, uint32_t newSize) 64711285ebcSJens Wiklander { 64811285ebcSJens Wiklander return TEE_Realloc(buffer, newSize); 64911285ebcSJens Wiklander } 65011285ebcSJens Wiklander 651b0104773SPascal Brand void TEE_Free(void *buffer) 652b0104773SPascal Brand { 653a83ee50aSSadiq Hussain if (buffer != TEE_NULL_SIZED_VA) 65496c1d8c5SJens Wiklander free(buffer); 655b0104773SPascal Brand } 656fa530828SPascal Brand 657fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ 658fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len) 659fa530828SPascal Brand { 6602c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHECLEAN); 661fa530828SPascal Brand } 662fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len) 663fa530828SPascal Brand { 6642c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEFLUSH); 665fa530828SPascal Brand } 666fa530828SPascal Brand 667fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len) 668fa530828SPascal Brand { 6692c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); 670fa530828SPascal Brand } 671