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/huk_subkey.h>
11cbe7e1b8SBalint Dobszay #include <kernel/ldelf_loader.h>
125843bb75SJerome Forissier #include <kernel/msg_param.h>
135843bb75SJerome Forissier #include <kernel/pseudo_ta.h>
14a8e39e9cSJens Wiklander #include <kernel/tpm.h>
1552e7b1a6SJens Wiklander #include <kernel/user_access.h>
169c34c0c7SBalint Dobszay #include <kernel/user_mode_ctx.h>
175843bb75SJerome Forissier #include <mm/file.h>
185843bb75SJerome Forissier #include <mm/fobj.h>
1989c9728dSJens Wiklander #include <mm/vm.h>
205843bb75SJerome Forissier #include <pta_system.h>
21a8e39e9cSJens Wiklander #include <stdlib.h>
225843bb75SJerome Forissier #include <string.h>
235843bb75SJerome Forissier #include <tee_api_defines_extensions.h>
245843bb75SJerome Forissier #include <tee_api_defines.h>
25e4ad5ccdSAleksandr Anisimov #include <tee/tee_supp_plugin_rpc.h>
265843bb75SJerome Forissier #include <util.h>
275843bb75SJerome Forissier
285843bb75SJerome Forissier static unsigned int system_pnum;
295843bb75SJerome Forissier
system_rng_reseed(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])309c34c0c7SBalint Dobszay static TEE_Result system_rng_reseed(uint32_t param_types,
315843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS])
325843bb75SJerome Forissier {
3300b3b9a2SJens Wiklander size_t entropy_sz = 0;
3400b3b9a2SJens Wiklander uint8_t *entropy_input = NULL;
35953707a4SSeonghyun Park void *seed_bbuf = NULL;
36953707a4SSeonghyun Park TEE_Result res = TEE_SUCCESS;
375843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
385843bb75SJerome Forissier TEE_PARAM_TYPE_NONE,
395843bb75SJerome Forissier TEE_PARAM_TYPE_NONE,
405843bb75SJerome Forissier TEE_PARAM_TYPE_NONE);
415843bb75SJerome Forissier
425843bb75SJerome Forissier if (exp_pt != param_types)
435843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
445843bb75SJerome Forissier entropy_input = params[0].memref.buffer;
455843bb75SJerome Forissier entropy_sz = params[0].memref.size;
465843bb75SJerome Forissier
47c2020b9dSJens Wiklander if (!entropy_sz || !entropy_input)
485843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
495843bb75SJerome Forissier
50953707a4SSeonghyun Park res = bb_memdup_user(entropy_input, entropy_sz, &seed_bbuf);
51953707a4SSeonghyun Park if (res)
52953707a4SSeonghyun Park return res;
53953707a4SSeonghyun Park
545843bb75SJerome Forissier crypto_rng_add_event(CRYPTO_RNG_SRC_NONSECURE, &system_pnum,
55953707a4SSeonghyun Park seed_bbuf, entropy_sz);
56953707a4SSeonghyun Park
57953707a4SSeonghyun Park bb_free(seed_bbuf, entropy_sz);
58953707a4SSeonghyun Park
595843bb75SJerome Forissier return TEE_SUCCESS;
605843bb75SJerome Forissier }
615843bb75SJerome Forissier
system_derive_ta_unique_key(struct user_mode_ctx * uctx,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])629c34c0c7SBalint Dobszay static TEE_Result system_derive_ta_unique_key(struct user_mode_ctx *uctx,
635843bb75SJerome Forissier uint32_t param_types,
645843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS])
655843bb75SJerome Forissier {
665843bb75SJerome Forissier size_t data_len = sizeof(TEE_UUID);
675843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC;
685843bb75SJerome Forissier uint8_t *data = NULL;
695843bb75SJerome Forissier uint32_t access_flags = 0;
70953707a4SSeonghyun Park void *subkey_bbuf = NULL;
715843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
725843bb75SJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT,
735843bb75SJerome Forissier TEE_PARAM_TYPE_NONE,
745843bb75SJerome Forissier TEE_PARAM_TYPE_NONE);
755843bb75SJerome Forissier
765843bb75SJerome Forissier if (exp_pt != param_types)
775843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
785843bb75SJerome Forissier
795843bb75SJerome Forissier if (params[0].memref.size > TA_DERIVED_EXTRA_DATA_MAX_SIZE ||
805843bb75SJerome Forissier params[1].memref.size < TA_DERIVED_KEY_MIN_SIZE ||
815843bb75SJerome Forissier params[1].memref.size > TA_DERIVED_KEY_MAX_SIZE)
825843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
835843bb75SJerome Forissier
845843bb75SJerome Forissier /*
855843bb75SJerome Forissier * The derived key shall not end up in non-secure memory by
865843bb75SJerome Forissier * mistake.
875843bb75SJerome Forissier *
885843bb75SJerome Forissier * Note that we're allowing shared memory as long as it's
895843bb75SJerome Forissier * secure. This is needed because a TA always uses shared memory
905843bb75SJerome Forissier * when communicating with another TA.
915843bb75SJerome Forissier */
925843bb75SJerome Forissier access_flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER |
935843bb75SJerome Forissier TEE_MEMORY_ACCESS_SECURE;
949c34c0c7SBalint Dobszay res = vm_check_access_rights(uctx, access_flags,
955843bb75SJerome Forissier (uaddr_t)params[1].memref.buffer,
965843bb75SJerome Forissier params[1].memref.size);
975843bb75SJerome Forissier if (res != TEE_SUCCESS)
985843bb75SJerome Forissier return TEE_ERROR_SECURITY;
995843bb75SJerome Forissier
1005843bb75SJerome Forissier /* Take extra data into account. */
1015843bb75SJerome Forissier if (ADD_OVERFLOW(data_len, params[0].memref.size, &data_len))
1025843bb75SJerome Forissier return TEE_ERROR_SECURITY;
1035843bb75SJerome Forissier
104*4522f807SJens Wiklander data = bb_alloc(data_len);
1055843bb75SJerome Forissier if (!data)
1065843bb75SJerome Forissier return TEE_ERROR_OUT_OF_MEMORY;
1075843bb75SJerome Forissier
1089c34c0c7SBalint Dobszay memcpy(data, &uctx->ts_ctx->uuid, sizeof(TEE_UUID));
1095843bb75SJerome Forissier
1105843bb75SJerome Forissier /* Append the user provided data */
111953707a4SSeonghyun Park res = copy_from_user(data + sizeof(TEE_UUID), params[0].memref.buffer,
1125843bb75SJerome Forissier params[0].memref.size);
113953707a4SSeonghyun Park if (res)
114953707a4SSeonghyun Park goto out;
115953707a4SSeonghyun Park
116953707a4SSeonghyun Park subkey_bbuf = bb_alloc(params[1].memref.size);
117953707a4SSeonghyun Park if (!subkey_bbuf) {
118953707a4SSeonghyun Park res = TEE_ERROR_OUT_OF_MEMORY;
119953707a4SSeonghyun Park goto out;
120953707a4SSeonghyun Park }
1215843bb75SJerome Forissier
1225843bb75SJerome Forissier res = huk_subkey_derive(HUK_SUBKEY_UNIQUE_TA, data, data_len,
123953707a4SSeonghyun Park subkey_bbuf, params[1].memref.size);
124953707a4SSeonghyun Park if (res)
125953707a4SSeonghyun Park goto out;
1265843bb75SJerome Forissier
127953707a4SSeonghyun Park res = copy_to_user(params[1].memref.buffer, subkey_bbuf,
128953707a4SSeonghyun Park params[1].memref.size);
129953707a4SSeonghyun Park
130953707a4SSeonghyun Park out:
131*4522f807SJens Wiklander bb_free_wipe(subkey_bbuf, params[1].memref.size);
132*4522f807SJens Wiklander bb_free_wipe(data, data_len);
1335843bb75SJerome Forissier return res;
1345843bb75SJerome Forissier }
1355843bb75SJerome Forissier
system_map_zi(struct user_mode_ctx * uctx,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])1369c34c0c7SBalint Dobszay static TEE_Result system_map_zi(struct user_mode_ctx *uctx,
1379c34c0c7SBalint Dobszay uint32_t param_types,
1385843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS])
1395843bb75SJerome Forissier {
1405843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1415843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INOUT,
1425843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INPUT,
1435843bb75SJerome Forissier TEE_PARAM_TYPE_NONE);
1445843bb75SJerome Forissier uint32_t prot = TEE_MATTR_URW | TEE_MATTR_PRW;
1455843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC;
1465843bb75SJerome Forissier struct mobj *mobj = NULL;
1475843bb75SJerome Forissier uint32_t pad_begin = 0;
148b9651492SJens Wiklander uint32_t vm_flags = 0;
1495843bb75SJerome Forissier struct fobj *f = NULL;
1505843bb75SJerome Forissier uint32_t pad_end = 0;
1515843bb75SJerome Forissier size_t num_bytes = 0;
1525843bb75SJerome Forissier vaddr_t va = 0;
1535843bb75SJerome Forissier
1545843bb75SJerome Forissier if (exp_pt != param_types)
1555843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
1565843bb75SJerome Forissier if (params[0].value.b & ~PTA_SYSTEM_MAP_FLAG_SHAREABLE)
1575843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
1585843bb75SJerome Forissier
1595843bb75SJerome Forissier if (params[0].value.b & PTA_SYSTEM_MAP_FLAG_SHAREABLE)
1605843bb75SJerome Forissier vm_flags |= VM_FLAG_SHAREABLE;
1615843bb75SJerome Forissier
1625843bb75SJerome Forissier num_bytes = params[0].value.a;
1635843bb75SJerome Forissier va = reg_pair_to_64(params[1].value.a, params[1].value.b);
1645843bb75SJerome Forissier pad_begin = params[2].value.a;
1655843bb75SJerome Forissier pad_end = params[2].value.b;
1665843bb75SJerome Forissier
167787295dfSJens Wiklander f = fobj_ta_mem_alloc(ROUNDUP_DIV(num_bytes, SMALL_PAGE_SIZE));
1685843bb75SJerome Forissier if (!f)
1695843bb75SJerome Forissier return TEE_ERROR_OUT_OF_MEMORY;
1706105aa86SJens Wiklander mobj = mobj_with_fobj_alloc(f, NULL, TEE_MATTR_MEM_TYPE_TAGGED);
1715843bb75SJerome Forissier fobj_put(f);
1725843bb75SJerome Forissier if (!mobj)
1735843bb75SJerome Forissier return TEE_ERROR_OUT_OF_MEMORY;
1749c34c0c7SBalint Dobszay res = vm_map_pad(uctx, &va, num_bytes, prot, vm_flags,
175918e36c6SSughosh Ganu mobj, 0, pad_begin, pad_end, 0);
176b9651492SJens Wiklander mobj_put(mobj);
177b9651492SJens Wiklander if (!res)
1785843bb75SJerome Forissier reg_pair_from_64(va, ¶ms[1].value.a, ¶ms[1].value.b);
1795843bb75SJerome Forissier
1805843bb75SJerome Forissier return res;
1815843bb75SJerome Forissier }
1825843bb75SJerome Forissier
system_unmap(struct user_mode_ctx * uctx,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])1839c34c0c7SBalint Dobszay static TEE_Result system_unmap(struct user_mode_ctx *uctx, uint32_t param_types,
1845843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS])
1855843bb75SJerome Forissier {
1865843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1875843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INPUT,
1885843bb75SJerome Forissier TEE_PARAM_TYPE_NONE,
1895843bb75SJerome Forissier TEE_PARAM_TYPE_NONE);
19079f22013SJens Wiklander TEE_Result res = TEE_SUCCESS;
19179f22013SJens Wiklander uint32_t vm_flags = 0;
192095b07ceSJens Wiklander vaddr_t end_va = 0;
19379f22013SJens Wiklander vaddr_t va = 0;
19479f22013SJens Wiklander size_t sz = 0;
1955843bb75SJerome Forissier
1965843bb75SJerome Forissier if (exp_pt != param_types)
1975843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
1985843bb75SJerome Forissier
1995843bb75SJerome Forissier if (params[0].value.b)
2005843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
2015843bb75SJerome Forissier
20279f22013SJens Wiklander va = reg_pair_to_64(params[1].value.a, params[1].value.b);
20379f22013SJens Wiklander sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE);
20479f22013SJens Wiklander
205095b07ceSJens Wiklander /*
206095b07ceSJens Wiklander * The vm_get_flags() and vm_unmap() are supposed to detect or
207095b07ceSJens Wiklander * handle overflow directly or indirectly. However, this function
208095b07ceSJens Wiklander * an API function so an extra guard here is in order. If nothing
209095b07ceSJens Wiklander * else to make it easier to review the code.
210095b07ceSJens Wiklander */
211095b07ceSJens Wiklander if (ADD_OVERFLOW(va, sz, &end_va))
212095b07ceSJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
213095b07ceSJens Wiklander
2149c34c0c7SBalint Dobszay res = vm_get_flags(uctx, va, sz, &vm_flags);
21579f22013SJens Wiklander if (res)
21679f22013SJens Wiklander return res;
21779f22013SJens Wiklander if (vm_flags & VM_FLAG_PERMANENT)
21879f22013SJens Wiklander return TEE_ERROR_ACCESS_DENIED;
21979f22013SJens Wiklander
2209c34c0c7SBalint Dobszay return vm_unmap(uctx, va, sz);
2215843bb75SJerome Forissier }
2225843bb75SJerome Forissier
system_dlopen(struct user_mode_ctx * uctx,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])2239c34c0c7SBalint Dobszay static TEE_Result system_dlopen(struct user_mode_ctx *uctx,
2249c34c0c7SBalint Dobszay uint32_t param_types,
2255843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS])
2265843bb75SJerome Forissier {
2275843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
2285843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_INPUT,
2295843bb75SJerome Forissier TEE_PARAM_TYPE_NONE,
2305843bb75SJerome Forissier TEE_PARAM_TYPE_NONE);
2315843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC;
23200b3b9a2SJens Wiklander struct ts_session *s = NULL;
23352e7b1a6SJens Wiklander TEE_UUID uuid = { };
2345843bb75SJerome Forissier uint32_t flags = 0;
2355843bb75SJerome Forissier
2365843bb75SJerome Forissier if (exp_pt != param_types)
2375843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
2385843bb75SJerome Forissier
23952e7b1a6SJens Wiklander if (!params[0].memref.buffer || params[0].memref.size != sizeof(uuid))
2405843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
2415843bb75SJerome Forissier
24252e7b1a6SJens Wiklander res = copy_from_user(&uuid, params[0].memref.buffer, sizeof(uuid));
24352e7b1a6SJens Wiklander if (res)
24452e7b1a6SJens Wiklander return res;
24552e7b1a6SJens Wiklander
2465843bb75SJerome Forissier flags = params[1].value.a;
2475843bb75SJerome Forissier
24800b3b9a2SJens Wiklander s = ts_pop_current_session();
24952e7b1a6SJens Wiklander res = ldelf_dlopen(uctx, &uuid, flags);
25000b3b9a2SJens Wiklander ts_push_current_session(s);
2515843bb75SJerome Forissier
2525843bb75SJerome Forissier return res;
2535843bb75SJerome Forissier }
2545843bb75SJerome Forissier
system_dlsym(struct user_mode_ctx * uctx,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])2559c34c0c7SBalint Dobszay static TEE_Result system_dlsym(struct user_mode_ctx *uctx, uint32_t param_types,
2565843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS])
2575843bb75SJerome Forissier {
2585843bb75SJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
2595843bb75SJerome Forissier TEE_PARAM_TYPE_MEMREF_INPUT,
2605843bb75SJerome Forissier TEE_PARAM_TYPE_VALUE_OUTPUT,
2615843bb75SJerome Forissier TEE_PARAM_TYPE_NONE);
2625843bb75SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC;
26300b3b9a2SJens Wiklander struct ts_session *s = NULL;
26452e7b1a6SJens Wiklander char *sym = NULL;
26552e7b1a6SJens Wiklander TEE_UUID uuid = { };
26652e7b1a6SJens Wiklander size_t symlen = 0;
2675843bb75SJerome Forissier vaddr_t va = 0;
2685843bb75SJerome Forissier
2695843bb75SJerome Forissier if (exp_pt != param_types)
2705843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
2715843bb75SJerome Forissier
27252e7b1a6SJens Wiklander if (!params[0].memref.buffer || params[0].memref.size != sizeof(uuid))
2735843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
2745843bb75SJerome Forissier
27552e7b1a6SJens Wiklander res = copy_from_user(&uuid, params[0].memref.buffer, sizeof(uuid));
27652e7b1a6SJens Wiklander if (res)
27752e7b1a6SJens Wiklander return res;
27852e7b1a6SJens Wiklander
27952e7b1a6SJens Wiklander if (!params[1].memref.buffer)
2805843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
28152e7b1a6SJens Wiklander res = bb_strndup_user(params[1].memref.buffer, params[1].memref.size,
28252e7b1a6SJens Wiklander &sym, &symlen);
28352e7b1a6SJens Wiklander if (res)
28452e7b1a6SJens Wiklander return res;
2855843bb75SJerome Forissier
28600b3b9a2SJens Wiklander s = ts_pop_current_session();
28752e7b1a6SJens Wiklander res = ldelf_dlsym(uctx, &uuid, sym, symlen, &va);
28800b3b9a2SJens Wiklander ts_push_current_session(s);
2895843bb75SJerome Forissier
2905843bb75SJerome Forissier if (!res)
2915843bb75SJerome Forissier reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b);
2925843bb75SJerome Forissier
2935843bb75SJerome Forissier return res;
2945843bb75SJerome Forissier }
2955843bb75SJerome Forissier
system_get_tpm_event_log(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])296dd333f03SJavier Almansa Sobrino static TEE_Result system_get_tpm_event_log(uint32_t param_types,
297dd333f03SJavier Almansa Sobrino TEE_Param params[TEE_NUM_PARAMS])
298dd333f03SJavier Almansa Sobrino {
299dd333f03SJavier Almansa Sobrino uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
300dd333f03SJavier Almansa Sobrino TEE_PARAM_TYPE_NONE,
301dd333f03SJavier Almansa Sobrino TEE_PARAM_TYPE_NONE,
302dd333f03SJavier Almansa Sobrino TEE_PARAM_TYPE_NONE);
303dd333f03SJavier Almansa Sobrino size_t size = 0;
304dd333f03SJavier Almansa Sobrino TEE_Result res = TEE_SUCCESS;
305dd333f03SJavier Almansa Sobrino
306dd333f03SJavier Almansa Sobrino if (exp_pt != param_types)
307dd333f03SJavier Almansa Sobrino return TEE_ERROR_BAD_PARAMETERS;
308dd333f03SJavier Almansa Sobrino
309dd333f03SJavier Almansa Sobrino size = params[0].memref.size;
310dd333f03SJavier Almansa Sobrino res = tpm_get_event_log(params[0].memref.buffer, &size);
311dd333f03SJavier Almansa Sobrino params[0].memref.size = size;
312dd333f03SJavier Almansa Sobrino
313dd333f03SJavier Almansa Sobrino return res;
314dd333f03SJavier Almansa Sobrino }
315dd333f03SJavier Almansa Sobrino
system_supp_plugin_invoke(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])316e4ad5ccdSAleksandr Anisimov static TEE_Result system_supp_plugin_invoke(uint32_t param_types,
317e4ad5ccdSAleksandr Anisimov TEE_Param params[TEE_NUM_PARAMS])
318e4ad5ccdSAleksandr Anisimov {
319e4ad5ccdSAleksandr Anisimov uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
320e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_VALUE_INPUT,
321e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_MEMREF_INOUT,
322e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_VALUE_OUTPUT);
323e4ad5ccdSAleksandr Anisimov TEE_Result res = TEE_ERROR_GENERIC;
324e4ad5ccdSAleksandr Anisimov size_t outlen = 0;
325953707a4SSeonghyun Park TEE_UUID uuid = { };
326e4ad5ccdSAleksandr Anisimov
327e4ad5ccdSAleksandr Anisimov if (exp_pt != param_types)
328e4ad5ccdSAleksandr Anisimov return TEE_ERROR_BAD_PARAMETERS;
329e4ad5ccdSAleksandr Anisimov
330953707a4SSeonghyun Park if (!params[0].memref.buffer || params[0].memref.size != sizeof(uuid))
331953707a4SSeonghyun Park return TEE_ERROR_BAD_PARAMETERS;
332953707a4SSeonghyun Park
333953707a4SSeonghyun Park res = copy_from_user(&uuid, params[0].memref.buffer, sizeof(uuid));
334953707a4SSeonghyun Park if (res)
335953707a4SSeonghyun Park return res;
336953707a4SSeonghyun Park
337953707a4SSeonghyun Park res = tee_invoke_supp_plugin_rpc(&uuid,
338e4ad5ccdSAleksandr Anisimov params[1].value.a, /* cmd */
339e4ad5ccdSAleksandr Anisimov params[1].value.b, /* sub_cmd */
340eb4a988aSJens Wiklander NULL,
341e4ad5ccdSAleksandr Anisimov params[2].memref.buffer, /* data */
342e4ad5ccdSAleksandr Anisimov params[2].memref.size, /* in len */
343e4ad5ccdSAleksandr Anisimov &outlen);
344e4ad5ccdSAleksandr Anisimov params[3].value.a = (uint32_t)outlen;
345e4ad5ccdSAleksandr Anisimov
346e4ad5ccdSAleksandr Anisimov return res;
347e4ad5ccdSAleksandr Anisimov }
348e4ad5ccdSAleksandr Anisimov
open_session(uint32_t param_types __unused,TEE_Param params[TEE_NUM_PARAMS]__unused,void ** sess_ctx __unused)3495843bb75SJerome Forissier static TEE_Result open_session(uint32_t param_types __unused,
3505843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS] __unused,
351baa5161dSBalint Dobszay void **sess_ctx __unused)
3525843bb75SJerome Forissier {
35300b3b9a2SJens Wiklander struct ts_session *s = NULL;
3545843bb75SJerome Forissier
3555843bb75SJerome Forissier /* Check that we're called from a user TA */
35600b3b9a2SJens Wiklander s = ts_get_calling_session();
3575843bb75SJerome Forissier if (!s)
3585843bb75SJerome Forissier return TEE_ERROR_ACCESS_DENIED;
3595843bb75SJerome Forissier if (!is_user_ta_ctx(s->ctx))
3605843bb75SJerome Forissier return TEE_ERROR_ACCESS_DENIED;
3615843bb75SJerome Forissier
3625843bb75SJerome Forissier return TEE_SUCCESS;
3635843bb75SJerome Forissier }
3645843bb75SJerome Forissier
invoke_command(void * sess_ctx __unused,uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])365baa5161dSBalint Dobszay static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id,
3665843bb75SJerome Forissier uint32_t param_types,
3675843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS])
3685843bb75SJerome Forissier {
36900b3b9a2SJens Wiklander struct ts_session *s = ts_get_calling_session();
3709c34c0c7SBalint Dobszay struct user_mode_ctx *uctx = to_user_mode_ctx(s->ctx);
3715843bb75SJerome Forissier
3725843bb75SJerome Forissier switch (cmd_id) {
3735843bb75SJerome Forissier case PTA_SYSTEM_ADD_RNG_ENTROPY:
3749c34c0c7SBalint Dobszay return system_rng_reseed(param_types, params);
3755843bb75SJerome Forissier case PTA_SYSTEM_DERIVE_TA_UNIQUE_KEY:
3769c34c0c7SBalint Dobszay return system_derive_ta_unique_key(uctx, param_types, params);
3775843bb75SJerome Forissier case PTA_SYSTEM_MAP_ZI:
3789c34c0c7SBalint Dobszay return system_map_zi(uctx, param_types, params);
3795843bb75SJerome Forissier case PTA_SYSTEM_UNMAP:
3809c34c0c7SBalint Dobszay return system_unmap(uctx, param_types, params);
3815843bb75SJerome Forissier case PTA_SYSTEM_DLOPEN:
3829c34c0c7SBalint Dobszay return system_dlopen(uctx, param_types, params);
3835843bb75SJerome Forissier case PTA_SYSTEM_DLSYM:
3849c34c0c7SBalint Dobszay return system_dlsym(uctx, param_types, params);
385dd333f03SJavier Almansa Sobrino case PTA_SYSTEM_GET_TPM_EVENT_LOG:
386dd333f03SJavier Almansa Sobrino return system_get_tpm_event_log(param_types, params);
387e4ad5ccdSAleksandr Anisimov case PTA_SYSTEM_SUPP_PLUGIN_INVOKE:
388e4ad5ccdSAleksandr Anisimov return system_supp_plugin_invoke(param_types, params);
3895843bb75SJerome Forissier default:
3905843bb75SJerome Forissier break;
3915843bb75SJerome Forissier }
3925843bb75SJerome Forissier
3935843bb75SJerome Forissier return TEE_ERROR_NOT_IMPLEMENTED;
3945843bb75SJerome Forissier }
3955843bb75SJerome Forissier
3965843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_SYSTEM_UUID, .name = "system.pta",
3975843bb75SJerome Forissier .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT,
3985843bb75SJerome Forissier .open_session_entry_point = open_session,
3995843bb75SJerome Forissier .invoke_command_entry_point = invoke_command);
400