15843bb75SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 25843bb75SJerome Forissier /* 36105aa86SJens Wiklander * Copyright (c) 2018-2022 Linaro Limited 46cb02818SJelle Sels * Copyright (c) 2020, Arm Limited. 5e4ad5ccdSAleksandr Anisimov * Copyright (c) 2020, Open Mobile Platform LLC 65843bb75SJerome Forissier */ 75843bb75SJerome Forissier 85843bb75SJerome Forissier #include <assert.h> 95843bb75SJerome Forissier #include <crypto/crypto.h> 105843bb75SJerome Forissier #include <kernel/handle.h> 115843bb75SJerome Forissier #include <kernel/huk_subkey.h> 12cbe7e1b8SBalint Dobszay #include <kernel/ldelf_loader.h> 135843bb75SJerome Forissier #include <kernel/misc.h> 145843bb75SJerome Forissier #include <kernel/msg_param.h> 155843bb75SJerome Forissier #include <kernel/pseudo_ta.h> 16a8e39e9cSJens Wiklander #include <kernel/tpm.h> 176cb02818SJelle Sels #include <kernel/ts_store.h> 1852e7b1a6SJens Wiklander #include <kernel/user_access.h> 199c34c0c7SBalint Dobszay #include <kernel/user_mode_ctx.h> 205843bb75SJerome Forissier #include <ldelf.h> 215843bb75SJerome Forissier #include <mm/file.h> 225843bb75SJerome Forissier #include <mm/fobj.h> 2389c9728dSJens Wiklander #include <mm/vm.h> 245843bb75SJerome Forissier #include <pta_system.h> 25a8e39e9cSJens Wiklander #include <stdlib_ext.h> 26a8e39e9cSJens Wiklander #include <stdlib.h> 275843bb75SJerome Forissier #include <string.h> 285843bb75SJerome Forissier #include <tee_api_defines_extensions.h> 295843bb75SJerome Forissier #include <tee_api_defines.h> 30e4ad5ccdSAleksandr Anisimov #include <tee/tee_supp_plugin_rpc.h> 31e4ad5ccdSAleksandr Anisimov #include <tee/uuid.h> 325843bb75SJerome Forissier #include <util.h> 335843bb75SJerome Forissier 345843bb75SJerome Forissier static unsigned int system_pnum; 355843bb75SJerome Forissier 369c34c0c7SBalint Dobszay static TEE_Result system_rng_reseed(uint32_t param_types, 375843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 385843bb75SJerome Forissier { 3900b3b9a2SJens Wiklander size_t entropy_sz = 0; 4000b3b9a2SJens Wiklander uint8_t *entropy_input = NULL; 41953707a4SSeonghyun Park void *seed_bbuf = NULL; 42953707a4SSeonghyun Park TEE_Result res = TEE_SUCCESS; 435843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 445843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 455843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 465843bb75SJerome Forissier TEE_PARAM_TYPE_NONE); 475843bb75SJerome Forissier 485843bb75SJerome Forissier if (exp_pt != param_types) 495843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 505843bb75SJerome Forissier entropy_input = params[0].memref.buffer; 515843bb75SJerome Forissier entropy_sz = params[0].memref.size; 525843bb75SJerome Forissier 53c2020b9dSJens Wiklander if (!entropy_sz || !entropy_input) 545843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 555843bb75SJerome Forissier 56953707a4SSeonghyun Park res = bb_memdup_user(entropy_input, entropy_sz, &seed_bbuf); 57953707a4SSeonghyun Park if (res) 58953707a4SSeonghyun Park return res; 59953707a4SSeonghyun Park 605843bb75SJerome Forissier crypto_rng_add_event(CRYPTO_RNG_SRC_NONSECURE, &system_pnum, 61953707a4SSeonghyun Park seed_bbuf, entropy_sz); 62953707a4SSeonghyun Park 63953707a4SSeonghyun Park bb_free(seed_bbuf, entropy_sz); 64953707a4SSeonghyun Park 655843bb75SJerome Forissier return TEE_SUCCESS; 665843bb75SJerome Forissier } 675843bb75SJerome Forissier 689c34c0c7SBalint Dobszay static TEE_Result system_derive_ta_unique_key(struct user_mode_ctx *uctx, 695843bb75SJerome Forissier uint32_t param_types, 705843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 715843bb75SJerome Forissier { 725843bb75SJerome Forissier size_t data_len = sizeof(TEE_UUID); 735843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 745843bb75SJerome Forissier uint8_t *data = NULL; 755843bb75SJerome Forissier uint32_t access_flags = 0; 76953707a4SSeonghyun Park void *subkey_bbuf = NULL; 775843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 785843bb75SJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT, 795843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 805843bb75SJerome Forissier TEE_PARAM_TYPE_NONE); 815843bb75SJerome Forissier 825843bb75SJerome Forissier if (exp_pt != param_types) 835843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 845843bb75SJerome Forissier 855843bb75SJerome Forissier if (params[0].memref.size > TA_DERIVED_EXTRA_DATA_MAX_SIZE || 865843bb75SJerome Forissier params[1].memref.size < TA_DERIVED_KEY_MIN_SIZE || 875843bb75SJerome Forissier params[1].memref.size > TA_DERIVED_KEY_MAX_SIZE) 885843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 895843bb75SJerome Forissier 905843bb75SJerome Forissier /* 915843bb75SJerome Forissier * The derived key shall not end up in non-secure memory by 925843bb75SJerome Forissier * mistake. 935843bb75SJerome Forissier * 945843bb75SJerome Forissier * Note that we're allowing shared memory as long as it's 955843bb75SJerome Forissier * secure. This is needed because a TA always uses shared memory 965843bb75SJerome Forissier * when communicating with another TA. 975843bb75SJerome Forissier */ 985843bb75SJerome Forissier access_flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER | 995843bb75SJerome Forissier TEE_MEMORY_ACCESS_SECURE; 1009c34c0c7SBalint Dobszay res = vm_check_access_rights(uctx, access_flags, 1015843bb75SJerome Forissier (uaddr_t)params[1].memref.buffer, 1025843bb75SJerome Forissier params[1].memref.size); 1035843bb75SJerome Forissier if (res != TEE_SUCCESS) 1045843bb75SJerome Forissier return TEE_ERROR_SECURITY; 1055843bb75SJerome Forissier 1065843bb75SJerome Forissier /* Take extra data into account. */ 1075843bb75SJerome Forissier if (ADD_OVERFLOW(data_len, params[0].memref.size, &data_len)) 1085843bb75SJerome Forissier return TEE_ERROR_SECURITY; 1095843bb75SJerome Forissier 110*4522f807SJens Wiklander data = bb_alloc(data_len); 1115843bb75SJerome Forissier if (!data) 1125843bb75SJerome Forissier return TEE_ERROR_OUT_OF_MEMORY; 1135843bb75SJerome Forissier 1149c34c0c7SBalint Dobszay memcpy(data, &uctx->ts_ctx->uuid, sizeof(TEE_UUID)); 1155843bb75SJerome Forissier 1165843bb75SJerome Forissier /* Append the user provided data */ 117953707a4SSeonghyun Park res = copy_from_user(data + sizeof(TEE_UUID), params[0].memref.buffer, 1185843bb75SJerome Forissier params[0].memref.size); 119953707a4SSeonghyun Park if (res) 120953707a4SSeonghyun Park goto out; 121953707a4SSeonghyun Park 122953707a4SSeonghyun Park subkey_bbuf = bb_alloc(params[1].memref.size); 123953707a4SSeonghyun Park if (!subkey_bbuf) { 124953707a4SSeonghyun Park res = TEE_ERROR_OUT_OF_MEMORY; 125953707a4SSeonghyun Park goto out; 126953707a4SSeonghyun Park } 1275843bb75SJerome Forissier 1285843bb75SJerome Forissier res = huk_subkey_derive(HUK_SUBKEY_UNIQUE_TA, data, data_len, 129953707a4SSeonghyun Park subkey_bbuf, params[1].memref.size); 130953707a4SSeonghyun Park if (res) 131953707a4SSeonghyun Park goto out; 1325843bb75SJerome Forissier 133953707a4SSeonghyun Park res = copy_to_user(params[1].memref.buffer, subkey_bbuf, 134953707a4SSeonghyun Park params[1].memref.size); 135953707a4SSeonghyun Park 136953707a4SSeonghyun Park out: 137*4522f807SJens Wiklander bb_free_wipe(subkey_bbuf, params[1].memref.size); 138*4522f807SJens Wiklander bb_free_wipe(data, data_len); 1395843bb75SJerome Forissier return res; 1405843bb75SJerome Forissier } 1415843bb75SJerome Forissier 1429c34c0c7SBalint Dobszay static TEE_Result system_map_zi(struct user_mode_ctx *uctx, 1439c34c0c7SBalint Dobszay uint32_t param_types, 1445843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 1455843bb75SJerome Forissier { 1465843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1475843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INOUT, 1485843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INPUT, 1495843bb75SJerome Forissier TEE_PARAM_TYPE_NONE); 1505843bb75SJerome Forissier uint32_t prot = TEE_MATTR_URW | TEE_MATTR_PRW; 1515843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 1525843bb75SJerome Forissier struct mobj *mobj = NULL; 1535843bb75SJerome Forissier uint32_t pad_begin = 0; 154b9651492SJens Wiklander uint32_t vm_flags = 0; 1555843bb75SJerome Forissier struct fobj *f = NULL; 1565843bb75SJerome Forissier uint32_t pad_end = 0; 1575843bb75SJerome Forissier size_t num_bytes = 0; 1585843bb75SJerome Forissier vaddr_t va = 0; 1595843bb75SJerome Forissier 1605843bb75SJerome Forissier if (exp_pt != param_types) 1615843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 1625843bb75SJerome Forissier if (params[0].value.b & ~PTA_SYSTEM_MAP_FLAG_SHAREABLE) 1635843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 1645843bb75SJerome Forissier 1655843bb75SJerome Forissier if (params[0].value.b & PTA_SYSTEM_MAP_FLAG_SHAREABLE) 1665843bb75SJerome Forissier vm_flags |= VM_FLAG_SHAREABLE; 1675843bb75SJerome Forissier 1685843bb75SJerome Forissier num_bytes = params[0].value.a; 1695843bb75SJerome Forissier va = reg_pair_to_64(params[1].value.a, params[1].value.b); 1705843bb75SJerome Forissier pad_begin = params[2].value.a; 1715843bb75SJerome Forissier pad_end = params[2].value.b; 1725843bb75SJerome Forissier 173787295dfSJens Wiklander f = fobj_ta_mem_alloc(ROUNDUP_DIV(num_bytes, SMALL_PAGE_SIZE)); 1745843bb75SJerome Forissier if (!f) 1755843bb75SJerome Forissier return TEE_ERROR_OUT_OF_MEMORY; 1766105aa86SJens Wiklander mobj = mobj_with_fobj_alloc(f, NULL, TEE_MATTR_MEM_TYPE_TAGGED); 1775843bb75SJerome Forissier fobj_put(f); 1785843bb75SJerome Forissier if (!mobj) 1795843bb75SJerome Forissier return TEE_ERROR_OUT_OF_MEMORY; 1809c34c0c7SBalint Dobszay res = vm_map_pad(uctx, &va, num_bytes, prot, vm_flags, 181918e36c6SSughosh Ganu mobj, 0, pad_begin, pad_end, 0); 182b9651492SJens Wiklander mobj_put(mobj); 183b9651492SJens Wiklander if (!res) 1845843bb75SJerome Forissier reg_pair_from_64(va, ¶ms[1].value.a, ¶ms[1].value.b); 1855843bb75SJerome Forissier 1865843bb75SJerome Forissier return res; 1875843bb75SJerome Forissier } 1885843bb75SJerome Forissier 1899c34c0c7SBalint Dobszay static TEE_Result system_unmap(struct user_mode_ctx *uctx, uint32_t param_types, 1905843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 1915843bb75SJerome Forissier { 1925843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 1935843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INPUT, 1945843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 1955843bb75SJerome Forissier TEE_PARAM_TYPE_NONE); 19679f22013SJens Wiklander TEE_Result res = TEE_SUCCESS; 19779f22013SJens Wiklander uint32_t vm_flags = 0; 198095b07ceSJens Wiklander vaddr_t end_va = 0; 19979f22013SJens Wiklander vaddr_t va = 0; 20079f22013SJens Wiklander size_t sz = 0; 2015843bb75SJerome Forissier 2025843bb75SJerome Forissier if (exp_pt != param_types) 2035843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2045843bb75SJerome Forissier 2055843bb75SJerome Forissier if (params[0].value.b) 2065843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2075843bb75SJerome Forissier 20879f22013SJens Wiklander va = reg_pair_to_64(params[1].value.a, params[1].value.b); 20979f22013SJens Wiklander sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE); 21079f22013SJens Wiklander 211095b07ceSJens Wiklander /* 212095b07ceSJens Wiklander * The vm_get_flags() and vm_unmap() are supposed to detect or 213095b07ceSJens Wiklander * handle overflow directly or indirectly. However, this function 214095b07ceSJens Wiklander * an API function so an extra guard here is in order. If nothing 215095b07ceSJens Wiklander * else to make it easier to review the code. 216095b07ceSJens Wiklander */ 217095b07ceSJens Wiklander if (ADD_OVERFLOW(va, sz, &end_va)) 218095b07ceSJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 219095b07ceSJens Wiklander 2209c34c0c7SBalint Dobszay res = vm_get_flags(uctx, va, sz, &vm_flags); 22179f22013SJens Wiklander if (res) 22279f22013SJens Wiklander return res; 22379f22013SJens Wiklander if (vm_flags & VM_FLAG_PERMANENT) 22479f22013SJens Wiklander return TEE_ERROR_ACCESS_DENIED; 22579f22013SJens Wiklander 2269c34c0c7SBalint Dobszay return vm_unmap(uctx, va, sz); 2275843bb75SJerome Forissier } 2285843bb75SJerome Forissier 2299c34c0c7SBalint Dobszay static TEE_Result system_dlopen(struct user_mode_ctx *uctx, 2309c34c0c7SBalint Dobszay uint32_t param_types, 2315843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 2325843bb75SJerome Forissier { 2335843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 2345843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INPUT, 2355843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 2365843bb75SJerome Forissier TEE_PARAM_TYPE_NONE); 2375843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 23800b3b9a2SJens Wiklander struct ts_session *s = NULL; 23952e7b1a6SJens Wiklander TEE_UUID uuid = { }; 2405843bb75SJerome Forissier uint32_t flags = 0; 2415843bb75SJerome Forissier 2425843bb75SJerome Forissier if (exp_pt != param_types) 2435843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2445843bb75SJerome Forissier 24552e7b1a6SJens Wiklander if (!params[0].memref.buffer || params[0].memref.size != sizeof(uuid)) 2465843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2475843bb75SJerome Forissier 24852e7b1a6SJens Wiklander res = copy_from_user(&uuid, params[0].memref.buffer, sizeof(uuid)); 24952e7b1a6SJens Wiklander if (res) 25052e7b1a6SJens Wiklander return res; 25152e7b1a6SJens Wiklander 2525843bb75SJerome Forissier flags = params[1].value.a; 2535843bb75SJerome Forissier 25400b3b9a2SJens Wiklander s = ts_pop_current_session(); 25552e7b1a6SJens Wiklander res = ldelf_dlopen(uctx, &uuid, flags); 25600b3b9a2SJens Wiklander ts_push_current_session(s); 2575843bb75SJerome Forissier 2585843bb75SJerome Forissier return res; 2595843bb75SJerome Forissier } 2605843bb75SJerome Forissier 2619c34c0c7SBalint Dobszay static TEE_Result system_dlsym(struct user_mode_ctx *uctx, uint32_t param_types, 2625843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 2635843bb75SJerome Forissier { 2645843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 2655843bb75SJerome Forissier TEE_PARAM_TYPE_MEMREF_INPUT, 2665843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_OUTPUT, 2675843bb75SJerome Forissier TEE_PARAM_TYPE_NONE); 2685843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 26900b3b9a2SJens Wiklander struct ts_session *s = NULL; 27052e7b1a6SJens Wiklander char *sym = NULL; 27152e7b1a6SJens Wiklander TEE_UUID uuid = { }; 27252e7b1a6SJens Wiklander size_t symlen = 0; 2735843bb75SJerome Forissier vaddr_t va = 0; 2745843bb75SJerome Forissier 2755843bb75SJerome Forissier if (exp_pt != param_types) 2765843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2775843bb75SJerome Forissier 27852e7b1a6SJens Wiklander if (!params[0].memref.buffer || params[0].memref.size != sizeof(uuid)) 2795843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2805843bb75SJerome Forissier 28152e7b1a6SJens Wiklander res = copy_from_user(&uuid, params[0].memref.buffer, sizeof(uuid)); 28252e7b1a6SJens Wiklander if (res) 28352e7b1a6SJens Wiklander return res; 28452e7b1a6SJens Wiklander 28552e7b1a6SJens Wiklander if (!params[1].memref.buffer) 2865843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 28752e7b1a6SJens Wiklander res = bb_strndup_user(params[1].memref.buffer, params[1].memref.size, 28852e7b1a6SJens Wiklander &sym, &symlen); 28952e7b1a6SJens Wiklander if (res) 29052e7b1a6SJens Wiklander return res; 2915843bb75SJerome Forissier 29200b3b9a2SJens Wiklander s = ts_pop_current_session(); 29352e7b1a6SJens Wiklander res = ldelf_dlsym(uctx, &uuid, sym, symlen, &va); 29400b3b9a2SJens Wiklander ts_push_current_session(s); 2955843bb75SJerome Forissier 2965843bb75SJerome Forissier if (!res) 2975843bb75SJerome Forissier reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b); 2985843bb75SJerome Forissier 2995843bb75SJerome Forissier return res; 3005843bb75SJerome Forissier } 3015843bb75SJerome Forissier 302dd333f03SJavier Almansa Sobrino static TEE_Result system_get_tpm_event_log(uint32_t param_types, 303dd333f03SJavier Almansa Sobrino TEE_Param params[TEE_NUM_PARAMS]) 304dd333f03SJavier Almansa Sobrino { 305dd333f03SJavier Almansa Sobrino uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 306dd333f03SJavier Almansa Sobrino TEE_PARAM_TYPE_NONE, 307dd333f03SJavier Almansa Sobrino TEE_PARAM_TYPE_NONE, 308dd333f03SJavier Almansa Sobrino TEE_PARAM_TYPE_NONE); 309dd333f03SJavier Almansa Sobrino size_t size = 0; 310dd333f03SJavier Almansa Sobrino TEE_Result res = TEE_SUCCESS; 311dd333f03SJavier Almansa Sobrino 312dd333f03SJavier Almansa Sobrino if (exp_pt != param_types) 313dd333f03SJavier Almansa Sobrino return TEE_ERROR_BAD_PARAMETERS; 314dd333f03SJavier Almansa Sobrino 315dd333f03SJavier Almansa Sobrino size = params[0].memref.size; 316dd333f03SJavier Almansa Sobrino res = tpm_get_event_log(params[0].memref.buffer, &size); 317dd333f03SJavier Almansa Sobrino params[0].memref.size = size; 318dd333f03SJavier Almansa Sobrino 319dd333f03SJavier Almansa Sobrino return res; 320dd333f03SJavier Almansa Sobrino } 321dd333f03SJavier Almansa Sobrino 322e4ad5ccdSAleksandr Anisimov static TEE_Result system_supp_plugin_invoke(uint32_t param_types, 323e4ad5ccdSAleksandr Anisimov TEE_Param params[TEE_NUM_PARAMS]) 324e4ad5ccdSAleksandr Anisimov { 325e4ad5ccdSAleksandr Anisimov uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 326e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_VALUE_INPUT, 327e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_MEMREF_INOUT, 328e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_VALUE_OUTPUT); 329e4ad5ccdSAleksandr Anisimov TEE_Result res = TEE_ERROR_GENERIC; 330e4ad5ccdSAleksandr Anisimov size_t outlen = 0; 331953707a4SSeonghyun Park TEE_UUID uuid = { }; 332e4ad5ccdSAleksandr Anisimov 333e4ad5ccdSAleksandr Anisimov if (exp_pt != param_types) 334e4ad5ccdSAleksandr Anisimov return TEE_ERROR_BAD_PARAMETERS; 335e4ad5ccdSAleksandr Anisimov 336953707a4SSeonghyun Park if (!params[0].memref.buffer || params[0].memref.size != sizeof(uuid)) 337953707a4SSeonghyun Park return TEE_ERROR_BAD_PARAMETERS; 338953707a4SSeonghyun Park 339953707a4SSeonghyun Park res = copy_from_user(&uuid, params[0].memref.buffer, sizeof(uuid)); 340953707a4SSeonghyun Park if (res) 341953707a4SSeonghyun Park return res; 342953707a4SSeonghyun Park 343953707a4SSeonghyun Park res = tee_invoke_supp_plugin_rpc(&uuid, 344e4ad5ccdSAleksandr Anisimov params[1].value.a, /* cmd */ 345e4ad5ccdSAleksandr Anisimov params[1].value.b, /* sub_cmd */ 346eb4a988aSJens Wiklander NULL, 347e4ad5ccdSAleksandr Anisimov params[2].memref.buffer, /* data */ 348e4ad5ccdSAleksandr Anisimov params[2].memref.size, /* in len */ 349e4ad5ccdSAleksandr Anisimov &outlen); 350e4ad5ccdSAleksandr Anisimov params[3].value.a = (uint32_t)outlen; 351e4ad5ccdSAleksandr Anisimov 352e4ad5ccdSAleksandr Anisimov return res; 353e4ad5ccdSAleksandr Anisimov } 354e4ad5ccdSAleksandr Anisimov 3555843bb75SJerome Forissier static TEE_Result open_session(uint32_t param_types __unused, 3565843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS] __unused, 357baa5161dSBalint Dobszay void **sess_ctx __unused) 3585843bb75SJerome Forissier { 35900b3b9a2SJens Wiklander struct ts_session *s = NULL; 3605843bb75SJerome Forissier 3615843bb75SJerome Forissier /* Check that we're called from a user TA */ 36200b3b9a2SJens Wiklander s = ts_get_calling_session(); 3635843bb75SJerome Forissier if (!s) 3645843bb75SJerome Forissier return TEE_ERROR_ACCESS_DENIED; 3655843bb75SJerome Forissier if (!is_user_ta_ctx(s->ctx)) 3665843bb75SJerome Forissier return TEE_ERROR_ACCESS_DENIED; 3675843bb75SJerome Forissier 3685843bb75SJerome Forissier return TEE_SUCCESS; 3695843bb75SJerome Forissier } 3705843bb75SJerome Forissier 371baa5161dSBalint Dobszay static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id, 3725843bb75SJerome Forissier uint32_t param_types, 3735843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 3745843bb75SJerome Forissier { 37500b3b9a2SJens Wiklander struct ts_session *s = ts_get_calling_session(); 3769c34c0c7SBalint Dobszay struct user_mode_ctx *uctx = to_user_mode_ctx(s->ctx); 3775843bb75SJerome Forissier 3785843bb75SJerome Forissier switch (cmd_id) { 3795843bb75SJerome Forissier case PTA_SYSTEM_ADD_RNG_ENTROPY: 3809c34c0c7SBalint Dobszay return system_rng_reseed(param_types, params); 3815843bb75SJerome Forissier case PTA_SYSTEM_DERIVE_TA_UNIQUE_KEY: 3829c34c0c7SBalint Dobszay return system_derive_ta_unique_key(uctx, param_types, params); 3835843bb75SJerome Forissier case PTA_SYSTEM_MAP_ZI: 3849c34c0c7SBalint Dobszay return system_map_zi(uctx, param_types, params); 3855843bb75SJerome Forissier case PTA_SYSTEM_UNMAP: 3869c34c0c7SBalint Dobszay return system_unmap(uctx, param_types, params); 3875843bb75SJerome Forissier case PTA_SYSTEM_DLOPEN: 3889c34c0c7SBalint Dobszay return system_dlopen(uctx, param_types, params); 3895843bb75SJerome Forissier case PTA_SYSTEM_DLSYM: 3909c34c0c7SBalint Dobszay return system_dlsym(uctx, param_types, params); 391dd333f03SJavier Almansa Sobrino case PTA_SYSTEM_GET_TPM_EVENT_LOG: 392dd333f03SJavier Almansa Sobrino return system_get_tpm_event_log(param_types, params); 393e4ad5ccdSAleksandr Anisimov case PTA_SYSTEM_SUPP_PLUGIN_INVOKE: 394e4ad5ccdSAleksandr Anisimov return system_supp_plugin_invoke(param_types, params); 3955843bb75SJerome Forissier default: 3965843bb75SJerome Forissier break; 3975843bb75SJerome Forissier } 3985843bb75SJerome Forissier 3995843bb75SJerome Forissier return TEE_ERROR_NOT_IMPLEMENTED; 4005843bb75SJerome Forissier } 4015843bb75SJerome Forissier 4025843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_SYSTEM_UUID, .name = "system.pta", 4035843bb75SJerome Forissier .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT, 4045843bb75SJerome Forissier .open_session_entry_point = open_session, 4055843bb75SJerome Forissier .invoke_command_entry_point = invoke_command); 406