1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (c) 2014, STMicroelectronics International N.V.
4 * Copyright (c) 2020, Linaro Limited
5 */
6
7 #ifndef XML_COMMON_API_H_
8 #define XML_COMMON_API_H_
9
10 #include <adbg.h>
11 #include <tee_client_api.h>
12
13 #include "xtest_helpers.h"
14 #include "xtest_test.h"
15
16 #define BIT(n) (1ul << (n))
17 #ifndef MAX
18 #define MAX(a, b) ((a) > (b) ? (a) : (b))
19 #endif
20
21 #define ALLOCATE_SHARED_MEMORY(context, sharedMemory, sharedMemorySize, \
22 memoryType, exit_label) \
23 res = AllocateSharedMemory(context, sharedMemory, sharedMemorySize, \
24 memoryType); \
25 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res)) \
26 goto exit_label; \
27 memset(sharedMemory->buffer, 0, sharedMemorySize);
28
29 #define ALLOCATE_AND_FILL_SHARED_MEMORY(context, sharedMemory, \
30 sharedMemorySize, \
31 memoryType, copySize, data, \
32 exit_label) \
33 res = AllocateSharedMemory(context, sharedMemory, sharedMemorySize, \
34 memoryType); \
35 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res)) \
36 goto exit_label; \
37 memset(sharedMemory->buffer, 0, sharedMemorySize); \
38 if (data != NULL) { \
39 memcpy(sharedMemory->buffer, data, copySize); \
40 }
41 #define ALLOCATE_AND_FILL_SHARED_MEMORY_6(a,b,c,d,e,f) \
42 ALLOCATE_AND_FILL_SHARED_MEMORY(a,b,c,d,c,e,f)
43
44 #define SET_SHARED_MEMORY_OPERATION_PARAMETER(parameterNumber, \
45 sharedMemoryOffset, \
46 sharedMemory, \
47 sharedMemorySize) \
48 op.params[parameterNumber].memref.offset = sharedMemoryOffset; \
49 op.params[parameterNumber].memref.size = sharedMemorySize; \
50 op.params[parameterNumber].memref.parent = sharedMemory;
51
52 /*Open session using TEEC_OpenSession and
53 check the returned value and/or returned origin.*/
54 #define XML_OpenSession(c, context, session, destination, connectionMethod, \
55 connectionData, operation, returnOrigin, expected) \
56 do { \
57 uint32_t ret_orig = 0; \
58 \
59 XML_VERIFY(c, expected, \
60 TEEC_OpenSession(context, session, destination, \
61 connectionMethod, connectionData, \
62 operation, &ret_orig)); \
63 if (!(unsigned long)(returnOrigin) || \
64 (unsigned long)(returnOrigin) == \
65 TEEC_ORIGIN_ANY_NOT_TRUSTED_APP) \
66 ADBG_EXPECT_NOT(c, (unsigned long)returnOrigin, \
67 ret_orig); \
68 else \
69 ADBG_EXPECT(c, (unsigned long)returnOrigin, ret_orig); \
70 } while (0)
71
72 /* XML_VERIFY macro define.
73 *
74 * Use ADBG_EXPECT or ADBG_EXPECT_NOT depending on the expected return value.
75 *
76 * ADBG_EXPECT() -> IF(EXP == GOT) RETURN TRUE
77 * ADBG_EXPECT() -> IF(EXP != GOT) RETURN TRUE
78 */
79 #define XML_VERIFY(c, exp, got) \
80 do { \
81 if (exp == TEEC_UNDEFINED_ERROR) \
82 ADBG_EXPECT_NOT(c, exp, got); \
83 else \
84 ADBG_EXPECT(c, exp, got); \
85 } while (0)
86
87 /*Initialize context using TEEC_InitializeContext and
88 check the returned value.*/
89 #define XML_InitializeContext(c, name, context, expected) \
90 XML_VERIFY(c, expected, TEEC_InitializeContext(name, context))
91
92 #define OPERATION_TEEC_PARAM_TYPES(op, p0, p1, p2, p3) \
93 do { \
94 op->paramTypes = TEEC_PARAM_TYPES(p0, p1, p2, p3); \
95 } while (0)
96
97 /*dummy functions*/
98 #define TEEC_SetUp_TEE() /*do nothing for now*/
99 #define TEEC_TearDown_TEE(a) /*do nothing for now*/
100 #define TEEC_SelectApp(a, b) /*do nothing for now*/
101 #define TEEC_createThread(a, b) /*do nothing for now*/
102
103 struct attr_value {
104 uint8_t buf[1024];
105 size_t buf_size;
106 uint32_t attr_id;
107 };
108
109 #define MAX_NUM_SAVED_ATTR_VALUES 8
110 static struct attr_value saved_attr[MAX_NUM_SAVED_ATTR_VALUES] __maybe_unused;
111
112
113 static TEEC_Result __maybe_unused
Invoke_Simple_Function(ADBG_Case_t * c __unused,TEEC_Session * sess,uint32_t cmdId)114 Invoke_Simple_Function(ADBG_Case_t *c __unused, TEEC_Session *sess,
115 uint32_t cmdId)
116 {
117 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
118 uint32_t org;
119
120 return TEEC_InvokeCommand(sess, cmdId, &op, &org);
121 }
122
123 static TEEC_Result __maybe_unused
Invoke_Simple_Function_v1(ADBG_Case_t * c __unused,TEEC_Session * sess,uint32_t cmd,uint32_t a,uint32_t b)124 Invoke_Simple_Function_v1(ADBG_Case_t *c __unused, TEEC_Session *sess,
125 uint32_t cmd, uint32_t a, uint32_t b)
126 {
127 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
128 uint32_t org;
129
130 op.params[0].value.a = a;
131 op.params[0].value.b = b;
132
133 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
134 TEEC_NONE, TEEC_NONE);
135
136 return TEEC_InvokeCommand(sess, cmd, &op, &org);
137 }
138
139 static TEEC_Result __maybe_unused
Invoke_Simple_Function_v2(ADBG_Case_t * c __unused,TEEC_Session * sess,uint32_t cmd,uint32_t a0,uint32_t b0,uint32_t a1,uint32_t b1)140 Invoke_Simple_Function_v2(ADBG_Case_t *c __unused, TEEC_Session *sess,
141 uint32_t cmd, uint32_t a0, uint32_t b0,
142 uint32_t a1, uint32_t b1)
143 {
144 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
145 uint32_t org;
146
147 op.params[0].value.a = a0;
148 op.params[0].value.b = b0;
149 op.params[1].value.a = a1;
150 op.params[1].value.b = b1;
151
152 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
153 TEEC_NONE, TEEC_NONE);
154
155 return TEEC_InvokeCommand(sess, cmd, &op, &org);
156 }
157
158 static TEEC_Result __maybe_unused
Invoke_Simple_Function_v3(ADBG_Case_t * c __unused,TEEC_Session * sess,uint32_t cmd,uint32_t a0,uint32_t b0,uint32_t a1,uint32_t b1,uint32_t a2,uint32_t b2)159 Invoke_Simple_Function_v3(ADBG_Case_t *c __unused, TEEC_Session *sess,
160 uint32_t cmd, uint32_t a0, uint32_t b0, uint32_t a1,
161 uint32_t b1, uint32_t a2, uint32_t b2)
162 {
163 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
164 uint32_t org;
165
166 op.params[0].value.a = a0;
167 op.params[0].value.b = b0;
168 op.params[1].value.a = a1;
169 op.params[1].value.b = b1;
170 op.params[2].value.a = a2;
171 op.params[2].value.b = b2;
172
173 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
174 TEEC_VALUE_INPUT, TEEC_NONE);
175
176 return TEEC_InvokeCommand(sess, cmd, &op, &org);
177 }
178
179 static TEEC_Result __maybe_unused
Invoke_Simple_Function_v4(ADBG_Case_t * c __unused,TEEC_Session * sess,uint32_t cmd,uint32_t a0,uint32_t b0,uint32_t a1,uint32_t b1,uint32_t a2,uint32_t b2,uint32_t a3,uint32_t b3)180 Invoke_Simple_Function_v4(ADBG_Case_t *c __unused, TEEC_Session *sess,
181 uint32_t cmd, uint32_t a0, uint32_t b0, uint32_t a1,
182 uint32_t b1, uint32_t a2, uint32_t b2, uint32_t a3,
183 uint32_t b3)
184 {
185 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
186 uint32_t org;
187
188 op.params[0].value.a = a0;
189 op.params[0].value.b = b0;
190 op.params[1].value.a = a1;
191 op.params[1].value.b = b1;
192 op.params[2].value.a = a2;
193 op.params[2].value.b = b2;
194 op.params[3].value.a = a3;
195 op.params[3].value.b = b3;
196
197 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
198 TEEC_VALUE_INPUT, TEEC_VALUE_INPUT);
199
200 return TEEC_InvokeCommand(sess, cmd, &op, &org);
201 }
202
AllocateSharedMemory(TEEC_Context * ctx,TEEC_SharedMemory * shm,uint32_t size,uint32_t flags)203 static TEEC_Result __maybe_unused AllocateSharedMemory(TEEC_Context *ctx,
204 TEEC_SharedMemory *shm,
205 uint32_t size,
206 uint32_t flags)
207 {
208 shm->flags = flags;
209 shm->size = size;
210 return TEEC_AllocateSharedMemory(ctx, shm);
211 }
212
GetObjectBufferAttribute_helper(ADBG_Case_t * c,TEEC_Session * sess,size_t n,uint32_t cmd,uint32_t obj,uint32_t attr_id,bool buffer_is_null,uint32_t buffer_size)213 static TEEC_Result GetObjectBufferAttribute_helper(ADBG_Case_t *c,
214 TEEC_Session *sess,
215 size_t n,
216 uint32_t cmd, uint32_t obj,
217 uint32_t attr_id,
218 bool buffer_is_null,
219 uint32_t buffer_size)
220 {
221 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
222 TEEC_Result res = TEE_SUCCESS;
223 uint32_t org = 0;
224 static TEEC_SharedMemory shm = { };
225 uint32_t memref_type = TEEC_MEMREF_TEMP_OUTPUT;
226
227 if (!ADBG_EXPECT_COMPARE_SIGNED(c, n, <, MAX_NUM_SAVED_ATTR_VALUES))
228 return TEEC_ERROR_BAD_PARAMETERS;
229 if (!ADBG_EXPECT_COMPARE_SIGNED(c, buffer_size, <=,
230 sizeof(saved_attr[n].buf)))
231 return TEEC_ERROR_BAD_PARAMETERS;
232
233 if (!buffer_is_null) {
234 shm.size = buffer_size;
235 shm.flags = TEEC_MEM_OUTPUT;
236 res = TEEC_AllocateSharedMemory(sess->ctx, &shm);
237 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
238 return res;
239 SET_SHARED_MEMORY_OPERATION_PARAMETER(1, 0, &shm, shm.size);
240 memref_type = TEEC_MEMREF_PARTIAL_OUTPUT;
241 }
242
243 op.params[0].value.a = obj;
244 op.params[0].value.b = attr_id;
245
246 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, memref_type,
247 TEEC_NONE, TEEC_NONE);
248
249 res = TEEC_InvokeCommand(sess, cmd, &op, &org);
250
251 if (!buffer_is_null) {
252 if (res) {
253 memset(saved_attr + n, 0, sizeof(saved_attr[n]));
254 } else {
255 memcpy(saved_attr[n].buf, shm.buffer,
256 sizeof(saved_attr[n].buf));
257 saved_attr[n].buf_size = op.params[1].memref.size;
258 saved_attr[n].attr_id = attr_id;
259 }
260 TEEC_ReleaseSharedMemory(&shm);
261 }
262
263 return res;
264 }
265
266 static TEEC_Result __maybe_unused
Invoke_GetObjectBufferAttribute(ADBG_Case_t * c,TEEC_Session * sess,uint32_t cmd,uint32_t obj,uint32_t attr_id,bool buffer_is_null,uint32_t buffer_size)267 Invoke_GetObjectBufferAttribute(ADBG_Case_t *c, TEEC_Session *sess,
268 uint32_t cmd, uint32_t obj, uint32_t attr_id,
269 bool buffer_is_null, uint32_t buffer_size)
270 {
271 return GetObjectBufferAttribute_helper(c, sess, 0, cmd, obj, attr_id,
272 buffer_is_null, buffer_size);
273 }
274
275 static TEEC_Result __maybe_unused
Invoke_FreeTransientObject(ADBG_Case_t * c,TEEC_Session * sess,uint32_t cmd,uint32_t obj_handle)276 Invoke_FreeTransientObject(ADBG_Case_t *c, TEEC_Session *sess, uint32_t cmd,
277 uint32_t obj_handle)
278 {
279 return Invoke_Simple_Function_v1(c, sess, cmd, obj_handle, 0);
280 }
281 #endif /* XML_COMMON_API_H_ */
282