1963051aaSJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2963051aaSJerome Forissier /*
3963051aaSJerome Forissier * Copyright (c) 2014, STMicroelectronics International N.V.
4963051aaSJerome Forissier */
5963051aaSJerome Forissier
6963051aaSJerome Forissier #include <compiler.h>
7963051aaSJerome Forissier #include <kernel/panic.h>
800b3b9a2SJens Wiklander #include <kernel/pseudo_ta.h>
900b3b9a2SJens Wiklander #include <kernel/tee_ta_manager.h>
1000b3b9a2SJens Wiklander #include <kernel/ts_manager.h>
11963051aaSJerome Forissier #include <mm/core_memprot.h>
12963051aaSJerome Forissier #include <pta_invoke_tests.h>
13963051aaSJerome Forissier #include <string.h>
14963051aaSJerome Forissier #include <tee_api_defines.h>
15963051aaSJerome Forissier #include <tee_api_types.h>
1600b3b9a2SJens Wiklander #include <tee/cache.h>
17963051aaSJerome Forissier #include <trace.h>
18963051aaSJerome Forissier #include <types_ext.h>
19963051aaSJerome Forissier
20963051aaSJerome Forissier #include "misc.h"
21963051aaSJerome Forissier
22963051aaSJerome Forissier #define TA_NAME "invoke_tests.pta"
23963051aaSJerome Forissier
test_trace(uint32_t param_types __unused,TEE_Param params[TEE_NUM_PARAMS]__unused)24963051aaSJerome Forissier static TEE_Result test_trace(uint32_t param_types __unused,
25963051aaSJerome Forissier TEE_Param params[TEE_NUM_PARAMS] __unused)
26963051aaSJerome Forissier {
27963051aaSJerome Forissier IMSG("pseudo TA \"%s\" says \"Hello world !\"", TA_NAME);
28963051aaSJerome Forissier
29963051aaSJerome Forissier return TEE_SUCCESS;
30963051aaSJerome Forissier }
31963051aaSJerome Forissier
test_v2p2v(void * va,size_t size)32c2e4eb43SAnton Rybakov static int test_v2p2v(void *va, size_t size)
33963051aaSJerome Forissier {
3400b3b9a2SJens Wiklander struct ts_session *session = NULL;
3500b3b9a2SJens Wiklander paddr_t p = 0;
3600b3b9a2SJens Wiklander void *v = NULL;
37963051aaSJerome Forissier
38963051aaSJerome Forissier if (!va)
39963051aaSJerome Forissier return 0;
40963051aaSJerome Forissier
4100b3b9a2SJens Wiklander session = ts_get_current_session();
42963051aaSJerome Forissier p = virt_to_phys(va);
43963051aaSJerome Forissier
44963051aaSJerome Forissier /* 0 is not a valid physical address */
45963051aaSJerome Forissier if (!p)
46963051aaSJerome Forissier return 1;
47963051aaSJerome Forissier
4800b3b9a2SJens Wiklander if (to_ta_session(session)->clnt_id.login == TEE_LOGIN_TRUSTED_APP) {
49c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_TS_VASPACE, size);
50963051aaSJerome Forissier } else {
51c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_NSEC_SHM, size);
52963051aaSJerome Forissier if (!v)
53c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_SDP_MEM, size);
54963051aaSJerome Forissier if (!v)
55c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_SHM_VASPACE, size);
56963051aaSJerome Forissier }
57963051aaSJerome Forissier
58963051aaSJerome Forissier /*
59963051aaSJerome Forissier * Return an error only the vaddr found mismatches input address.
60963051aaSJerome Forissier * Finding a virtual address from a physical address cannot be painful
61963051aaSJerome Forissier * in some case (i.e pager). Moreover this operation is more debug
62963051aaSJerome Forissier * related. Thus do not report error if phys_to_virt failed
63963051aaSJerome Forissier */
64963051aaSJerome Forissier if (v && va != v) {
65963051aaSJerome Forissier EMSG("Failed to p2v/v2p on caller TA memref arguments");
66963051aaSJerome Forissier EMSG("va %p -> pa 0x%" PRIxPA " -> va %p", va, p, v);
67963051aaSJerome Forissier return 1;
68963051aaSJerome Forissier }
69963051aaSJerome Forissier
70963051aaSJerome Forissier return 0;
71963051aaSJerome Forissier }
72963051aaSJerome Forissier
73963051aaSJerome Forissier /*
74b213d8bdSEtienne Carriere * Check PTA can be invoked with a memory reference on a NULL buffer
75b213d8bdSEtienne Carriere */
test_entry_memref_null(uint32_t type,TEE_Param p[TEE_NUM_PARAMS])76b213d8bdSEtienne Carriere static TEE_Result test_entry_memref_null(uint32_t type,
77b213d8bdSEtienne Carriere TEE_Param p[TEE_NUM_PARAMS])
78b213d8bdSEtienne Carriere {
79b213d8bdSEtienne Carriere uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
80b213d8bdSEtienne Carriere TEE_PARAM_TYPE_NONE,
81b213d8bdSEtienne Carriere TEE_PARAM_TYPE_NONE,
82b213d8bdSEtienne Carriere TEE_PARAM_TYPE_NONE);
83b213d8bdSEtienne Carriere
84b213d8bdSEtienne Carriere if (exp_pt != type)
85b213d8bdSEtienne Carriere return TEE_ERROR_BAD_PARAMETERS;
86b213d8bdSEtienne Carriere
87b213d8bdSEtienne Carriere if (p[0].memref.buffer || p[0].memref.size)
88b213d8bdSEtienne Carriere return TEE_ERROR_BAD_PARAMETERS;
89b213d8bdSEtienne Carriere
90b213d8bdSEtienne Carriere return TEE_SUCCESS;
91b213d8bdSEtienne Carriere }
92b213d8bdSEtienne Carriere
93b213d8bdSEtienne Carriere /*
94963051aaSJerome Forissier * Supported tests on parameters
95963051aaSJerome Forissier * (I, J, K, L refer to param index)
96963051aaSJerome Forissier *
97963051aaSJerome Forissier * Case 1: command parameters type are: 1 in/out value, 3 empty.
98963051aaSJerome Forissier * => process outI.a = inI.a + inI.b
99963051aaSJerome Forissier * Case 2: command parameters type are: 3 input value, 1 output value
100963051aaSJerome Forissier * => process = outI.a = inJ.a + inK.a + inL.a
101963051aaSJerome Forissier * Case 3: command parameters type are: 1 in/out memref, 3 empty.
102963051aaSJerome Forissier * => process = outI[0] = sum(inI[0..len-1])
103963051aaSJerome Forissier */
test_entry_params(uint32_t type,TEE_Param p[TEE_NUM_PARAMS])104963051aaSJerome Forissier static TEE_Result test_entry_params(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
105963051aaSJerome Forissier {
106963051aaSJerome Forissier size_t i;
107963051aaSJerome Forissier uint8_t d8, *in;
108963051aaSJerome Forissier
109963051aaSJerome Forissier /* case 1a: 1 input/output value argument */
110963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INOUT) &&
111963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
112963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
113963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
114963051aaSJerome Forissier p[0].value.a = p[0].value.a + p[0].value.b;
115963051aaSJerome Forissier return TEE_SUCCESS;
116963051aaSJerome Forissier }
117963051aaSJerome Forissier /* case 1b: 1 input/output value argument */
118963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
119963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INOUT) &&
120963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
121963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
122963051aaSJerome Forissier p[1].value.a = p[1].value.a + p[1].value.b;
123963051aaSJerome Forissier return TEE_SUCCESS;
124963051aaSJerome Forissier }
125963051aaSJerome Forissier /* case 1c: 1 input/output value argument */
126963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
127963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
128963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INOUT) &&
129963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
130963051aaSJerome Forissier p[2].value.a = p[2].value.a + p[2].value.b;
131963051aaSJerome Forissier return TEE_SUCCESS;
132963051aaSJerome Forissier }
133963051aaSJerome Forissier /* case 1d: 1 input/output value argument */
134963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
135963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
136963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
137963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INOUT)) {
138963051aaSJerome Forissier p[3].value.a = p[3].value.a + p[3].value.b;
139963051aaSJerome Forissier return TEE_SUCCESS;
140963051aaSJerome Forissier }
141963051aaSJerome Forissier
142963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */
143963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
144963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
145963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
146963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
147963051aaSJerome Forissier p[0].value.a = p[1].value.a + p[2].value.a + p[3].value.a;
148963051aaSJerome Forissier p[0].value.b = p[1].value.b + p[2].value.b + p[3].value.b;
149963051aaSJerome Forissier return TEE_SUCCESS;
150963051aaSJerome Forissier }
151963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */
152963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
153963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
154963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
155963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
156963051aaSJerome Forissier p[1].value.a = p[0].value.a + p[2].value.a + p[3].value.a;
157963051aaSJerome Forissier p[1].value.b = p[0].value.b + p[2].value.b + p[3].value.b;
158963051aaSJerome Forissier return TEE_SUCCESS;
159963051aaSJerome Forissier }
160963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */
161963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
162963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
163963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
164963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
165963051aaSJerome Forissier p[2].value.a = p[0].value.a + p[1].value.a + p[3].value.a;
166963051aaSJerome Forissier p[2].value.b = p[0].value.b + p[1].value.b + p[3].value.b;
167963051aaSJerome Forissier return TEE_SUCCESS;
168963051aaSJerome Forissier }
169963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */
170963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
171963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
172963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
173963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_OUTPUT)) {
174963051aaSJerome Forissier p[3].value.a = p[0].value.a + p[1].value.a + p[2].value.a;
175963051aaSJerome Forissier p[3].value.b = p[0].value.b + p[1].value.b + p[2].value.b;
176963051aaSJerome Forissier return TEE_SUCCESS;
177963051aaSJerome Forissier }
178963051aaSJerome Forissier
1797509620bSJens Wiklander DMSG("expect memref params: %p/%zu - %p/%zu - %p/%zu - %p/%zu",
1807509620bSJens Wiklander p[0].memref.buffer, p[0].memref.size, p[1].memref.buffer,
1817509620bSJens Wiklander p[1].memref.size, p[2].memref.buffer, p[2].memref.size,
182963051aaSJerome Forissier p[3].memref.buffer, p[3].memref.size);
183963051aaSJerome Forissier
184963051aaSJerome Forissier /* case 3a: 1 in/out memref argument */
185963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
186963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
187963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
188963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
189963051aaSJerome Forissier in = (uint8_t *)p[0].memref.buffer;
190c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[0].memref.size))
191963051aaSJerome Forissier return TEE_ERROR_SECURITY;
192963051aaSJerome Forissier d8 = 0;
193963051aaSJerome Forissier for (i = 0; i < p[0].memref.size; i++)
194963051aaSJerome Forissier d8 += in[i];
195963051aaSJerome Forissier *(uint8_t *)p[0].memref.buffer = d8;
196963051aaSJerome Forissier return TEE_SUCCESS;
197963051aaSJerome Forissier }
198963051aaSJerome Forissier /* case 3b: 1 in/out memref argument */
199963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
200963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
201963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
202963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
203963051aaSJerome Forissier in = (uint8_t *)p[1].memref.buffer;
204c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[1].memref.size))
205963051aaSJerome Forissier return TEE_ERROR_SECURITY;
206963051aaSJerome Forissier d8 = 0;
207963051aaSJerome Forissier for (i = 0; i < p[1].memref.size; i++)
208963051aaSJerome Forissier d8 += in[i];
209963051aaSJerome Forissier *(uint8_t *)p[1].memref.buffer = d8;
210963051aaSJerome Forissier return TEE_SUCCESS;
211963051aaSJerome Forissier }
212963051aaSJerome Forissier /* case 3c: 1 in/out memref argument */
213963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
214963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
215963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
216963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
217963051aaSJerome Forissier in = (uint8_t *)p[2].memref.buffer;
218c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[2].memref.size))
219963051aaSJerome Forissier return TEE_ERROR_SECURITY;
220963051aaSJerome Forissier d8 = 0;
221963051aaSJerome Forissier for (i = 0; i < p[2].memref.size; i++)
222963051aaSJerome Forissier d8 += in[i];
223963051aaSJerome Forissier *(uint8_t *)p[2].memref.buffer = d8;
224963051aaSJerome Forissier return TEE_SUCCESS;
225963051aaSJerome Forissier }
226963051aaSJerome Forissier /* case 3d: 1 in/out memref argument */
227963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
228963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
229963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
230963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_MEMREF_INOUT)) {
231963051aaSJerome Forissier in = (uint8_t *)p[3].memref.buffer;
232c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[3].memref.size))
233963051aaSJerome Forissier return TEE_ERROR_SECURITY;
234963051aaSJerome Forissier d8 = 0;
235963051aaSJerome Forissier for (i = 0; i < p[3].memref.size; i++)
236963051aaSJerome Forissier d8 += in[i];
237963051aaSJerome Forissier *(uint8_t *)p[3].memref.buffer = d8;
238963051aaSJerome Forissier return TEE_SUCCESS;
239963051aaSJerome Forissier }
240963051aaSJerome Forissier
241963051aaSJerome Forissier EMSG("unexpected parameters");
242963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
243963051aaSJerome Forissier }
244963051aaSJerome Forissier
245963051aaSJerome Forissier /*
246963051aaSJerome Forissier * Test access to Secure Data Path memory from pseudo TAs
247963051aaSJerome Forissier */
248963051aaSJerome Forissier
test_inject_sdp(uint32_t type,TEE_Param p[TEE_NUM_PARAMS])249963051aaSJerome Forissier static TEE_Result test_inject_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
250963051aaSJerome Forissier {
251963051aaSJerome Forissier char *src = p[0].memref.buffer;
252963051aaSJerome Forissier char *dst = p[1].memref.buffer;
253963051aaSJerome Forissier size_t sz = p[0].memref.size;
254963051aaSJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
255963051aaSJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT,
256963051aaSJerome Forissier TEE_PARAM_TYPE_NONE,
257963051aaSJerome Forissier TEE_PARAM_TYPE_NONE);
258963051aaSJerome Forissier
259963051aaSJerome Forissier if (exp_pt != type) {
260963051aaSJerome Forissier DMSG("bad parameter types");
261963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
262963051aaSJerome Forissier }
263963051aaSJerome Forissier
264963051aaSJerome Forissier if (p[1].memref.size < sz) {
265963051aaSJerome Forissier p[1].memref.size = sz;
266963051aaSJerome Forissier return TEE_ERROR_SHORT_BUFFER;
267963051aaSJerome Forissier }
268963051aaSJerome Forissier
269963051aaSJerome Forissier if (!core_vbuf_is(CORE_MEM_NON_SEC, src, sz) ||
270963051aaSJerome Forissier !core_vbuf_is(CORE_MEM_SDP_MEM, dst, sz)) {
271963051aaSJerome Forissier DMSG("bad memref secure attribute");
272963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
273963051aaSJerome Forissier }
274963051aaSJerome Forissier
275963051aaSJerome Forissier if (!sz)
276963051aaSJerome Forissier return TEE_SUCCESS;
277963051aaSJerome Forissier
278963051aaSJerome Forissier /* Check that core can p2v and v2p over memory reference arguments */
279c2e4eb43SAnton Rybakov if (test_v2p2v(src, sz) || test_v2p2v(dst, sz))
280963051aaSJerome Forissier return TEE_ERROR_SECURITY;
281963051aaSJerome Forissier
282963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
283963051aaSJerome Forissier return TEE_ERROR_GENERIC;
284963051aaSJerome Forissier
285963051aaSJerome Forissier memcpy(dst, src, sz);
286963051aaSJerome Forissier
287963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
288963051aaSJerome Forissier return TEE_ERROR_GENERIC;
289963051aaSJerome Forissier
290963051aaSJerome Forissier return TEE_SUCCESS;
291963051aaSJerome Forissier }
292963051aaSJerome Forissier
test_transform_sdp(uint32_t type,TEE_Param p[TEE_NUM_PARAMS])293963051aaSJerome Forissier static TEE_Result test_transform_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
294963051aaSJerome Forissier {
295963051aaSJerome Forissier char *buf = p[0].memref.buffer;
296963051aaSJerome Forissier size_t sz = p[0].memref.size;
297963051aaSJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
298963051aaSJerome Forissier TEE_PARAM_TYPE_NONE,
299963051aaSJerome Forissier TEE_PARAM_TYPE_NONE,
300963051aaSJerome Forissier TEE_PARAM_TYPE_NONE);
301963051aaSJerome Forissier
302963051aaSJerome Forissier if (exp_pt != type) {
303963051aaSJerome Forissier DMSG("bad parameter types");
304963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
305963051aaSJerome Forissier }
306963051aaSJerome Forissier
307963051aaSJerome Forissier if (!core_vbuf_is(CORE_MEM_SDP_MEM, buf, sz)) {
308963051aaSJerome Forissier DMSG("bad memref secure attribute");
309963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
310963051aaSJerome Forissier }
311963051aaSJerome Forissier
312963051aaSJerome Forissier if (!sz)
313963051aaSJerome Forissier return TEE_SUCCESS;
314963051aaSJerome Forissier
315963051aaSJerome Forissier /* Check that core can p2v and v2p over memory reference arguments */
316c2e4eb43SAnton Rybakov if (test_v2p2v(buf, sz))
317963051aaSJerome Forissier return TEE_ERROR_SECURITY;
318963051aaSJerome Forissier
319963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS)
320963051aaSJerome Forissier return TEE_ERROR_GENERIC;
321963051aaSJerome Forissier
322963051aaSJerome Forissier for (; sz; sz--, buf++)
323963051aaSJerome Forissier *buf = ~(*buf) + 1;
324963051aaSJerome Forissier
325963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS)
326963051aaSJerome Forissier return TEE_ERROR_GENERIC;
327963051aaSJerome Forissier
328963051aaSJerome Forissier return TEE_SUCCESS;
329963051aaSJerome Forissier }
330963051aaSJerome Forissier
test_dump_sdp(uint32_t type,TEE_Param p[TEE_NUM_PARAMS])331963051aaSJerome Forissier static TEE_Result test_dump_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
332963051aaSJerome Forissier {
333963051aaSJerome Forissier char *src = p[0].memref.buffer;
334963051aaSJerome Forissier char *dst = p[1].memref.buffer;
335963051aaSJerome Forissier size_t sz = p[0].memref.size;
336963051aaSJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
337963051aaSJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT,
338963051aaSJerome Forissier TEE_PARAM_TYPE_NONE,
339963051aaSJerome Forissier TEE_PARAM_TYPE_NONE);
340963051aaSJerome Forissier
341963051aaSJerome Forissier if (exp_pt != type) {
342963051aaSJerome Forissier DMSG("bad parameter types");
343963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
344963051aaSJerome Forissier }
345963051aaSJerome Forissier
346963051aaSJerome Forissier if (p[1].memref.size < sz) {
347963051aaSJerome Forissier p[1].memref.size = sz;
348963051aaSJerome Forissier return TEE_ERROR_SHORT_BUFFER;
349963051aaSJerome Forissier }
350963051aaSJerome Forissier
351963051aaSJerome Forissier if (!core_vbuf_is(CORE_MEM_SDP_MEM, src, sz) ||
352963051aaSJerome Forissier !core_vbuf_is(CORE_MEM_NON_SEC, dst, sz)) {
353963051aaSJerome Forissier DMSG("bad memref secure attribute");
354963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
355963051aaSJerome Forissier }
356963051aaSJerome Forissier
357963051aaSJerome Forissier if (!sz)
358963051aaSJerome Forissier return TEE_SUCCESS;
359963051aaSJerome Forissier
360963051aaSJerome Forissier /* Check that core can p2v and v2p over memory reference arguments */
361c2e4eb43SAnton Rybakov if (test_v2p2v(src, sz) || test_v2p2v(dst, sz))
362963051aaSJerome Forissier return TEE_ERROR_SECURITY;
363963051aaSJerome Forissier
364963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
365963051aaSJerome Forissier return TEE_ERROR_GENERIC;
366963051aaSJerome Forissier
367963051aaSJerome Forissier memcpy(dst, src, sz);
368963051aaSJerome Forissier
369963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
370963051aaSJerome Forissier return TEE_ERROR_GENERIC;
371963051aaSJerome Forissier
372963051aaSJerome Forissier return TEE_SUCCESS;
373963051aaSJerome Forissier }
374963051aaSJerome Forissier
375963051aaSJerome Forissier /*
376963051aaSJerome Forissier * Trusted Application Entry Points
377963051aaSJerome Forissier */
378963051aaSJerome Forissier
create_ta(void)379963051aaSJerome Forissier static TEE_Result create_ta(void)
380963051aaSJerome Forissier {
381963051aaSJerome Forissier DMSG("create entry point for pseudo TA \"%s\"", TA_NAME);
382963051aaSJerome Forissier return TEE_SUCCESS;
383963051aaSJerome Forissier }
384963051aaSJerome Forissier
destroy_ta(void)385963051aaSJerome Forissier static void destroy_ta(void)
386963051aaSJerome Forissier {
387963051aaSJerome Forissier DMSG("destroy entry point for pseudo ta \"%s\"", TA_NAME);
388963051aaSJerome Forissier }
389963051aaSJerome Forissier
open_session(uint32_t nParamTypes __unused,TEE_Param pParams[TEE_NUM_PARAMS]__unused,void ** ppSessionContext __unused)390963051aaSJerome Forissier static TEE_Result open_session(uint32_t nParamTypes __unused,
391963051aaSJerome Forissier TEE_Param pParams[TEE_NUM_PARAMS] __unused,
392963051aaSJerome Forissier void **ppSessionContext __unused)
393963051aaSJerome Forissier {
394963051aaSJerome Forissier DMSG("open entry point for pseudo ta \"%s\"", TA_NAME);
395963051aaSJerome Forissier return TEE_SUCCESS;
396963051aaSJerome Forissier }
397963051aaSJerome Forissier
close_session(void * pSessionContext __unused)398963051aaSJerome Forissier static void close_session(void *pSessionContext __unused)
399963051aaSJerome Forissier {
400963051aaSJerome Forissier DMSG("close entry point for pseudo ta \"%s\"", TA_NAME);
401963051aaSJerome Forissier }
402963051aaSJerome Forissier
invoke_command(void * pSessionContext __unused,uint32_t nCommandID,uint32_t nParamTypes,TEE_Param pParams[TEE_NUM_PARAMS])403963051aaSJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused,
404963051aaSJerome Forissier uint32_t nCommandID, uint32_t nParamTypes,
405963051aaSJerome Forissier TEE_Param pParams[TEE_NUM_PARAMS])
406963051aaSJerome Forissier {
407963051aaSJerome Forissier FMSG("command entry point for pseudo ta \"%s\"", TA_NAME);
408963051aaSJerome Forissier
409963051aaSJerome Forissier switch (nCommandID) {
410963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_TRACE:
411963051aaSJerome Forissier return test_trace(nParamTypes, pParams);
412963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_PARAMS:
413963051aaSJerome Forissier return test_entry_params(nParamTypes, pParams);
414b213d8bdSEtienne Carriere case PTA_INVOKE_TESTS_CMD_MEMREF_NULL:
415b213d8bdSEtienne Carriere return test_entry_memref_null(nParamTypes, pParams);
416963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC:
417963051aaSJerome Forissier return test_inject_sdp(nParamTypes, pParams);
418963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC:
419963051aaSJerome Forissier return test_transform_sdp(nParamTypes, pParams);
420963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC:
421963051aaSJerome Forissier return test_dump_sdp(nParamTypes, pParams);
422963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_SELF_TESTS:
423963051aaSJerome Forissier return core_self_tests(nParamTypes, pParams);
424c6b34ea8SJerome Forissier #if defined(CFG_REE_FS) && defined(CFG_WITH_USER_TA)
425963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_FS_HTREE:
426963051aaSJerome Forissier return core_fs_htree_tests(nParamTypes, pParams);
427963051aaSJerome Forissier #endif
428963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_MUTEX:
429963051aaSJerome Forissier return core_mutex_tests(nParamTypes, pParams);
430963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_LOCKDEP:
431963051aaSJerome Forissier return core_lockdep_tests(nParamTypes, pParams);
43285898338SJens Wiklander case PTA_INVOKE_TEST_CMD_AES_PERF:
43385898338SJens Wiklander return core_aes_perf_tests(nParamTypes, pParams);
434d783b681SEtienne Carriere case PTA_INVOKE_TESTS_CMD_DT_DRIVER_TESTS:
435d783b681SEtienne Carriere return core_dt_driver_tests(nParamTypes, pParams);
436*76d920d3SRaymond Mao case PTA_INVOKE_TESTS_CMD_TRANSFER_LIST_TESTS:
437*76d920d3SRaymond Mao return core_transfer_list_tests(nParamTypes, pParams);
438963051aaSJerome Forissier default:
439963051aaSJerome Forissier break;
440963051aaSJerome Forissier }
441963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
442963051aaSJerome Forissier }
443963051aaSJerome Forissier
444963051aaSJerome Forissier pseudo_ta_register(.uuid = PTA_INVOKE_TESTS_UUID, .name = TA_NAME,
445963051aaSJerome Forissier .flags = PTA_DEFAULT_FLAGS | TA_FLAG_SECURE_DATA_PATH |
4463db0071cSJens Wiklander TA_FLAG_CONCURRENT | TA_FLAG_DEVICE_ENUM,
447963051aaSJerome Forissier .create_entry_point = create_ta,
448963051aaSJerome Forissier .destroy_entry_point = destroy_ta,
449963051aaSJerome Forissier .open_session_entry_point = open_session,
450963051aaSJerome Forissier .close_session_entry_point = close_session,
451963051aaSJerome Forissier .invoke_command_entry_point = invoke_command);
452