xref: /optee_os/core/pta/tests/invoke.c (revision 85898338fa28cf3a758f5b62d93fdeeffdbfdea8)
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/pseudo_ta.h>
8963051aaSJerome Forissier #include <kernel/panic.h>
9963051aaSJerome Forissier #include <mm/core_memprot.h>
10963051aaSJerome Forissier #include <pta_invoke_tests.h>
11963051aaSJerome Forissier #include <string.h>
12963051aaSJerome Forissier #include <tee/cache.h>
13963051aaSJerome Forissier #include <tee_api_defines.h>
14963051aaSJerome Forissier #include <tee_api_types.h>
15963051aaSJerome Forissier #include <trace.h>
16963051aaSJerome Forissier #include <types_ext.h>
17963051aaSJerome Forissier 
18963051aaSJerome Forissier #include "misc.h"
19963051aaSJerome Forissier 
20963051aaSJerome Forissier #define TA_NAME		"invoke_tests.pta"
21963051aaSJerome Forissier 
22963051aaSJerome Forissier static TEE_Result test_trace(uint32_t param_types __unused,
23963051aaSJerome Forissier 			TEE_Param params[TEE_NUM_PARAMS] __unused)
24963051aaSJerome Forissier {
25963051aaSJerome Forissier 	IMSG("pseudo TA \"%s\" says \"Hello world !\"", TA_NAME);
26963051aaSJerome Forissier 
27963051aaSJerome Forissier 	return TEE_SUCCESS;
28963051aaSJerome Forissier }
29963051aaSJerome Forissier 
30963051aaSJerome Forissier static int test_v2p2v(void *va)
31963051aaSJerome Forissier {
32963051aaSJerome Forissier 	struct tee_ta_session *session;
33963051aaSJerome Forissier 	paddr_t p;
34963051aaSJerome Forissier 	void *v;
35963051aaSJerome Forissier 
36963051aaSJerome Forissier 	if  (!va)
37963051aaSJerome Forissier 		return 0;
38963051aaSJerome Forissier 
39963051aaSJerome Forissier 	if (tee_ta_get_current_session(&session))
40963051aaSJerome Forissier 		panic();
41963051aaSJerome Forissier 
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 
48963051aaSJerome Forissier 	if (session->clnt_id.login == TEE_LOGIN_TRUSTED_APP) {
49963051aaSJerome Forissier 		v = phys_to_virt(p, MEM_AREA_TA_VASPACE);
50963051aaSJerome Forissier 	} else {
51963051aaSJerome Forissier 		v = phys_to_virt(p, MEM_AREA_NSEC_SHM);
52963051aaSJerome Forissier 		if (!v)
53963051aaSJerome Forissier 			v = phys_to_virt(p, MEM_AREA_SDP_MEM);
54963051aaSJerome Forissier 		if (!v)
55963051aaSJerome Forissier 			v = phys_to_virt(p, MEM_AREA_SHM_VASPACE);
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 /*
74963051aaSJerome Forissier  * Supported tests on parameters
75963051aaSJerome Forissier  * (I, J, K, L refer to param index)
76963051aaSJerome Forissier  *
77963051aaSJerome Forissier  * Case 1: command parameters type are: 1 in/out value, 3 empty.
78963051aaSJerome Forissier  *         => process outI.a = inI.a + inI.b
79963051aaSJerome Forissier  * Case 2: command parameters type are: 3 input value, 1 output value
80963051aaSJerome Forissier  *         => process = outI.a = inJ.a + inK.a + inL.a
81963051aaSJerome Forissier  * Case 3: command parameters type are: 1 in/out memref, 3 empty.
82963051aaSJerome Forissier  *         => process = outI[0] = sum(inI[0..len-1])
83963051aaSJerome Forissier  */
84963051aaSJerome Forissier static TEE_Result test_entry_params(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
85963051aaSJerome Forissier {
86963051aaSJerome Forissier 	size_t i;
87963051aaSJerome Forissier 	uint8_t d8, *in;
88963051aaSJerome Forissier 
89963051aaSJerome Forissier 	/* case 1a: 1 input/output value argument */
90963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INOUT) &&
91963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
92963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
93963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
94963051aaSJerome Forissier 		p[0].value.a = p[0].value.a + p[0].value.b;
95963051aaSJerome Forissier 		return TEE_SUCCESS;
96963051aaSJerome Forissier 	}
97963051aaSJerome Forissier 	/* case 1b: 1 input/output value argument */
98963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
99963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INOUT) &&
100963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
101963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
102963051aaSJerome Forissier 		p[1].value.a = p[1].value.a + p[1].value.b;
103963051aaSJerome Forissier 		return TEE_SUCCESS;
104963051aaSJerome Forissier 	}
105963051aaSJerome Forissier 	/* case 1c: 1 input/output value argument */
106963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
107963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
108963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INOUT) &&
109963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
110963051aaSJerome Forissier 		p[2].value.a = p[2].value.a + p[2].value.b;
111963051aaSJerome Forissier 		return TEE_SUCCESS;
112963051aaSJerome Forissier 	}
113963051aaSJerome Forissier 	/* case 1d: 1 input/output value argument */
114963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
115963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
116963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
117963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INOUT)) {
118963051aaSJerome Forissier 		p[3].value.a = p[3].value.a + p[3].value.b;
119963051aaSJerome Forissier 		return TEE_SUCCESS;
120963051aaSJerome Forissier 	}
121963051aaSJerome Forissier 
122963051aaSJerome Forissier 	/* case 2a: 3 input value arguments, 1 output value argument */
123963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
124963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
125963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
126963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
127963051aaSJerome Forissier 		p[0].value.a = p[1].value.a + p[2].value.a + p[3].value.a;
128963051aaSJerome Forissier 		p[0].value.b = p[1].value.b + p[2].value.b + p[3].value.b;
129963051aaSJerome Forissier 		return TEE_SUCCESS;
130963051aaSJerome Forissier 	}
131963051aaSJerome Forissier 	/* case 2a: 3 input value arguments, 1 output value argument */
132963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
133963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
134963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
135963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
136963051aaSJerome Forissier 		p[1].value.a = p[0].value.a + p[2].value.a + p[3].value.a;
137963051aaSJerome Forissier 		p[1].value.b = p[0].value.b + p[2].value.b + p[3].value.b;
138963051aaSJerome Forissier 		return TEE_SUCCESS;
139963051aaSJerome Forissier 	}
140963051aaSJerome Forissier 	/* case 2a: 3 input value arguments, 1 output value argument */
141963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
142963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
143963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
144963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
145963051aaSJerome Forissier 		p[2].value.a = p[0].value.a + p[1].value.a + p[3].value.a;
146963051aaSJerome Forissier 		p[2].value.b = p[0].value.b + p[1].value.b + p[3].value.b;
147963051aaSJerome Forissier 		return TEE_SUCCESS;
148963051aaSJerome Forissier 	}
149963051aaSJerome Forissier 	/* case 2a: 3 input value arguments, 1 output value argument */
150963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
151963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
152963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
153963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_OUTPUT)) {
154963051aaSJerome Forissier 		p[3].value.a = p[0].value.a + p[1].value.a + p[2].value.a;
155963051aaSJerome Forissier 		p[3].value.b = p[0].value.b + p[1].value.b + p[2].value.b;
156963051aaSJerome Forissier 		return TEE_SUCCESS;
157963051aaSJerome Forissier 	}
158963051aaSJerome Forissier 
159963051aaSJerome Forissier 	DMSG("expect memref params: %p/%" PRIu32 " - %p/%" PRIu32 "zu - %p/%" PRIu32 "zu - %p/%" PRIu32 "zu",
160963051aaSJerome Forissier 			p[0].memref.buffer, p[0].memref.size,
161963051aaSJerome Forissier 			p[1].memref.buffer, p[1].memref.size,
162963051aaSJerome Forissier 			p[2].memref.buffer, p[2].memref.size,
163963051aaSJerome Forissier 			p[3].memref.buffer, p[3].memref.size);
164963051aaSJerome Forissier 
165963051aaSJerome Forissier 	/* case 3a: 1 in/out memref argument */
166963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
167963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
168963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
169963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
170963051aaSJerome Forissier 		in = (uint8_t *)p[0].memref.buffer;
171963051aaSJerome Forissier 		if (test_v2p2v(in))
172963051aaSJerome Forissier 			return TEE_ERROR_SECURITY;
173963051aaSJerome Forissier 		d8 = 0;
174963051aaSJerome Forissier 		for (i = 0; i < p[0].memref.size; i++)
175963051aaSJerome Forissier 			d8 += in[i];
176963051aaSJerome Forissier 		*(uint8_t *)p[0].memref.buffer = d8;
177963051aaSJerome Forissier 		return TEE_SUCCESS;
178963051aaSJerome Forissier 	}
179963051aaSJerome Forissier 	/* case 3b: 1 in/out memref argument */
180963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
181963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
182963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
183963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
184963051aaSJerome Forissier 		in = (uint8_t *)p[1].memref.buffer;
185963051aaSJerome Forissier 		if (test_v2p2v(in))
186963051aaSJerome Forissier 			return TEE_ERROR_SECURITY;
187963051aaSJerome Forissier 		d8 = 0;
188963051aaSJerome Forissier 		for (i = 0; i < p[1].memref.size; i++)
189963051aaSJerome Forissier 			d8 += in[i];
190963051aaSJerome Forissier 		*(uint8_t *)p[1].memref.buffer = d8;
191963051aaSJerome Forissier 		return TEE_SUCCESS;
192963051aaSJerome Forissier 	}
193963051aaSJerome Forissier 	/* case 3c: 1 in/out memref argument */
194963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
195963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
196963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
197963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
198963051aaSJerome Forissier 		in = (uint8_t *)p[2].memref.buffer;
199963051aaSJerome Forissier 		if (test_v2p2v(in))
200963051aaSJerome Forissier 			return TEE_ERROR_SECURITY;
201963051aaSJerome Forissier 		d8 = 0;
202963051aaSJerome Forissier 		for (i = 0; i < p[2].memref.size; i++)
203963051aaSJerome Forissier 			d8 += in[i];
204963051aaSJerome Forissier 		*(uint8_t *)p[2].memref.buffer = d8;
205963051aaSJerome Forissier 		return TEE_SUCCESS;
206963051aaSJerome Forissier 	}
207963051aaSJerome Forissier 	/* case 3d: 1 in/out memref argument */
208963051aaSJerome Forissier 	if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
209963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
210963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
211963051aaSJerome Forissier 		(TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_MEMREF_INOUT)) {
212963051aaSJerome Forissier 		in = (uint8_t *)p[3].memref.buffer;
213963051aaSJerome Forissier 		if (test_v2p2v(in))
214963051aaSJerome Forissier 			return TEE_ERROR_SECURITY;
215963051aaSJerome Forissier 		d8 = 0;
216963051aaSJerome Forissier 		for (i = 0; i < p[3].memref.size; i++)
217963051aaSJerome Forissier 			d8 += in[i];
218963051aaSJerome Forissier 		*(uint8_t *)p[3].memref.buffer = d8;
219963051aaSJerome Forissier 		return TEE_SUCCESS;
220963051aaSJerome Forissier 	}
221963051aaSJerome Forissier 
222963051aaSJerome Forissier 	EMSG("unexpected parameters");
223963051aaSJerome Forissier 	return TEE_ERROR_BAD_PARAMETERS;
224963051aaSJerome Forissier }
225963051aaSJerome Forissier 
226963051aaSJerome Forissier /*
227963051aaSJerome Forissier  * Test access to Secure Data Path memory from pseudo TAs
228963051aaSJerome Forissier  */
229963051aaSJerome Forissier 
230963051aaSJerome Forissier static TEE_Result test_inject_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
231963051aaSJerome Forissier {
232963051aaSJerome Forissier 	char *src = p[0].memref.buffer;
233963051aaSJerome Forissier 	char *dst = p[1].memref.buffer;
234963051aaSJerome Forissier 	size_t sz = p[0].memref.size;
235963051aaSJerome Forissier 	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
236963051aaSJerome Forissier 					  TEE_PARAM_TYPE_MEMREF_OUTPUT,
237963051aaSJerome Forissier 					  TEE_PARAM_TYPE_NONE,
238963051aaSJerome Forissier 					  TEE_PARAM_TYPE_NONE);
239963051aaSJerome Forissier 
240963051aaSJerome Forissier 	if (exp_pt != type) {
241963051aaSJerome Forissier 		DMSG("bad parameter types");
242963051aaSJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
243963051aaSJerome Forissier 	}
244963051aaSJerome Forissier 
245963051aaSJerome Forissier 	if (p[1].memref.size < sz) {
246963051aaSJerome Forissier 		p[1].memref.size = sz;
247963051aaSJerome Forissier 		return TEE_ERROR_SHORT_BUFFER;
248963051aaSJerome Forissier 	}
249963051aaSJerome Forissier 
250963051aaSJerome Forissier 	if (!core_vbuf_is(CORE_MEM_NON_SEC, src, sz) ||
251963051aaSJerome Forissier 	    !core_vbuf_is(CORE_MEM_SDP_MEM, dst, sz)) {
252963051aaSJerome Forissier 		DMSG("bad memref secure attribute");
253963051aaSJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
254963051aaSJerome Forissier 	}
255963051aaSJerome Forissier 
256963051aaSJerome Forissier 	if (!sz)
257963051aaSJerome Forissier 		return TEE_SUCCESS;
258963051aaSJerome Forissier 
259963051aaSJerome Forissier 	/* Check that core can p2v and v2p over memory reference arguments */
260963051aaSJerome Forissier 	if (test_v2p2v(src) || test_v2p2v(src + sz - 1) ||
261963051aaSJerome Forissier 	    test_v2p2v(dst) || test_v2p2v(dst + sz - 1))
262963051aaSJerome Forissier 		return TEE_ERROR_SECURITY;
263963051aaSJerome Forissier 
264963051aaSJerome Forissier 	if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
265963051aaSJerome Forissier 		return TEE_ERROR_GENERIC;
266963051aaSJerome Forissier 
267963051aaSJerome Forissier 	memcpy(dst, src, sz);
268963051aaSJerome Forissier 
269963051aaSJerome Forissier 	if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
270963051aaSJerome Forissier 		return TEE_ERROR_GENERIC;
271963051aaSJerome Forissier 
272963051aaSJerome Forissier 	return TEE_SUCCESS;
273963051aaSJerome Forissier }
274963051aaSJerome Forissier 
275963051aaSJerome Forissier static TEE_Result test_transform_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
276963051aaSJerome Forissier {
277963051aaSJerome Forissier 	char *buf = p[0].memref.buffer;
278963051aaSJerome Forissier 	size_t sz = p[0].memref.size;
279963051aaSJerome Forissier 	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
280963051aaSJerome Forissier 					  TEE_PARAM_TYPE_NONE,
281963051aaSJerome Forissier 					  TEE_PARAM_TYPE_NONE,
282963051aaSJerome Forissier 					  TEE_PARAM_TYPE_NONE);
283963051aaSJerome Forissier 
284963051aaSJerome Forissier 	if (exp_pt != type) {
285963051aaSJerome Forissier 		DMSG("bad parameter types");
286963051aaSJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
287963051aaSJerome Forissier 	}
288963051aaSJerome Forissier 
289963051aaSJerome Forissier 	if (!core_vbuf_is(CORE_MEM_SDP_MEM, buf, sz)) {
290963051aaSJerome Forissier 		DMSG("bad memref secure attribute");
291963051aaSJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
292963051aaSJerome Forissier 	}
293963051aaSJerome Forissier 
294963051aaSJerome Forissier 	if (!sz)
295963051aaSJerome Forissier 		return TEE_SUCCESS;
296963051aaSJerome Forissier 
297963051aaSJerome Forissier 	/* Check that core can p2v and v2p over memory reference arguments */
298963051aaSJerome Forissier 	if (test_v2p2v(buf) || test_v2p2v(buf + sz - 1))
299963051aaSJerome Forissier 		return TEE_ERROR_SECURITY;
300963051aaSJerome Forissier 
301963051aaSJerome Forissier 	if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS)
302963051aaSJerome Forissier 		return TEE_ERROR_GENERIC;
303963051aaSJerome Forissier 
304963051aaSJerome Forissier 	for (; sz; sz--, buf++)
305963051aaSJerome Forissier 		*buf = ~(*buf) + 1;
306963051aaSJerome Forissier 
307963051aaSJerome Forissier 	if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS)
308963051aaSJerome Forissier 		return TEE_ERROR_GENERIC;
309963051aaSJerome Forissier 
310963051aaSJerome Forissier 	return TEE_SUCCESS;
311963051aaSJerome Forissier }
312963051aaSJerome Forissier 
313963051aaSJerome Forissier static TEE_Result test_dump_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
314963051aaSJerome Forissier {
315963051aaSJerome Forissier 	char *src = p[0].memref.buffer;
316963051aaSJerome Forissier 	char *dst = p[1].memref.buffer;
317963051aaSJerome Forissier 	size_t sz = p[0].memref.size;
318963051aaSJerome Forissier 	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
319963051aaSJerome Forissier 					  TEE_PARAM_TYPE_MEMREF_OUTPUT,
320963051aaSJerome Forissier 					  TEE_PARAM_TYPE_NONE,
321963051aaSJerome Forissier 					  TEE_PARAM_TYPE_NONE);
322963051aaSJerome Forissier 
323963051aaSJerome Forissier 	if (exp_pt != type) {
324963051aaSJerome Forissier 		DMSG("bad parameter types");
325963051aaSJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
326963051aaSJerome Forissier 	}
327963051aaSJerome Forissier 
328963051aaSJerome Forissier 	if (p[1].memref.size < sz) {
329963051aaSJerome Forissier 		p[1].memref.size = sz;
330963051aaSJerome Forissier 		return TEE_ERROR_SHORT_BUFFER;
331963051aaSJerome Forissier 	}
332963051aaSJerome Forissier 
333963051aaSJerome Forissier 	if (!core_vbuf_is(CORE_MEM_SDP_MEM, src, sz) ||
334963051aaSJerome Forissier 	    !core_vbuf_is(CORE_MEM_NON_SEC, dst, sz)) {
335963051aaSJerome Forissier 		DMSG("bad memref secure attribute");
336963051aaSJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
337963051aaSJerome Forissier 	}
338963051aaSJerome Forissier 
339963051aaSJerome Forissier 	if (!sz)
340963051aaSJerome Forissier 		return TEE_SUCCESS;
341963051aaSJerome Forissier 
342963051aaSJerome Forissier 	/* Check that core can p2v and v2p over memory reference arguments */
343963051aaSJerome Forissier 	if (test_v2p2v(src) || test_v2p2v(src + sz - 1) ||
344963051aaSJerome Forissier 	    test_v2p2v(dst) || test_v2p2v(dst + sz - 1))
345963051aaSJerome Forissier 		return TEE_ERROR_SECURITY;
346963051aaSJerome Forissier 
347963051aaSJerome Forissier 	if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
348963051aaSJerome Forissier 		return TEE_ERROR_GENERIC;
349963051aaSJerome Forissier 
350963051aaSJerome Forissier 	memcpy(dst, src, sz);
351963051aaSJerome Forissier 
352963051aaSJerome Forissier 	if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
353963051aaSJerome Forissier 		return TEE_ERROR_GENERIC;
354963051aaSJerome Forissier 
355963051aaSJerome Forissier 	return TEE_SUCCESS;
356963051aaSJerome Forissier }
357963051aaSJerome Forissier 
358963051aaSJerome Forissier /*
359963051aaSJerome Forissier  * Trusted Application Entry Points
360963051aaSJerome Forissier  */
361963051aaSJerome Forissier 
362963051aaSJerome Forissier static TEE_Result create_ta(void)
363963051aaSJerome Forissier {
364963051aaSJerome Forissier 	DMSG("create entry point for pseudo TA \"%s\"", TA_NAME);
365963051aaSJerome Forissier 	return TEE_SUCCESS;
366963051aaSJerome Forissier }
367963051aaSJerome Forissier 
368963051aaSJerome Forissier static void destroy_ta(void)
369963051aaSJerome Forissier {
370963051aaSJerome Forissier 	DMSG("destroy entry point for pseudo ta \"%s\"", TA_NAME);
371963051aaSJerome Forissier }
372963051aaSJerome Forissier 
373963051aaSJerome Forissier static TEE_Result open_session(uint32_t nParamTypes __unused,
374963051aaSJerome Forissier 		TEE_Param pParams[TEE_NUM_PARAMS] __unused,
375963051aaSJerome Forissier 		void **ppSessionContext __unused)
376963051aaSJerome Forissier {
377963051aaSJerome Forissier 	DMSG("open entry point for pseudo ta \"%s\"", TA_NAME);
378963051aaSJerome Forissier 	return TEE_SUCCESS;
379963051aaSJerome Forissier }
380963051aaSJerome Forissier 
381963051aaSJerome Forissier static void close_session(void *pSessionContext __unused)
382963051aaSJerome Forissier {
383963051aaSJerome Forissier 	DMSG("close entry point for pseudo ta \"%s\"", TA_NAME);
384963051aaSJerome Forissier }
385963051aaSJerome Forissier 
386963051aaSJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused,
387963051aaSJerome Forissier 		uint32_t nCommandID, uint32_t nParamTypes,
388963051aaSJerome Forissier 		TEE_Param pParams[TEE_NUM_PARAMS])
389963051aaSJerome Forissier {
390963051aaSJerome Forissier 	FMSG("command entry point for pseudo ta \"%s\"", TA_NAME);
391963051aaSJerome Forissier 
392963051aaSJerome Forissier 	switch (nCommandID) {
393963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_TRACE:
394963051aaSJerome Forissier 		return test_trace(nParamTypes, pParams);
395963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_PARAMS:
396963051aaSJerome Forissier 		return test_entry_params(nParamTypes, pParams);
397963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC:
398963051aaSJerome Forissier 		return test_inject_sdp(nParamTypes, pParams);
399963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC:
400963051aaSJerome Forissier 		return test_transform_sdp(nParamTypes, pParams);
401963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC:
402963051aaSJerome Forissier 		return test_dump_sdp(nParamTypes, pParams);
403963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_SELF_TESTS:
404963051aaSJerome Forissier 		return core_self_tests(nParamTypes, pParams);
405963051aaSJerome Forissier #if defined(CFG_WITH_USER_TA)
406963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_FS_HTREE:
407963051aaSJerome Forissier 		return core_fs_htree_tests(nParamTypes, pParams);
408963051aaSJerome Forissier #endif
409963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_MUTEX:
410963051aaSJerome Forissier 		return core_mutex_tests(nParamTypes, pParams);
411963051aaSJerome Forissier 	case PTA_INVOKE_TESTS_CMD_LOCKDEP:
412963051aaSJerome Forissier 		return core_lockdep_tests(nParamTypes, pParams);
413*85898338SJens Wiklander 	case PTA_INVOKE_TEST_CMD_AES_PERF:
414*85898338SJens Wiklander 		return core_aes_perf_tests(nParamTypes, pParams);
415963051aaSJerome Forissier 	default:
416963051aaSJerome Forissier 		break;
417963051aaSJerome Forissier 	}
418963051aaSJerome Forissier 	return TEE_ERROR_BAD_PARAMETERS;
419963051aaSJerome Forissier }
420963051aaSJerome Forissier 
421963051aaSJerome Forissier pseudo_ta_register(.uuid = PTA_INVOKE_TESTS_UUID, .name = TA_NAME,
422963051aaSJerome Forissier 		   .flags = PTA_DEFAULT_FLAGS | TA_FLAG_SECURE_DATA_PATH |
4233db0071cSJens Wiklander 			    TA_FLAG_CONCURRENT | TA_FLAG_DEVICE_ENUM,
424963051aaSJerome Forissier 		   .create_entry_point = create_ta,
425963051aaSJerome Forissier 		   .destroy_entry_point = destroy_ta,
426963051aaSJerome Forissier 		   .open_session_entry_point = open_session,
427963051aaSJerome Forissier 		   .close_session_entry_point = close_session,
428963051aaSJerome Forissier 		   .invoke_command_entry_point = invoke_command);
429