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