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 25*7509620bSJens Wiklander static void copy_param(struct utee_params *up, uint32_t param_types, 26*7509620bSJens Wiklander const TEE_Param params[TEE_NUM_PARAMS]) 27*7509620bSJens Wiklander { 28*7509620bSJens Wiklander size_t n = 0; 29*7509620bSJens Wiklander uint64_t a = 0; 30*7509620bSJens Wiklander uint64_t b = 0; 31*7509620bSJens Wiklander 32*7509620bSJens Wiklander up->types = param_types; 33*7509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 34*7509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 35*7509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 36*7509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 37*7509620bSJens Wiklander a = params[n].value.a; 38*7509620bSJens Wiklander b = params[n].value.b; 39*7509620bSJens Wiklander break; 40*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 41*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 42*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 43*7509620bSJens Wiklander a = (vaddr_t)params[n].memref.buffer; 44*7509620bSJens Wiklander b = params[n].memref.size; 45*7509620bSJens Wiklander break; 46*7509620bSJens Wiklander default: 47*7509620bSJens Wiklander a = 0; 48*7509620bSJens Wiklander b = 0; 49*7509620bSJens Wiklander } 50*7509620bSJens Wiklander up->vals[n * 2] = a; 51*7509620bSJens Wiklander up->vals[n * 2 + 1] = b; 52*7509620bSJens Wiklander } 53*7509620bSJens Wiklander } 54*7509620bSJens Wiklander 55*7509620bSJens Wiklander static void copy_gp11_param(struct utee_params *up, uint32_t param_types, 56*7509620bSJens Wiklander const __GP11_TEE_Param params[TEE_NUM_PARAMS]) 57*7509620bSJens Wiklander { 58*7509620bSJens Wiklander size_t n = 0; 59*7509620bSJens Wiklander uint64_t a = 0; 60*7509620bSJens Wiklander uint64_t b = 0; 61*7509620bSJens Wiklander 62*7509620bSJens Wiklander up->types = param_types; 63*7509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 64*7509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(up->types, n)) { 65*7509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INPUT: 66*7509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 67*7509620bSJens Wiklander a = params[n].value.a; 68*7509620bSJens Wiklander b = params[n].value.b; 69*7509620bSJens Wiklander break; 70*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 71*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 72*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INPUT: 73*7509620bSJens Wiklander a = (vaddr_t)params[n].memref.buffer; 74*7509620bSJens Wiklander b = params[n].memref.size; 75*7509620bSJens Wiklander break; 76*7509620bSJens Wiklander default: 77*7509620bSJens Wiklander a = 0; 78*7509620bSJens Wiklander b = 0; 79*7509620bSJens Wiklander } 80*7509620bSJens Wiklander up->vals[n * 2] = a; 81*7509620bSJens Wiklander up->vals[n * 2 + 1] = b; 82*7509620bSJens Wiklander } 83*7509620bSJens Wiklander } 84*7509620bSJens Wiklander 85*7509620bSJens Wiklander static TEE_Result map_tmp_param(struct utee_params *up, void **tmp_buf, 86*7509620bSJens 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; 107*7509620bSJens 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: 111*7509620bSJens Wiklander b = (void *)(vaddr_t)up->vals[n * 2]; 112*7509620bSJens 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++) { 142*7509620bSJens 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: 146*7509620bSJens Wiklander if (!is_tmp_mem[n]) 147*7509620bSJens Wiklander break; 148*7509620bSJens Wiklander s = up->vals[n * 2 + 1]; 149*7509620bSJens Wiklander b = (void *)(vaddr_t)up->vals[n * 2]; 150ef305e54SJens Wiklander tmp_va[n] = tb; 151ef305e54SJens Wiklander tb += ROUNDUP(s, tmp_align); 152*7509620bSJens Wiklander up->vals[n * 2] = (vaddr_t)tmp_va[n]; 153*7509620bSJens Wiklander if (TEE_PARAM_TYPE_GET(up->types, n) != 154ef305e54SJens Wiklander TEE_PARAM_TYPE_MEMREF_OUTPUT) 155*7509620bSJens 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; 163*7509620bSJens 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 196*7509620bSJens Wiklander static void update_out_gp11_param(__GP11_TEE_Param params[TEE_NUM_PARAMS], 197*7509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS], 198*7509620bSJens Wiklander const struct utee_params *up) 199*7509620bSJens Wiklander { 200*7509620bSJens Wiklander size_t n = 0; 201*7509620bSJens Wiklander uint32_t types = up->types; 202*7509620bSJens Wiklander 203*7509620bSJens Wiklander for (n = 0; n < TEE_NUM_PARAMS; n++) { 204*7509620bSJens Wiklander uintptr_t a = up->vals[n * 2]; 205*7509620bSJens Wiklander uintptr_t b = up->vals[n * 2 + 1]; 206*7509620bSJens Wiklander 207*7509620bSJens Wiklander switch (TEE_PARAM_TYPE_GET(types, n)) { 208*7509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_OUTPUT: 209*7509620bSJens Wiklander case TEE_PARAM_TYPE_VALUE_INOUT: 210*7509620bSJens Wiklander params[n].value.a = a; 211*7509620bSJens Wiklander params[n].value.b = b; 212*7509620bSJens Wiklander break; 213*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_OUTPUT: 214*7509620bSJens Wiklander case TEE_PARAM_TYPE_MEMREF_INOUT: 215*7509620bSJens Wiklander if (tmp_va[n]) 216*7509620bSJens Wiklander memcpy(params[n].memref.buffer, tmp_va[n], 217*7509620bSJens Wiklander MIN(b, params[n].memref.size)); 218*7509620bSJens Wiklander params[n].memref.size = b; 219*7509620bSJens Wiklander break; 220*7509620bSJens Wiklander default: 221*7509620bSJens Wiklander break; 222*7509620bSJens Wiklander } 223*7509620bSJens Wiklander } 224*7509620bSJens Wiklander } 225*7509620bSJens 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; 234*7509620bSJens 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 246*7509620bSJens Wiklander copy_param(&up, paramTypes, params); 247*7509620bSJens 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 273*7509620bSJens Wiklander TEE_Result __GP11_TEE_OpenTASession(const TEE_UUID *destination, 274*7509620bSJens Wiklander uint32_t cancellationRequestTimeout, 275*7509620bSJens Wiklander uint32_t paramTypes, 276*7509620bSJens Wiklander __GP11_TEE_Param params[TEE_NUM_PARAMS], 277*7509620bSJens Wiklander TEE_TASessionHandle *session, 278*7509620bSJens Wiklander uint32_t *returnOrigin) 279*7509620bSJens Wiklander { 280*7509620bSJens Wiklander TEE_Result res = TEE_SUCCESS; 281*7509620bSJens Wiklander struct utee_params up = { }; 282*7509620bSJens Wiklander uint32_t s = 0; 283*7509620bSJens Wiklander void *tmp_buf = NULL; 284*7509620bSJens Wiklander size_t tmp_len = 0; 285*7509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 286*7509620bSJens Wiklander 287*7509620bSJens Wiklander if (paramTypes) 288*7509620bSJens Wiklander __utee_check_inout_annotation(params, 289*7509620bSJens Wiklander sizeof(__GP11_TEE_Param) * 290*7509620bSJens Wiklander TEE_NUM_PARAMS); 291*7509620bSJens Wiklander __utee_check_out_annotation(session, sizeof(*session)); 292*7509620bSJens Wiklander 293*7509620bSJens Wiklander copy_gp11_param(&up, paramTypes, params); 294*7509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 295*7509620bSJens Wiklander if (res) 296*7509620bSJens Wiklander goto out; 297*7509620bSJens Wiklander res = _utee_open_ta_session(destination, cancellationRequestTimeout, 298*7509620bSJens Wiklander &up, &s, returnOrigin); 299*7509620bSJens Wiklander update_out_gp11_param(params, tmp_va, &up); 300*7509620bSJens Wiklander if (tmp_buf) { 301*7509620bSJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 302*7509620bSJens Wiklander 303*7509620bSJens Wiklander if (res2) 304*7509620bSJens Wiklander TEE_Panic(res2); 305*7509620bSJens Wiklander } 306*7509620bSJens Wiklander 307*7509620bSJens Wiklander out: 308*7509620bSJens Wiklander /* 309*7509620bSJens Wiklander * Specification says that *session must hold TEE_HANDLE_NULL if 310*7509620bSJens Wiklander * TEE_SUCCESS isn't returned. Set it here explicitly in case 311*7509620bSJens Wiklander * the syscall fails before out parameters has been updated. 312*7509620bSJens Wiklander */ 313*7509620bSJens Wiklander if (res != TEE_SUCCESS) 314*7509620bSJens Wiklander s = TEE_HANDLE_NULL; 315*7509620bSJens Wiklander 316*7509620bSJens Wiklander *session = (TEE_TASessionHandle)(uintptr_t)s; 317*7509620bSJens Wiklander return res; 318*7509620bSJens Wiklander } 319*7509620bSJens 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; 338*7509620bSJens 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 351*7509620bSJens Wiklander copy_param(&up, paramTypes, params); 352*7509620bSJens 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 381*7509620bSJens Wiklander TEE_Result __GP11_TEE_InvokeTACommand(TEE_TASessionHandle session, 382*7509620bSJens Wiklander uint32_t cancellationRequestTimeout, 383*7509620bSJens Wiklander uint32_t commandID, uint32_t paramTypes, 384*7509620bSJens Wiklander __GP11_TEE_Param params[TEE_NUM_PARAMS], 385*7509620bSJens Wiklander uint32_t *returnOrigin) 386*7509620bSJens Wiklander { 387*7509620bSJens Wiklander TEE_Result res = TEE_SUCCESS; 388*7509620bSJens Wiklander uint32_t ret_origin = TEE_ORIGIN_TEE; 389*7509620bSJens Wiklander struct utee_params up = { }; 390*7509620bSJens Wiklander void *tmp_buf = NULL; 391*7509620bSJens Wiklander size_t tmp_len = 0; 392*7509620bSJens Wiklander void *tmp_va[TEE_NUM_PARAMS] = { NULL }; 393*7509620bSJens Wiklander 394*7509620bSJens Wiklander if (paramTypes) 395*7509620bSJens Wiklander __utee_check_inout_annotation(params, 396*7509620bSJens Wiklander sizeof(__GP11_TEE_Param) * 397*7509620bSJens Wiklander TEE_NUM_PARAMS); 398*7509620bSJens Wiklander if (returnOrigin) 399*7509620bSJens Wiklander __utee_check_out_annotation(returnOrigin, 400*7509620bSJens Wiklander sizeof(*returnOrigin)); 401*7509620bSJens Wiklander 402*7509620bSJens Wiklander copy_gp11_param(&up, paramTypes, params); 403*7509620bSJens Wiklander res = map_tmp_param(&up, &tmp_buf, &tmp_len, tmp_va); 404*7509620bSJens Wiklander if (res) 405*7509620bSJens Wiklander goto out; 406*7509620bSJens Wiklander res = _utee_invoke_ta_command((uintptr_t)session, 407*7509620bSJens Wiklander cancellationRequestTimeout, 408*7509620bSJens Wiklander commandID, &up, &ret_origin); 409*7509620bSJens Wiklander update_out_gp11_param(params, tmp_va, &up); 410*7509620bSJens Wiklander if (tmp_buf) { 411*7509620bSJens Wiklander TEE_Result res2 = tee_unmap(tmp_buf, tmp_len); 412*7509620bSJens Wiklander 413*7509620bSJens Wiklander if (res2) 414*7509620bSJens Wiklander TEE_Panic(res2); 415*7509620bSJens Wiklander } 416*7509620bSJens Wiklander 417*7509620bSJens Wiklander out: 418*7509620bSJens Wiklander if (returnOrigin) 419*7509620bSJens Wiklander *returnOrigin = ret_origin; 420*7509620bSJens Wiklander 421*7509620bSJens Wiklander if (ret_origin == TEE_ORIGIN_TRUSTED_APP) 422*7509620bSJens Wiklander return res; 423*7509620bSJens Wiklander 424*7509620bSJens Wiklander if (res != TEE_SUCCESS && 425*7509620bSJens Wiklander res != TEE_ERROR_OUT_OF_MEMORY && 426*7509620bSJens Wiklander res != TEE_ERROR_TARGET_DEAD) 427*7509620bSJens Wiklander TEE_Panic(res); 428*7509620bSJens Wiklander 429*7509620bSJens Wiklander return res; 430*7509620bSJens Wiklander } 431*7509620bSJens 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, 46779a3c601SCedric Chaumont uint32_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 4898f07fe6fSJerome Forissier void TEE_SetInstanceData(const void *instanceData) 490b0104773SPascal Brand { 491b0104773SPascal Brand tee_api_instance_data = instanceData; 492b0104773SPascal Brand } 493b0104773SPascal Brand 4948f07fe6fSJerome Forissier const void *TEE_GetInstanceData(void) 495b0104773SPascal Brand { 496b0104773SPascal Brand return tee_api_instance_data; 497b0104773SPascal Brand } 498b0104773SPascal Brand 499b0104773SPascal Brand void *TEE_MemMove(void *dest, const void *src, uint32_t size) 500b0104773SPascal Brand { 501b0104773SPascal Brand return memmove(dest, src, size); 502b0104773SPascal Brand } 503b0104773SPascal Brand 504b0104773SPascal Brand int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size) 505b0104773SPascal Brand { 50665551e69SJerome Forissier return consttime_memcmp(buffer1, buffer2, size); 507b0104773SPascal Brand } 508b0104773SPascal Brand 50932c75600SJens Wiklander void TEE_MemFill(void *buff, uint32_t x, uint32_t size) 510b0104773SPascal Brand { 51132c75600SJens Wiklander memset(buff, x, size); 512b0104773SPascal Brand } 513b0104773SPascal Brand 514b0104773SPascal Brand /* Date & Time API */ 515b0104773SPascal Brand 516b0104773SPascal Brand void TEE_GetSystemTime(TEE_Time *time) 517b0104773SPascal Brand { 5182c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_SYSTEM, time); 519b0104773SPascal Brand 520b0104773SPascal Brand if (res != TEE_SUCCESS) 521b36311adSJerome Forissier TEE_Panic(res); 522b0104773SPascal Brand } 523b0104773SPascal Brand 524b0104773SPascal Brand TEE_Result TEE_Wait(uint32_t timeout) 525b0104773SPascal Brand { 5262c028fdeSJerome Forissier TEE_Result res = _utee_wait(timeout); 527b0104773SPascal Brand 528b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_CANCEL) 529b0104773SPascal Brand TEE_Panic(res); 530b0104773SPascal Brand 531b0104773SPascal Brand return res; 532b0104773SPascal Brand } 533b0104773SPascal Brand 534b0104773SPascal Brand TEE_Result TEE_GetTAPersistentTime(TEE_Time *time) 535b0104773SPascal Brand { 536b64d6909SCedric Chaumont TEE_Result res; 537b64d6909SCedric Chaumont 5382c028fdeSJerome Forissier res = _utee_get_time(UTEE_TIME_CAT_TA_PERSISTENT, time); 539b64d6909SCedric Chaumont 540b64d6909SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) { 541b64d6909SCedric Chaumont time->seconds = 0; 542b64d6909SCedric Chaumont time->millis = 0; 543b64d6909SCedric Chaumont } 544b64d6909SCedric Chaumont 545b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 546b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NOT_SET && 547b64d6909SCedric Chaumont res != TEE_ERROR_TIME_NEEDS_RESET && 548b64d6909SCedric Chaumont res != TEE_ERROR_OVERFLOW && 549b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY) 550b64d6909SCedric Chaumont TEE_Panic(res); 551b64d6909SCedric Chaumont 552b64d6909SCedric Chaumont return res; 553b0104773SPascal Brand } 554b0104773SPascal Brand 555b0104773SPascal Brand TEE_Result TEE_SetTAPersistentTime(const TEE_Time *time) 556b0104773SPascal Brand { 557b64d6909SCedric Chaumont TEE_Result res; 558b64d6909SCedric Chaumont 5592c028fdeSJerome Forissier res = _utee_set_ta_time(time); 560b64d6909SCedric Chaumont 561b64d6909SCedric Chaumont if (res != TEE_SUCCESS && 562b64d6909SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 563b64d6909SCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE) 564b64d6909SCedric Chaumont TEE_Panic(res); 565b64d6909SCedric Chaumont 566b64d6909SCedric Chaumont return res; 567b0104773SPascal Brand } 568b0104773SPascal Brand 569b0104773SPascal Brand void TEE_GetREETime(TEE_Time *time) 570b0104773SPascal Brand { 5712c028fdeSJerome Forissier TEE_Result res = _utee_get_time(UTEE_TIME_CAT_REE, time); 572b0104773SPascal Brand 573b0104773SPascal Brand if (res != TEE_SUCCESS) 574b36311adSJerome Forissier TEE_Panic(res); 575b0104773SPascal Brand } 576b0104773SPascal Brand 57779a3c601SCedric Chaumont void *TEE_Malloc(uint32_t len, uint32_t hint) 578b0104773SPascal Brand { 579a83ee50aSSadiq Hussain if (!len) 580a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 581a83ee50aSSadiq Hussain 58296c1d8c5SJens Wiklander if (hint == TEE_MALLOC_FILL_ZERO) 58396c1d8c5SJens Wiklander return calloc(1, len); 58496c1d8c5SJens Wiklander else if (hint == TEE_USER_MEM_HINT_NO_FILL_ZERO) 58596c1d8c5SJens Wiklander return malloc(len); 58696c1d8c5SJens Wiklander 58796c1d8c5SJens Wiklander EMSG("Invalid hint %#" PRIx32, hint); 58896c1d8c5SJens Wiklander 58996c1d8c5SJens Wiklander return NULL; 590b0104773SPascal Brand } 591b0104773SPascal Brand 592c0ce02edSJens Wiklander void *TEE_Realloc(void *buffer, uint32_t newSize) 593b0104773SPascal Brand { 594a83ee50aSSadiq Hussain if (!newSize) { 595a83ee50aSSadiq Hussain TEE_Free(buffer); 596a83ee50aSSadiq Hussain return TEE_NULL_SIZED_VA; 597a83ee50aSSadiq Hussain } 598a83ee50aSSadiq Hussain 599a83ee50aSSadiq Hussain if (buffer == TEE_NULL_SIZED_VA) 600a83ee50aSSadiq Hussain return calloc(1, newSize); 601a83ee50aSSadiq Hussain 60296c1d8c5SJens Wiklander return realloc(buffer, newSize); 603b0104773SPascal Brand } 604b0104773SPascal Brand 605b0104773SPascal Brand void TEE_Free(void *buffer) 606b0104773SPascal Brand { 607a83ee50aSSadiq Hussain if (buffer != TEE_NULL_SIZED_VA) 60896c1d8c5SJens Wiklander free(buffer); 609b0104773SPascal Brand } 610fa530828SPascal Brand 611fa530828SPascal Brand /* Cache maintenance support (TA requires the CACHE_MAINTENANCE property) */ 612fa530828SPascal Brand TEE_Result TEE_CacheClean(char *buf, size_t len) 613fa530828SPascal Brand { 6142c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHECLEAN); 615fa530828SPascal Brand } 616fa530828SPascal Brand TEE_Result TEE_CacheFlush(char *buf, size_t len) 617fa530828SPascal Brand { 6182c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEFLUSH); 619fa530828SPascal Brand } 620fa530828SPascal Brand 621fa530828SPascal Brand TEE_Result TEE_CacheInvalidate(char *buf, size_t len) 622fa530828SPascal Brand { 6232c028fdeSJerome Forissier return _utee_cache_operation(buf, len, TEE_CACHEINVALIDATE); 624fa530828SPascal Brand } 625