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.
28 #include <types_ext.h>
29 #include <kernel/pseudo_ta.h>
31 #include <tee_api_types.h>
32 #include <tee_api_defines.h>
33 #include "core_self_tests.h"
35 #define TA_NAME "sta_self_tests.ta"
37 #define STA_SELF_TEST_UUID \
38 { 0xd96a5b40, 0xc3e5, 0x21e3, \
39 { 0x87, 0x94, 0x10, 0x02, 0xa5, 0xd5, 0xc6, 0x1b } }
43 #define CMD_SELF_TESTS 2
45 static TEE_Result test_trace(uint32_t param_types __unused,
46 TEE_Param params[TEE_NUM_PARAMS] __unused)
48 IMSG("pseudo TA \"%s\" says \"Hello world !\"", TA_NAME);
54 * Supported tests on parameters
55 * (I, J, K, L refer to param index)
57 * Case 1: command parameters type are: 1 in/out value, 3 empty.
58 * => process outI.a = inI.a + inI.b
59 * Case 2: command parameters type are: 3 input value, 1 output value
60 * => process = outI.a = inJ.a + inK.a + inL.a
61 * Case 3: command parameters type are: 1 in/out memref, 3 empty.
62 * => process = outI[0] = sum(inI[0..len-1])
64 static TEE_Result test_entry_params(uint32_t type, TEE_Param p[TEE_NUM_PARAMS])
69 /* case 1a: 1 input/output value argument */
70 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INOUT) &&
71 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
72 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
73 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
74 p[0].value.a = p[0].value.a + p[0].value.b;
77 /* case 1b: 1 input/output value argument */
78 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
79 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INOUT) &&
80 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
81 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
82 p[1].value.a = p[1].value.a + p[1].value.b;
85 /* case 1c: 1 input/output value argument */
86 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
87 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
88 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INOUT) &&
89 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
90 p[2].value.a = p[2].value.a + p[2].value.b;
93 /* case 1d: 1 input/output value argument */
94 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
95 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
96 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
97 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INOUT)) {
98 p[3].value.a = p[3].value.a + p[3].value.b;
102 /* case 2a: 3 input value arguments, 1 output value argument */
103 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
104 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
105 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
106 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
107 p[0].value.a = p[1].value.a + p[2].value.a + p[3].value.a;
108 p[0].value.b = p[1].value.b + p[2].value.b + p[3].value.b;
111 /* case 2a: 3 input value arguments, 1 output value argument */
112 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
113 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
114 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
115 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
116 p[1].value.a = p[0].value.a + p[2].value.a + p[3].value.a;
117 p[1].value.b = p[0].value.b + p[2].value.b + p[3].value.b;
120 /* case 2a: 3 input value arguments, 1 output value argument */
121 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
122 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
123 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_OUTPUT) &&
124 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) {
125 p[2].value.a = p[0].value.a + p[1].value.a + p[3].value.a;
126 p[2].value.b = p[0].value.b + p[1].value.b + p[3].value.b;
129 /* case 2a: 3 input value arguments, 1 output value argument */
130 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) &&
131 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) &&
132 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) &&
133 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_OUTPUT)) {
134 p[3].value.a = p[0].value.a + p[1].value.a + p[2].value.a;
135 p[3].value.b = p[0].value.b + p[1].value.b + p[2].value.b;
139 DMSG("expect memref params: %p/%" PRIu32 " - %p/%" PRIu32 "zu - %p/%" PRIu32 "zu - %p/%" PRIu32 "zu",
140 p[0].memref.buffer, p[0].memref.size,
141 p[1].memref.buffer, p[1].memref.size,
142 p[2].memref.buffer, p[2].memref.size,
143 p[3].memref.buffer, p[3].memref.size);
145 /* case 3a: 1 in/out memref argument */
146 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
147 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
148 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
149 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
150 in = (uint8_t *)p[0].memref.buffer;
152 for (i = 0; i < p[0].memref.size; i++)
154 *(uint8_t *)p[0].memref.buffer = d8;
157 /* case 3b: 1 in/out memref argument */
158 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
159 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
160 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
161 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
162 in = (uint8_t *)p[1].memref.buffer;
164 for (i = 0; i < p[1].memref.size; i++)
166 *(uint8_t *)p[1].memref.buffer = d8;
169 /* case 3c: 1 in/out memref argument */
170 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
171 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
172 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_MEMREF_INOUT) &&
173 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) {
174 in = (uint8_t *)p[2].memref.buffer;
176 for (i = 0; i < p[2].memref.size; i++)
178 *(uint8_t *)p[2].memref.buffer = d8;
181 /* case 3d: 1 in/out memref argument */
182 if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) &&
183 (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) &&
184 (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) &&
185 (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_MEMREF_INOUT)) {
186 in = (uint8_t *)p[3].memref.buffer;
188 for (i = 0; i < p[3].memref.size; i++)
190 *(uint8_t *)p[3].memref.buffer = d8;
194 EMSG("unexpected parameters");
195 return TEE_ERROR_BAD_PARAMETERS;
199 * Trusted Application Entry Points
202 static TEE_Result create_ta(void)
204 DMSG("create entry point for pseudo TA \"%s\"", TA_NAME);
208 static void destroy_ta(void)
210 DMSG("destroy entry point for pseudo ta \"%s\"", TA_NAME);
213 static TEE_Result open_session(uint32_t nParamTypes __unused,
214 TEE_Param pParams[TEE_NUM_PARAMS] __unused,
215 void **ppSessionContext __unused)
217 DMSG("open entry point for pseudo ta \"%s\"", TA_NAME);
221 static void close_session(void *pSessionContext __unused)
223 DMSG("close entry point for pseudo ta \"%s\"", TA_NAME);
226 static TEE_Result invoke_command(void *pSessionContext __unused,
227 uint32_t nCommandID, uint32_t nParamTypes,
228 TEE_Param pParams[TEE_NUM_PARAMS])
230 DMSG("command entry point for pseudo ta \"%s\"", TA_NAME);
232 switch (nCommandID) {
234 return test_trace(nParamTypes, pParams);
236 return test_entry_params(nParamTypes, pParams);
238 return core_self_tests(nParamTypes, pParams);
242 return TEE_ERROR_BAD_PARAMETERS;
245 pseudo_ta_register(.uuid = STA_SELF_TEST_UUID, .name = TA_NAME,
246 .flags = PTA_DEFAULT_FLAGS,
247 .create_entry_point = create_ta,
248 .destroy_entry_point = destroy_ta,
249 .open_session_entry_point = open_session,
250 .close_session_entry_point = close_session,
251 .invoke_command_entry_point = invoke_command);