1*25c76675SMarouene Boubakri // SPDX-License-Identifier: BSD-2-Clause 2*25c76675SMarouene Boubakri /* 3*25c76675SMarouene Boubakri * Copyright (c) 2015-2016, Linaro Limited 4*25c76675SMarouene Boubakri * Copyright (c) 2014, STMicroelectronics International N.V. 5*25c76675SMarouene Boubakri */ 6*25c76675SMarouene Boubakri 7*25c76675SMarouene Boubakri #include <assert.h> 8*25c76675SMarouene Boubakri #include <bench.h> 9*25c76675SMarouene Boubakri #include <compiler.h> 10*25c76675SMarouene Boubakri #include <initcall.h> 11*25c76675SMarouene Boubakri #include <io.h> 12*25c76675SMarouene Boubakri #include <kernel/linker.h> 13*25c76675SMarouene Boubakri #include <kernel/msg_param.h> 14*25c76675SMarouene Boubakri #include <kernel/panic.h> 15*25c76675SMarouene Boubakri #include <kernel/tee_misc.h> 16*25c76675SMarouene Boubakri #include <mm/core_memprot.h> 17*25c76675SMarouene Boubakri #include <mm/core_mmu.h> 18*25c76675SMarouene Boubakri #include <mm/mobj.h> 19*25c76675SMarouene Boubakri #include <optee_msg.h> 20*25c76675SMarouene Boubakri #include <sm/optee_smc.h> 21*25c76675SMarouene Boubakri #include <string.h> 22*25c76675SMarouene Boubakri #include <tee/entry_std.h> 23*25c76675SMarouene Boubakri #include <tee/tee_cryp_utl.h> 24*25c76675SMarouene Boubakri #include <tee/uuid.h> 25*25c76675SMarouene Boubakri #include <util.h> 26*25c76675SMarouene Boubakri 27*25c76675SMarouene Boubakri #define SHM_CACHE_ATTRS \ 28*25c76675SMarouene Boubakri (uint32_t)(core_mmu_is_shm_cached() ? OPTEE_SMC_SHM_CACHED : 0) 29*25c76675SMarouene Boubakri 30*25c76675SMarouene Boubakri /* Sessions opened from normal world */ 31*25c76675SMarouene Boubakri static struct tee_ta_session_head tee_open_sessions = 32*25c76675SMarouene Boubakri TAILQ_HEAD_INITIALIZER(tee_open_sessions); 33*25c76675SMarouene Boubakri 34*25c76675SMarouene Boubakri #ifdef CFG_CORE_RESERVED_SHM 35*25c76675SMarouene Boubakri static struct mobj *shm_mobj; 36*25c76675SMarouene Boubakri #endif 37*25c76675SMarouene Boubakri #ifdef CFG_SECURE_DATA_PATH 38*25c76675SMarouene Boubakri static struct mobj **sdp_mem_mobjs; 39*25c76675SMarouene Boubakri #endif 40*25c76675SMarouene Boubakri 41*25c76675SMarouene Boubakri static unsigned int session_pnum; 42*25c76675SMarouene Boubakri 43*25c76675SMarouene Boubakri static bool __maybe_unused param_mem_from_mobj(struct param_mem *mem, 44*25c76675SMarouene Boubakri struct mobj *mobj, 45*25c76675SMarouene Boubakri const paddr_t pa, 46*25c76675SMarouene Boubakri const size_t sz) 47*25c76675SMarouene Boubakri { 48*25c76675SMarouene Boubakri paddr_t b; 49*25c76675SMarouene Boubakri 50*25c76675SMarouene Boubakri if (mobj_get_pa(mobj, 0, 0, &b) != TEE_SUCCESS) 51*25c76675SMarouene Boubakri panic("mobj_get_pa failed"); 52*25c76675SMarouene Boubakri 53*25c76675SMarouene Boubakri if (!core_is_buffer_inside(pa, MAX(sz, 1UL), b, mobj->size)) 54*25c76675SMarouene Boubakri return false; 55*25c76675SMarouene Boubakri 56*25c76675SMarouene Boubakri mem->mobj = mobj_get(mobj); 57*25c76675SMarouene Boubakri mem->offs = pa - b; 58*25c76675SMarouene Boubakri mem->size = sz; 59*25c76675SMarouene Boubakri return true; 60*25c76675SMarouene Boubakri } 61*25c76675SMarouene Boubakri 62*25c76675SMarouene Boubakri #ifdef CFG_CORE_FFA 63*25c76675SMarouene Boubakri static TEE_Result set_fmem_param(const struct optee_msg_param_fmem *fmem, 64*25c76675SMarouene Boubakri struct param_mem *mem) 65*25c76675SMarouene Boubakri { 66*25c76675SMarouene Boubakri size_t req_size = 0; 67*25c76675SMarouene Boubakri uint64_t global_id = READ_ONCE(fmem->global_id); 68*25c76675SMarouene Boubakri size_t sz = READ_ONCE(fmem->size); 69*25c76675SMarouene Boubakri 70*25c76675SMarouene Boubakri if (!global_id && !sz) { 71*25c76675SMarouene Boubakri mem->mobj = NULL; 72*25c76675SMarouene Boubakri mem->offs = 0; 73*25c76675SMarouene Boubakri mem->size = 0; 74*25c76675SMarouene Boubakri return TEE_SUCCESS; 75*25c76675SMarouene Boubakri } 76*25c76675SMarouene Boubakri mem->mobj = mobj_ffa_get_by_cookie(global_id, 77*25c76675SMarouene Boubakri READ_ONCE(fmem->internal_offs)); 78*25c76675SMarouene Boubakri if (!mem->mobj) 79*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 80*25c76675SMarouene Boubakri 81*25c76675SMarouene Boubakri mem->offs = reg_pair_to_64(READ_ONCE(fmem->offs_high), 82*25c76675SMarouene Boubakri READ_ONCE(fmem->offs_low)); 83*25c76675SMarouene Boubakri mem->size = sz; 84*25c76675SMarouene Boubakri 85*25c76675SMarouene Boubakri /* 86*25c76675SMarouene Boubakri * Check that the supplied offset and size is covered by the 87*25c76675SMarouene Boubakri * previously verified MOBJ. 88*25c76675SMarouene Boubakri */ 89*25c76675SMarouene Boubakri if (ADD_OVERFLOW(mem->offs, mem->size, &req_size) || 90*25c76675SMarouene Boubakri mem->mobj->size < req_size) 91*25c76675SMarouene Boubakri return TEE_ERROR_SECURITY; 92*25c76675SMarouene Boubakri 93*25c76675SMarouene Boubakri return TEE_SUCCESS; 94*25c76675SMarouene Boubakri } 95*25c76675SMarouene Boubakri #else /*!CFG_CORE_FFA*/ 96*25c76675SMarouene Boubakri /* fill 'struct param_mem' structure if buffer matches a valid memory object */ 97*25c76675SMarouene Boubakri static TEE_Result set_tmem_param(const struct optee_msg_param_tmem *tmem, 98*25c76675SMarouene Boubakri uint32_t attr, struct param_mem *mem) 99*25c76675SMarouene Boubakri { 100*25c76675SMarouene Boubakri struct mobj __maybe_unused **mobj; 101*25c76675SMarouene Boubakri paddr_t pa = READ_ONCE(tmem->buf_ptr); 102*25c76675SMarouene Boubakri size_t sz = READ_ONCE(tmem->size); 103*25c76675SMarouene Boubakri 104*25c76675SMarouene Boubakri /* 105*25c76675SMarouene Boubakri * Handle NULL memory reference 106*25c76675SMarouene Boubakri */ 107*25c76675SMarouene Boubakri if (!pa) { 108*25c76675SMarouene Boubakri mem->mobj = NULL; 109*25c76675SMarouene Boubakri mem->offs = 0; 110*25c76675SMarouene Boubakri mem->size = 0; 111*25c76675SMarouene Boubakri return TEE_SUCCESS; 112*25c76675SMarouene Boubakri } 113*25c76675SMarouene Boubakri 114*25c76675SMarouene Boubakri /* Handle non-contiguous reference from a shared memory area */ 115*25c76675SMarouene Boubakri if (attr & OPTEE_MSG_ATTR_NONCONTIG) { 116*25c76675SMarouene Boubakri uint64_t shm_ref = READ_ONCE(tmem->shm_ref); 117*25c76675SMarouene Boubakri 118*25c76675SMarouene Boubakri mem->mobj = msg_param_mobj_from_noncontig(pa, sz, shm_ref, 119*25c76675SMarouene Boubakri false); 120*25c76675SMarouene Boubakri if (!mem->mobj) 121*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 122*25c76675SMarouene Boubakri mem->offs = 0; 123*25c76675SMarouene Boubakri mem->size = sz; 124*25c76675SMarouene Boubakri return TEE_SUCCESS; 125*25c76675SMarouene Boubakri } 126*25c76675SMarouene Boubakri 127*25c76675SMarouene Boubakri #ifdef CFG_CORE_RESERVED_SHM 128*25c76675SMarouene Boubakri /* Handle memory reference in the contiguous shared memory */ 129*25c76675SMarouene Boubakri if (param_mem_from_mobj(mem, shm_mobj, pa, sz)) 130*25c76675SMarouene Boubakri return TEE_SUCCESS; 131*25c76675SMarouene Boubakri #endif 132*25c76675SMarouene Boubakri 133*25c76675SMarouene Boubakri #ifdef CFG_SECURE_DATA_PATH 134*25c76675SMarouene Boubakri /* Handle memory reference to Secure Data Path memory areas */ 135*25c76675SMarouene Boubakri for (mobj = sdp_mem_mobjs; *mobj; mobj++) 136*25c76675SMarouene Boubakri if (param_mem_from_mobj(mem, *mobj, pa, sz)) 137*25c76675SMarouene Boubakri return TEE_SUCCESS; 138*25c76675SMarouene Boubakri #endif 139*25c76675SMarouene Boubakri 140*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 141*25c76675SMarouene Boubakri } 142*25c76675SMarouene Boubakri 143*25c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM 144*25c76675SMarouene Boubakri static TEE_Result set_rmem_param(const struct optee_msg_param_rmem *rmem, 145*25c76675SMarouene Boubakri struct param_mem *mem) 146*25c76675SMarouene Boubakri { 147*25c76675SMarouene Boubakri size_t req_size = 0; 148*25c76675SMarouene Boubakri uint64_t shm_ref = READ_ONCE(rmem->shm_ref); 149*25c76675SMarouene Boubakri size_t sz = READ_ONCE(rmem->size); 150*25c76675SMarouene Boubakri 151*25c76675SMarouene Boubakri mem->mobj = mobj_reg_shm_get_by_cookie(shm_ref); 152*25c76675SMarouene Boubakri if (!mem->mobj) 153*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 154*25c76675SMarouene Boubakri 155*25c76675SMarouene Boubakri mem->offs = READ_ONCE(rmem->offs); 156*25c76675SMarouene Boubakri mem->size = sz; 157*25c76675SMarouene Boubakri 158*25c76675SMarouene Boubakri /* 159*25c76675SMarouene Boubakri * Check that the supplied offset and size is covered by the 160*25c76675SMarouene Boubakri * previously verified MOBJ. 161*25c76675SMarouene Boubakri */ 162*25c76675SMarouene Boubakri if (ADD_OVERFLOW(mem->offs, mem->size, &req_size) || 163*25c76675SMarouene Boubakri mem->mobj->size < req_size) 164*25c76675SMarouene Boubakri return TEE_ERROR_SECURITY; 165*25c76675SMarouene Boubakri 166*25c76675SMarouene Boubakri return TEE_SUCCESS; 167*25c76675SMarouene Boubakri } 168*25c76675SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/ 169*25c76675SMarouene Boubakri #endif /*!CFG_CORE_FFA*/ 170*25c76675SMarouene Boubakri 171*25c76675SMarouene Boubakri static TEE_Result copy_in_params(const struct optee_msg_param *params, 172*25c76675SMarouene Boubakri uint32_t num_params, 173*25c76675SMarouene Boubakri struct tee_ta_param *ta_param, 174*25c76675SMarouene Boubakri uint64_t *saved_attr) 175*25c76675SMarouene Boubakri { 176*25c76675SMarouene Boubakri TEE_Result res; 177*25c76675SMarouene Boubakri size_t n; 178*25c76675SMarouene Boubakri uint8_t pt[TEE_NUM_PARAMS] = { 0 }; 179*25c76675SMarouene Boubakri 180*25c76675SMarouene Boubakri if (num_params > TEE_NUM_PARAMS) 181*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 182*25c76675SMarouene Boubakri 183*25c76675SMarouene Boubakri memset(ta_param, 0, sizeof(*ta_param)); 184*25c76675SMarouene Boubakri 185*25c76675SMarouene Boubakri for (n = 0; n < num_params; n++) { 186*25c76675SMarouene Boubakri uint32_t attr; 187*25c76675SMarouene Boubakri 188*25c76675SMarouene Boubakri saved_attr[n] = READ_ONCE(params[n].attr); 189*25c76675SMarouene Boubakri 190*25c76675SMarouene Boubakri if (saved_attr[n] & OPTEE_MSG_ATTR_META) 191*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 192*25c76675SMarouene Boubakri 193*25c76675SMarouene Boubakri attr = saved_attr[n] & OPTEE_MSG_ATTR_TYPE_MASK; 194*25c76675SMarouene Boubakri switch (attr) { 195*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_NONE: 196*25c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_NONE; 197*25c76675SMarouene Boubakri break; 198*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT: 199*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT: 200*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT: 201*25c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_VALUE_INPUT + attr - 202*25c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; 203*25c76675SMarouene Boubakri ta_param->u[n].val.a = READ_ONCE(params[n].u.value.a); 204*25c76675SMarouene Boubakri ta_param->u[n].val.b = READ_ONCE(params[n].u.value.b); 205*25c76675SMarouene Boubakri break; 206*25c76675SMarouene Boubakri #ifdef CFG_CORE_FFA 207*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT: 208*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT: 209*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT: 210*25c76675SMarouene Boubakri res = set_fmem_param(¶ms[n].u.fmem, 211*25c76675SMarouene Boubakri &ta_param->u[n].mem); 212*25c76675SMarouene Boubakri if (res) 213*25c76675SMarouene Boubakri return res; 214*25c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr - 215*25c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_FMEM_INPUT; 216*25c76675SMarouene Boubakri break; 217*25c76675SMarouene Boubakri #else /*!CFG_CORE_FFA*/ 218*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: 219*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: 220*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: 221*25c76675SMarouene Boubakri res = set_tmem_param(¶ms[n].u.tmem, saved_attr[n], 222*25c76675SMarouene Boubakri &ta_param->u[n].mem); 223*25c76675SMarouene Boubakri if (res) 224*25c76675SMarouene Boubakri return res; 225*25c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr - 226*25c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; 227*25c76675SMarouene Boubakri break; 228*25c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM 229*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT: 230*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT: 231*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT: 232*25c76675SMarouene Boubakri res = set_rmem_param(¶ms[n].u.rmem, 233*25c76675SMarouene Boubakri &ta_param->u[n].mem); 234*25c76675SMarouene Boubakri if (res) 235*25c76675SMarouene Boubakri return res; 236*25c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr - 237*25c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_RMEM_INPUT; 238*25c76675SMarouene Boubakri break; 239*25c76675SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/ 240*25c76675SMarouene Boubakri #endif /*!CFG_CORE_FFA*/ 241*25c76675SMarouene Boubakri default: 242*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 243*25c76675SMarouene Boubakri } 244*25c76675SMarouene Boubakri } 245*25c76675SMarouene Boubakri 246*25c76675SMarouene Boubakri ta_param->types = TEE_PARAM_TYPES(pt[0], pt[1], pt[2], pt[3]); 247*25c76675SMarouene Boubakri 248*25c76675SMarouene Boubakri return TEE_SUCCESS; 249*25c76675SMarouene Boubakri } 250*25c76675SMarouene Boubakri 251*25c76675SMarouene Boubakri static void cleanup_shm_refs(const uint64_t *saved_attr, 252*25c76675SMarouene Boubakri struct tee_ta_param *param, uint32_t num_params) 253*25c76675SMarouene Boubakri { 254*25c76675SMarouene Boubakri size_t n; 255*25c76675SMarouene Boubakri 256*25c76675SMarouene Boubakri for (n = 0; n < num_params; n++) { 257*25c76675SMarouene Boubakri switch (saved_attr[n]) { 258*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: 259*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: 260*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: 261*25c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM 262*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT: 263*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT: 264*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT: 265*25c76675SMarouene Boubakri #endif 266*25c76675SMarouene Boubakri mobj_put(param->u[n].mem.mobj); 267*25c76675SMarouene Boubakri break; 268*25c76675SMarouene Boubakri default: 269*25c76675SMarouene Boubakri break; 270*25c76675SMarouene Boubakri } 271*25c76675SMarouene Boubakri } 272*25c76675SMarouene Boubakri } 273*25c76675SMarouene Boubakri 274*25c76675SMarouene Boubakri static void copy_out_param(struct tee_ta_param *ta_param, uint32_t num_params, 275*25c76675SMarouene Boubakri struct optee_msg_param *params, uint64_t *saved_attr) 276*25c76675SMarouene Boubakri { 277*25c76675SMarouene Boubakri size_t n; 278*25c76675SMarouene Boubakri 279*25c76675SMarouene Boubakri for (n = 0; n < num_params; n++) { 280*25c76675SMarouene Boubakri switch (TEE_PARAM_TYPE_GET(ta_param->types, n)) { 281*25c76675SMarouene Boubakri case TEE_PARAM_TYPE_MEMREF_OUTPUT: 282*25c76675SMarouene Boubakri case TEE_PARAM_TYPE_MEMREF_INOUT: 283*25c76675SMarouene Boubakri switch (saved_attr[n] & OPTEE_MSG_ATTR_TYPE_MASK) { 284*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: 285*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: 286*25c76675SMarouene Boubakri params[n].u.tmem.size = ta_param->u[n].mem.size; 287*25c76675SMarouene Boubakri break; 288*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT: 289*25c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT: 290*25c76675SMarouene Boubakri params[n].u.rmem.size = ta_param->u[n].mem.size; 291*25c76675SMarouene Boubakri break; 292*25c76675SMarouene Boubakri default: 293*25c76675SMarouene Boubakri break; 294*25c76675SMarouene Boubakri } 295*25c76675SMarouene Boubakri break; 296*25c76675SMarouene Boubakri case TEE_PARAM_TYPE_VALUE_OUTPUT: 297*25c76675SMarouene Boubakri case TEE_PARAM_TYPE_VALUE_INOUT: 298*25c76675SMarouene Boubakri params[n].u.value.a = ta_param->u[n].val.a; 299*25c76675SMarouene Boubakri params[n].u.value.b = ta_param->u[n].val.b; 300*25c76675SMarouene Boubakri break; 301*25c76675SMarouene Boubakri default: 302*25c76675SMarouene Boubakri break; 303*25c76675SMarouene Boubakri } 304*25c76675SMarouene Boubakri } 305*25c76675SMarouene Boubakri } 306*25c76675SMarouene Boubakri 307*25c76675SMarouene Boubakri /* 308*25c76675SMarouene Boubakri * Extracts mandatory parameter for open session. 309*25c76675SMarouene Boubakri * 310*25c76675SMarouene Boubakri * Returns 311*25c76675SMarouene Boubakri * false : mandatory parameter wasn't found or malformatted 312*25c76675SMarouene Boubakri * true : paramater found and OK 313*25c76675SMarouene Boubakri */ 314*25c76675SMarouene Boubakri static TEE_Result get_open_session_meta(size_t num_params, 315*25c76675SMarouene Boubakri struct optee_msg_param *params, 316*25c76675SMarouene Boubakri size_t *num_meta, TEE_UUID *uuid, 317*25c76675SMarouene Boubakri TEE_Identity *clnt_id) 318*25c76675SMarouene Boubakri { 319*25c76675SMarouene Boubakri const uint32_t req_attr = OPTEE_MSG_ATTR_META | 320*25c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; 321*25c76675SMarouene Boubakri 322*25c76675SMarouene Boubakri if (num_params < 2) 323*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 324*25c76675SMarouene Boubakri 325*25c76675SMarouene Boubakri if (params[0].attr != req_attr || params[1].attr != req_attr) 326*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 327*25c76675SMarouene Boubakri 328*25c76675SMarouene Boubakri tee_uuid_from_octets(uuid, (void *)¶ms[0].u.value); 329*25c76675SMarouene Boubakri clnt_id->login = params[1].u.value.c; 330*25c76675SMarouene Boubakri switch (clnt_id->login) { 331*25c76675SMarouene Boubakri case TEE_LOGIN_PUBLIC: 332*25c76675SMarouene Boubakri case TEE_LOGIN_REE_KERNEL: 333*25c76675SMarouene Boubakri memset(&clnt_id->uuid, 0, sizeof(clnt_id->uuid)); 334*25c76675SMarouene Boubakri break; 335*25c76675SMarouene Boubakri case TEE_LOGIN_USER: 336*25c76675SMarouene Boubakri case TEE_LOGIN_GROUP: 337*25c76675SMarouene Boubakri case TEE_LOGIN_APPLICATION: 338*25c76675SMarouene Boubakri case TEE_LOGIN_APPLICATION_USER: 339*25c76675SMarouene Boubakri case TEE_LOGIN_APPLICATION_GROUP: 340*25c76675SMarouene Boubakri tee_uuid_from_octets(&clnt_id->uuid, 341*25c76675SMarouene Boubakri (void *)¶ms[1].u.value); 342*25c76675SMarouene Boubakri break; 343*25c76675SMarouene Boubakri default: 344*25c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS; 345*25c76675SMarouene Boubakri } 346*25c76675SMarouene Boubakri 347*25c76675SMarouene Boubakri *num_meta = 2; 348*25c76675SMarouene Boubakri return TEE_SUCCESS; 349*25c76675SMarouene Boubakri } 350*25c76675SMarouene Boubakri 351*25c76675SMarouene Boubakri static void entry_open_session(struct optee_msg_arg *arg, uint32_t num_params) 352*25c76675SMarouene Boubakri { 353*25c76675SMarouene Boubakri TEE_Result res; 354*25c76675SMarouene Boubakri TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE; 355*25c76675SMarouene Boubakri struct tee_ta_session *s = NULL; 356*25c76675SMarouene Boubakri TEE_Identity clnt_id; 357*25c76675SMarouene Boubakri TEE_UUID uuid; 358*25c76675SMarouene Boubakri struct tee_ta_param param; 359*25c76675SMarouene Boubakri size_t num_meta; 360*25c76675SMarouene Boubakri uint64_t saved_attr[TEE_NUM_PARAMS] = { 0 }; 361*25c76675SMarouene Boubakri 362*25c76675SMarouene Boubakri res = get_open_session_meta(num_params, arg->params, &num_meta, &uuid, 363*25c76675SMarouene Boubakri &clnt_id); 364*25c76675SMarouene Boubakri if (res != TEE_SUCCESS) 365*25c76675SMarouene Boubakri goto out; 366*25c76675SMarouene Boubakri 367*25c76675SMarouene Boubakri res = copy_in_params(arg->params + num_meta, num_params - num_meta, 368*25c76675SMarouene Boubakri ¶m, saved_attr); 369*25c76675SMarouene Boubakri if (res != TEE_SUCCESS) 370*25c76675SMarouene Boubakri goto cleanup_shm_refs; 371*25c76675SMarouene Boubakri 372*25c76675SMarouene Boubakri res = tee_ta_open_session(&err_orig, &s, &tee_open_sessions, &uuid, 373*25c76675SMarouene Boubakri &clnt_id, TEE_TIMEOUT_INFINITE, ¶m); 374*25c76675SMarouene Boubakri if (res != TEE_SUCCESS) 375*25c76675SMarouene Boubakri s = NULL; 376*25c76675SMarouene Boubakri copy_out_param(¶m, num_params - num_meta, arg->params + num_meta, 377*25c76675SMarouene Boubakri saved_attr); 378*25c76675SMarouene Boubakri 379*25c76675SMarouene Boubakri /* 380*25c76675SMarouene Boubakri * The occurrence of open/close session command is usually 381*25c76675SMarouene Boubakri * un-predictable, using this property to increase randomness 382*25c76675SMarouene Boubakri * of prng 383*25c76675SMarouene Boubakri */ 384*25c76675SMarouene Boubakri plat_prng_add_jitter_entropy(CRYPTO_RNG_SRC_JITTER_SESSION, 385*25c76675SMarouene Boubakri &session_pnum); 386*25c76675SMarouene Boubakri 387*25c76675SMarouene Boubakri cleanup_shm_refs: 388*25c76675SMarouene Boubakri cleanup_shm_refs(saved_attr, ¶m, num_params - num_meta); 389*25c76675SMarouene Boubakri 390*25c76675SMarouene Boubakri out: 391*25c76675SMarouene Boubakri if (s) 392*25c76675SMarouene Boubakri arg->session = s->id; 393*25c76675SMarouene Boubakri else 394*25c76675SMarouene Boubakri arg->session = 0; 395*25c76675SMarouene Boubakri arg->ret = res; 396*25c76675SMarouene Boubakri arg->ret_origin = err_orig; 397*25c76675SMarouene Boubakri } 398*25c76675SMarouene Boubakri 399*25c76675SMarouene Boubakri static void entry_close_session(struct optee_msg_arg *arg, uint32_t num_params) 400*25c76675SMarouene Boubakri { 401*25c76675SMarouene Boubakri TEE_Result res; 402*25c76675SMarouene Boubakri struct tee_ta_session *s; 403*25c76675SMarouene Boubakri 404*25c76675SMarouene Boubakri if (num_params) { 405*25c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS; 406*25c76675SMarouene Boubakri goto out; 407*25c76675SMarouene Boubakri } 408*25c76675SMarouene Boubakri 409*25c76675SMarouene Boubakri plat_prng_add_jitter_entropy(CRYPTO_RNG_SRC_JITTER_SESSION, 410*25c76675SMarouene Boubakri &session_pnum); 411*25c76675SMarouene Boubakri 412*25c76675SMarouene Boubakri s = tee_ta_find_session(arg->session, &tee_open_sessions); 413*25c76675SMarouene Boubakri res = tee_ta_close_session(s, &tee_open_sessions, NSAPP_IDENTITY); 414*25c76675SMarouene Boubakri out: 415*25c76675SMarouene Boubakri arg->ret = res; 416*25c76675SMarouene Boubakri arg->ret_origin = TEE_ORIGIN_TEE; 417*25c76675SMarouene Boubakri } 418*25c76675SMarouene Boubakri 419*25c76675SMarouene Boubakri static void entry_invoke_command(struct optee_msg_arg *arg, uint32_t num_params) 420*25c76675SMarouene Boubakri { 421*25c76675SMarouene Boubakri TEE_Result res; 422*25c76675SMarouene Boubakri TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE; 423*25c76675SMarouene Boubakri struct tee_ta_session *s; 424*25c76675SMarouene Boubakri struct tee_ta_param param = { 0 }; 425*25c76675SMarouene Boubakri uint64_t saved_attr[TEE_NUM_PARAMS] = { 0 }; 426*25c76675SMarouene Boubakri 427*25c76675SMarouene Boubakri bm_timestamp(); 428*25c76675SMarouene Boubakri 429*25c76675SMarouene Boubakri res = copy_in_params(arg->params, num_params, ¶m, saved_attr); 430*25c76675SMarouene Boubakri if (res != TEE_SUCCESS) 431*25c76675SMarouene Boubakri goto out; 432*25c76675SMarouene Boubakri 433*25c76675SMarouene Boubakri s = tee_ta_get_session(arg->session, true, &tee_open_sessions); 434*25c76675SMarouene Boubakri if (!s) { 435*25c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS; 436*25c76675SMarouene Boubakri goto out; 437*25c76675SMarouene Boubakri } 438*25c76675SMarouene Boubakri 439*25c76675SMarouene Boubakri res = tee_ta_invoke_command(&err_orig, s, NSAPP_IDENTITY, 440*25c76675SMarouene Boubakri TEE_TIMEOUT_INFINITE, arg->func, ¶m); 441*25c76675SMarouene Boubakri 442*25c76675SMarouene Boubakri bm_timestamp(); 443*25c76675SMarouene Boubakri 444*25c76675SMarouene Boubakri tee_ta_put_session(s); 445*25c76675SMarouene Boubakri 446*25c76675SMarouene Boubakri copy_out_param(¶m, num_params, arg->params, saved_attr); 447*25c76675SMarouene Boubakri 448*25c76675SMarouene Boubakri out: 449*25c76675SMarouene Boubakri cleanup_shm_refs(saved_attr, ¶m, num_params); 450*25c76675SMarouene Boubakri 451*25c76675SMarouene Boubakri arg->ret = res; 452*25c76675SMarouene Boubakri arg->ret_origin = err_orig; 453*25c76675SMarouene Boubakri } 454*25c76675SMarouene Boubakri 455*25c76675SMarouene Boubakri static void entry_cancel(struct optee_msg_arg *arg, uint32_t num_params) 456*25c76675SMarouene Boubakri { 457*25c76675SMarouene Boubakri TEE_Result res; 458*25c76675SMarouene Boubakri TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE; 459*25c76675SMarouene Boubakri struct tee_ta_session *s; 460*25c76675SMarouene Boubakri 461*25c76675SMarouene Boubakri if (num_params) { 462*25c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS; 463*25c76675SMarouene Boubakri goto out; 464*25c76675SMarouene Boubakri } 465*25c76675SMarouene Boubakri 466*25c76675SMarouene Boubakri s = tee_ta_get_session(arg->session, false, &tee_open_sessions); 467*25c76675SMarouene Boubakri if (!s) { 468*25c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS; 469*25c76675SMarouene Boubakri goto out; 470*25c76675SMarouene Boubakri } 471*25c76675SMarouene Boubakri 472*25c76675SMarouene Boubakri res = tee_ta_cancel_command(&err_orig, s, NSAPP_IDENTITY); 473*25c76675SMarouene Boubakri tee_ta_put_session(s); 474*25c76675SMarouene Boubakri 475*25c76675SMarouene Boubakri out: 476*25c76675SMarouene Boubakri arg->ret = res; 477*25c76675SMarouene Boubakri arg->ret_origin = err_orig; 478*25c76675SMarouene Boubakri } 479*25c76675SMarouene Boubakri 480*25c76675SMarouene Boubakri #ifndef CFG_CORE_FFA 481*25c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM 482*25c76675SMarouene Boubakri static void register_shm(struct optee_msg_arg *arg, uint32_t num_params) 483*25c76675SMarouene Boubakri { 484*25c76675SMarouene Boubakri arg->ret = TEE_ERROR_BAD_PARAMETERS; 485*25c76675SMarouene Boubakri 486*25c76675SMarouene Boubakri if (num_params != 1 || 487*25c76675SMarouene Boubakri (arg->params[0].attr != 488*25c76675SMarouene Boubakri (OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_NONCONTIG))) 489*25c76675SMarouene Boubakri return; 490*25c76675SMarouene Boubakri 491*25c76675SMarouene Boubakri struct optee_msg_param_tmem *tmem = &arg->params[0].u.tmem; 492*25c76675SMarouene Boubakri struct mobj *mobj = msg_param_mobj_from_noncontig(tmem->buf_ptr, 493*25c76675SMarouene Boubakri tmem->size, 494*25c76675SMarouene Boubakri tmem->shm_ref, false); 495*25c76675SMarouene Boubakri 496*25c76675SMarouene Boubakri if (!mobj) 497*25c76675SMarouene Boubakri return; 498*25c76675SMarouene Boubakri 499*25c76675SMarouene Boubakri mobj_reg_shm_unguard(mobj); 500*25c76675SMarouene Boubakri arg->ret = TEE_SUCCESS; 501*25c76675SMarouene Boubakri } 502*25c76675SMarouene Boubakri 503*25c76675SMarouene Boubakri static void unregister_shm(struct optee_msg_arg *arg, uint32_t num_params) 504*25c76675SMarouene Boubakri { 505*25c76675SMarouene Boubakri if (num_params == 1) { 506*25c76675SMarouene Boubakri uint64_t cookie = arg->params[0].u.rmem.shm_ref; 507*25c76675SMarouene Boubakri TEE_Result res = mobj_reg_shm_release_by_cookie(cookie); 508*25c76675SMarouene Boubakri 509*25c76675SMarouene Boubakri if (res) 510*25c76675SMarouene Boubakri EMSG("Can't find mapping with given cookie"); 511*25c76675SMarouene Boubakri arg->ret = res; 512*25c76675SMarouene Boubakri } else { 513*25c76675SMarouene Boubakri arg->ret = TEE_ERROR_BAD_PARAMETERS; 514*25c76675SMarouene Boubakri arg->ret_origin = TEE_ORIGIN_TEE; 515*25c76675SMarouene Boubakri } 516*25c76675SMarouene Boubakri } 517*25c76675SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/ 518*25c76675SMarouene Boubakri #endif 519*25c76675SMarouene Boubakri 520*25c76675SMarouene Boubakri void nsec_sessions_list_head(struct tee_ta_session_head **open_sessions) 521*25c76675SMarouene Boubakri { 522*25c76675SMarouene Boubakri *open_sessions = &tee_open_sessions; 523*25c76675SMarouene Boubakri } 524*25c76675SMarouene Boubakri 525*25c76675SMarouene Boubakri /* Note: this function is weak to let platforms add special handling */ 526*25c76675SMarouene Boubakri uint32_t __weak tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params) 527*25c76675SMarouene Boubakri { 528*25c76675SMarouene Boubakri return __tee_entry_std(arg, num_params); 529*25c76675SMarouene Boubakri } 530*25c76675SMarouene Boubakri 531*25c76675SMarouene Boubakri /* 532*25c76675SMarouene Boubakri * If tee_entry_std() is overridden, it's still supposed to call this 533*25c76675SMarouene Boubakri * function. 534*25c76675SMarouene Boubakri */ 535*25c76675SMarouene Boubakri uint32_t __tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params) 536*25c76675SMarouene Boubakri { 537*25c76675SMarouene Boubakri uint32_t rv = OPTEE_SMC_RETURN_OK; 538*25c76675SMarouene Boubakri 539*25c76675SMarouene Boubakri /* Enable foreign interrupts for STD calls */ 540*25c76675SMarouene Boubakri thread_set_foreign_intr(true); 541*25c76675SMarouene Boubakri switch (arg->cmd) { 542*25c76675SMarouene Boubakri case OPTEE_MSG_CMD_OPEN_SESSION: 543*25c76675SMarouene Boubakri entry_open_session(arg, num_params); 544*25c76675SMarouene Boubakri break; 545*25c76675SMarouene Boubakri case OPTEE_MSG_CMD_CLOSE_SESSION: 546*25c76675SMarouene Boubakri entry_close_session(arg, num_params); 547*25c76675SMarouene Boubakri break; 548*25c76675SMarouene Boubakri case OPTEE_MSG_CMD_INVOKE_COMMAND: 549*25c76675SMarouene Boubakri entry_invoke_command(arg, num_params); 550*25c76675SMarouene Boubakri break; 551*25c76675SMarouene Boubakri case OPTEE_MSG_CMD_CANCEL: 552*25c76675SMarouene Boubakri entry_cancel(arg, num_params); 553*25c76675SMarouene Boubakri break; 554*25c76675SMarouene Boubakri #ifndef CFG_CORE_FFA 555*25c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM 556*25c76675SMarouene Boubakri case OPTEE_MSG_CMD_REGISTER_SHM: 557*25c76675SMarouene Boubakri register_shm(arg, num_params); 558*25c76675SMarouene Boubakri break; 559*25c76675SMarouene Boubakri case OPTEE_MSG_CMD_UNREGISTER_SHM: 560*25c76675SMarouene Boubakri unregister_shm(arg, num_params); 561*25c76675SMarouene Boubakri break; 562*25c76675SMarouene Boubakri #endif 563*25c76675SMarouene Boubakri #endif 564*25c76675SMarouene Boubakri default: 565*25c76675SMarouene Boubakri EMSG("Unknown cmd 0x%x", arg->cmd); 566*25c76675SMarouene Boubakri rv = OPTEE_SMC_RETURN_EBADCMD; 567*25c76675SMarouene Boubakri } 568*25c76675SMarouene Boubakri 569*25c76675SMarouene Boubakri return rv; 570*25c76675SMarouene Boubakri } 571*25c76675SMarouene Boubakri 572*25c76675SMarouene Boubakri static TEE_Result default_mobj_init(void) 573*25c76675SMarouene Boubakri { 574*25c76675SMarouene Boubakri #ifdef CFG_CORE_RESERVED_SHM 575*25c76675SMarouene Boubakri shm_mobj = mobj_phys_alloc(default_nsec_shm_paddr, 576*25c76675SMarouene Boubakri default_nsec_shm_size, SHM_CACHE_ATTRS, 577*25c76675SMarouene Boubakri CORE_MEM_NSEC_SHM); 578*25c76675SMarouene Boubakri if (!shm_mobj) 579*25c76675SMarouene Boubakri panic("Failed to register shared memory"); 580*25c76675SMarouene Boubakri #endif 581*25c76675SMarouene Boubakri 582*25c76675SMarouene Boubakri #ifdef CFG_SECURE_DATA_PATH 583*25c76675SMarouene Boubakri sdp_mem_mobjs = core_sdp_mem_create_mobjs(); 584*25c76675SMarouene Boubakri if (!sdp_mem_mobjs) 585*25c76675SMarouene Boubakri panic("Failed to register SDP memory"); 586*25c76675SMarouene Boubakri #endif 587*25c76675SMarouene Boubakri 588*25c76675SMarouene Boubakri return TEE_SUCCESS; 589*25c76675SMarouene Boubakri } 590*25c76675SMarouene Boubakri 591*25c76675SMarouene Boubakri driver_init_late(default_mobj_init); 592