2 * Copyright (c) 2014, STMicroelectronics International N.V.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
29 #include <kernel/pseudo_ta.h>
30 #include <mm/core_memprot.h>
31 #include <pta_invoke_tests.h>
33 #include <tee/cache.h>
34 #include <tee_api_defines.h>
35 #include <tee_api_types.h>
37 #include <types_ext.h>
39 #include "core_self_tests.h"
41 #define TA_NAME "invoke_tests.pta"
43 static TEE_Result test_trace(uint32_t param_types __unused,
44 TEE_Param params[TEE_NUM_PARAMS] __unused)
46 IMSG("pseudo TA \"%s\" says \"Hello world !\"", TA_NAME);
52 * Supported tests on parameters
53 * (I, J, K, L refer to param index)
55 * Case 1: command parameters type are: 1 in/out value, 3 empty.
56 * => process outI.a = inI.a + inI.b
57 * Case 2: command parameters type are: 3 input value, 1 output value
58 * => process = outI.a = inJ.a + inK.a + inL.a
59 * Case 3: command parameters type are: 1 in/out memref, 3 empty.
60 * => process = outI[0] = sum(inI[0..len-1])
62 static TEE_Result test_entry_params(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
67 /* case 1a: 1 input/output value argument */
68 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INOUT) &&
69 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
70 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
71 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
72 p[0].value.a = p[0].value.a + p[0].value.b;
75 /* case 1b: 1 input/output value argument */
76 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
77 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INOUT) &&
78 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
79 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
80 p[1].value.a = p[1].value.a + p[1].value.b;
83 /* case 1c: 1 input/output value argument */
84 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
85 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
86 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INOUT) &&
87 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
88 p[2].value.a = p[2].value.a + p[2].value.b;
91 /* case 1d: 1 input/output value argument */
92 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
93 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
94 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
95 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INOUT)) {
96 p[3].value.a = p[3].value.a + p[3].value.b;
100 /* case 2a: 3 input value arguments, 1 output value argument */
101 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
102 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
103 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
104 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
105 p[0].value.a = p[1].value.a + p[2].value.a + p[3].value.a;
106 p[0].value.b = p[1].value.b + p[2].value.b + p[3].value.b;
109 /* case 2a: 3 input value arguments, 1 output value argument */
110 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
111 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
112 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
113 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
114 p[1].value.a = p[0].value.a + p[2].value.a + p[3].value.a;
115 p[1].value.b = p[0].value.b + p[2].value.b + p[3].value.b;
118 /* case 2a: 3 input value arguments, 1 output value argument */
119 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
120 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
121 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
122 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
123 p[2].value.a = p[0].value.a + p[1].value.a + p[3].value.a;
124 p[2].value.b = p[0].value.b + p[1].value.b + p[3].value.b;
127 /* case 2a: 3 input value arguments, 1 output value argument */
128 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
129 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
130 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
131 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_OUTPUT)) {
132 p[3].value.a = p[0].value.a + p[1].value.a + p[2].value.a;
133 p[3].value.b = p[0].value.b + p[1].value.b + p[2].value.b;
137 DMSG("expect memref params: %p/%" PRIu32 " - %p/%" PRIu32 "zu - %p/%" PRIu32 "zu - %p/%" PRIu32 "zu",
138 p[0].memref.buffer, p[0].memref.size,
139 p[1].memref.buffer, p[1].memref.size,
140 p[2].memref.buffer, p[2].memref.size,
141 p[3].memref.buffer, p[3].memref.size);
143 /* case 3a: 1 in/out memref argument */
144 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
145 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
146 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
147 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
148 in = (uint8_t *)p[0].memref.buffer;
150 for (i = 0; i < p[0].memref.size; i++)
152 *(uint8_t *)p[0].memref.buffer = d8;
155 /* case 3b: 1 in/out memref argument */
156 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
157 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
158 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
159 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
160 in = (uint8_t *)p[1].memref.buffer;
162 for (i = 0; i < p[1].memref.size; i++)
164 *(uint8_t *)p[1].memref.buffer = d8;
167 /* case 3c: 1 in/out memref argument */
168 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
169 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
170 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
171 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
172 in = (uint8_t *)p[2].memref.buffer;
174 for (i = 0; i < p[2].memref.size; i++)
176 *(uint8_t *)p[2].memref.buffer = d8;
179 /* case 3d: 1 in/out memref argument */
180 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
181 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
182 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
183 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_MEMREF_INOUT)) {
184 in = (uint8_t *)p[3].memref.buffer;
186 for (i = 0; i < p[3].memref.size; i++)
188 *(uint8_t *)p[3].memref.buffer = d8;
192 EMSG("unexpected parameters");
193 return TEE_ERROR_BAD_PARAMETERS;
197 * Test access to Secure Data Path memory from pseudo TAs
200 static TEE_Result test_inject_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
202 char *src = p[0].memref.buffer;
203 char *dst = p[1].memref.buffer;
204 size_t sz = p[0].memref.size;
205 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
206 TEE_PARAM_TYPE_MEMREF_OUTPUT,
208 TEE_PARAM_TYPE_NONE);
210 if (exp_pt != type) {
211 DMSG("bad parameter types");
212 return TEE_ERROR_BAD_PARAMETERS;
215 if (p[1].memref.size < sz) {
216 p[1].memref.size = sz;
217 return TEE_ERROR_SHORT_BUFFER;
221 if (!core_vbuf_is(CORE_MEM_NSEC_SHM, src, sz) ||
222 !core_vbuf_is(CORE_MEM_SDP_MEM, dst, sz)) {
223 DMSG("bad memref secure attribute");
224 return TEE_ERROR_BAD_PARAMETERS;
227 if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
228 return TEE_ERROR_GENERIC;
230 memcpy(dst, src, sz);
232 if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
233 return TEE_ERROR_GENERIC;
238 static TEE_Result test_transform_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
240 char *buf = p[0].memref.buffer;
241 size_t sz = p[0].memref.size;
242 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
245 TEE_PARAM_TYPE_NONE);
247 if (exp_pt != type) {
248 DMSG("bad parameter types");
249 return TEE_ERROR_BAD_PARAMETERS;
252 if (!core_vbuf_is(CORE_MEM_SDP_MEM, buf, sz)) {
253 DMSG("bad memref secure attribute");
254 return TEE_ERROR_BAD_PARAMETERS;
257 if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS)
258 return TEE_ERROR_GENERIC;
260 for (; sz; sz--, buf++)
263 if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS)
264 return TEE_ERROR_GENERIC;
269 static TEE_Result test_dump_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
271 char *src = p[0].memref.buffer;
272 char *dst = p[1].memref.buffer;
273 size_t sz = p[0].memref.size;
274 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
275 TEE_PARAM_TYPE_MEMREF_OUTPUT,
277 TEE_PARAM_TYPE_NONE);
279 if (exp_pt != type) {
280 DMSG("bad parameter types");
281 return TEE_ERROR_BAD_PARAMETERS;
284 if (p[1].memref.size < sz) {
285 p[1].memref.size = sz;
286 return TEE_ERROR_SHORT_BUFFER;
289 if (!core_vbuf_is(CORE_MEM_SDP_MEM, src, sz) ||
290 !core_vbuf_is(CORE_MEM_NSEC_SHM, dst, sz)) {
291 DMSG("bad memref secure attribute");
292 return TEE_ERROR_BAD_PARAMETERS;
295 if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
296 return TEE_ERROR_GENERIC;
298 memcpy(dst, src, sz);
300 if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS)
301 return TEE_ERROR_GENERIC;
307 * Trusted Application Entry Points
310 static TEE_Result create_ta(void)
312 DMSG("create entry point for pseudo TA \"%s\"", TA_NAME);
316 static void destroy_ta(void)
318 DMSG("destroy entry point for pseudo ta \"%s\"", TA_NAME);
321 static TEE_Result open_session(uint32_t nParamTypes __unused,
322 TEE_Param pParams[TEE_NUM_PARAMS] __unused,
323 void **ppSessionContext __unused)
325 DMSG("open entry point for pseudo ta \"%s\"", TA_NAME);
329 static void close_session(void *pSessionContext __unused)
331 DMSG("close entry point for pseudo ta \"%s\"", TA_NAME);
334 static TEE_Result invoke_command(void *pSessionContext __unused,
335 uint32_t nCommandID, uint32_t nParamTypes,
336 TEE_Param pParams[TEE_NUM_PARAMS])
338 DMSG("command entry point for pseudo ta \"%s\"", TA_NAME);
340 switch (nCommandID) {
341 case PTA_INVOKE_TESTS_CMD_TRACE:
342 return test_trace(nParamTypes, pParams);
343 case PTA_INVOKE_TESTS_CMD_PARAMS:
344 return test_entry_params(nParamTypes, pParams);
345 case PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC:
346 return test_inject_sdp(nParamTypes, pParams);
347 case PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC:
348 return test_transform_sdp(nParamTypes, pParams);
349 case PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC:
350 return test_dump_sdp(nParamTypes, pParams);
351 case PTA_INVOKE_TESTS_CMD_SELF_TESTS:
352 return core_self_tests(nParamTypes, pParams);
353 #if defined(CFG_WITH_USER_TA)
354 case PTA_INVOKE_TESTS_CMD_FS_HTREE:
355 return core_fs_htree_tests(nParamTypes, pParams);
360 return TEE_ERROR_BAD_PARAMETERS;
363 pseudo_ta_register(.uuid = PTA_INVOKE_TESTS_UUID, .name = TA_NAME,
364 .flags = PTA_DEFAULT_FLAGS | TA_FLAG_SECURE_DATA_PATH,
365 .create_entry_point = create_ta,
366 .destroy_entry_point = destroy_ta,
367 .open_session_entry_point = open_session,
368 .close_session_entry_point = close_session,
369 .invoke_command_entry_point = invoke_command);