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_CLIENT_API_H_
8 #define XML_CLIENT_API_H_
9 
10 #include <assert.h>
11 #include <pthread.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/types.h>
16 #include <tee_api_defines.h>
17 #include <tee_client_api.h>
18 #include <unistd.h>
19 
20 #include <xml_common_api.h>
21 #include "xtest_helpers.h"
22 #include "xtest_test.h"
23 
24 /* ta_testingClientAPI_test.h*/
25 #define COMMAND_TTA_Remember_Expected_ParamTypes 0x00000002
26 #define COMMAND_TTA_Copy_ParamIn_to_ParamOut	0x00000001
27 #define COMMAND_TTA_Check_ParamTypes		0x00000003
28 #define COMMAND_TTA_To_Be_Cancelled		0x00000004
29 #define COMMAND_TTA_Success			0x00000005
30 #define COMMAND_TTA_Panic			0x00000006
31 
32 /* ta_answerSuccessTo_OpenSession_Invoke_test.h */
33 #define COMMAND_TTA_Remember_Expected_ParamTypes 0x00000002
34 #define COMMAND_TTA_Copy_ParamIn_to_ParamOut	0x00000001
35 #define COMMAND_TTA_Check_ParamTypes		0x00000003
36 
37 /* ta_testingClientAPI_test.h */
38 #define COMMAND_TTA_Remember_Expected_ParamTypes 0x00000002
39 #define COMMAND_TTA_Copy_ParamIn_to_ParamOut	0x00000001
40 #define COMMAND_TTA_Check_ParamTypes		0x00000003
41 #define COMMAND_TTA_To_Be_Cancelled		0x00000004
42 #define COMMAND_TTA_Success			0x00000005
43 #define COMMAND_TTA_Panic			0x00000006
44 
45 #define INVALID_CONNECTION_METHODS			0x0A
46 #define COMMAND_TTA_Check_Expected_ParamTypes	COMMAND_TTA_Check_ParamTypes
47 #define COMMAND_TTA_Check_Update_Params		0xFFFF0002u
48 #define COMMAND_TTA_Store_Expected_Param_Info	0xFFFF0001u
49 
50 #define CLIENT_APP01	NULL
51 
52 #define TEEC_UNDEFINED_ERROR 0xDEADDEAD
53 
54 #define TEEC_ORIGIN_ANY_NOT_TRUSTED_APP  0x00000005
55 
56 #define OFFSET0 0
57 #define OFFSET_02 0x64
58 
59 #define BIG_SIZE			1024
60 #define IGNORE				0xFEFEFEFE
61 #define VALUE01				0x01234567
62 #define VALUE02				0xFEDCBA98
63 #define SIZE_OVER_MEMORY		0xFFFFFFFE
64 #define SIZE_VALUE01			4
65 #define SIZE_LESSER_THAN_SIZE_02	0x1B58
66 #define SIZE_GREATER_THAN_SIZE_02	0x2328
67 #define ZERO				0
68 #define SIZE_02				0x2000
69 #define ALLOC_SIZE_02			0x2800
70 #define BYTE_01				1
71 #define BYTE_02				2
72 #define BYTE_03				3
73 #define BYTE_04				4
74 
75 #define VALUE_A_IN_0			0x01234567
76 #define VALUE_A_IN_1			0xF9E8D7C6
77 #define VALUE_A_IN_2			0xE01C083D
78 #define VALUE_A_IN_3			0xDCA65016
79 #define VALUE_A_OUT_0			0xABCD0248
80 #define VALUE_A_OUT_1			0x03579EF4
81 #define VALUE_A_OUT_2			0x344C64BC
82 #define VALUE_A_OUT_3			0x3590BBD9
83 #define VALUE_B_IN_0			0x89ABCDEF
84 #define VALUE_B_IN_1			0x1248DCBA
85 #define VALUE_B_IN_2			0x5E816B61
86 #define VALUE_B_IN_3			0x4C899A96
87 #define VALUE_B_OUT_0			0x1A2B3C4D
88 #define VALUE_B_OUT_1			0x1439F7A2
89 #define VALUE_B_OUT_2			0x6EC61CAE
90 #define VALUE_B_OUT_3			0xB2639F77
91 
92 #define TEEC_MEM_INOUT			(TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)
93 
94 static TEEC_SharedMemory share_mem[4];
95 static TEEC_SharedMemory *SHARE_MEM01 = share_mem;
96 static TEEC_SharedMemory *SHARE_MEM02 = share_mem + 1;
97 static TEEC_SharedMemory *SHARE_MEM03 = share_mem + 2;
98 static TEEC_SharedMemory *SHARE_MEM04 = share_mem + 3;
99 static TEEC_SharedMemory *SHARE_MEM_NULL_BUFFER;
100 static TEEC_Session session[2];
101 static TEEC_Session *SESSION01 = session;
102 static TEEC_Session *SESSION02 = session + 1;
103 static TEEC_Context context[2];
104 static TEEC_Context *CONTEXT01 = context;
105 static TEEC_Context *CONTEXT02 = context + 1;
106 static TEEC_Operation operation[1];
107 static TEEC_Operation *OPERATION01 = operation;
108 
109 /* "ItIsNotTotosTEEs" */
110 static const char *INVALID_NOT_EXISTING_TEE = "ItIsNotTotosTEEs\0";
111 
112 /** ALL_TEMPORARY_MEMORIES */
113 static uint8_t *TEMP_MEM01;
114 static uint8_t *TEMP_MEM02;
115 static uint8_t *TEMP_MEM03;
116 static uint8_t *TEMP_MEM04;
117 static uint8_t *TEMP_MEM_NULL_BUFFER;
118 
119 static TEEC_UUID UUID_TTA_answerErrorTo_OpenSession = {
120 	0x534D4152, 0x5443, 0x534C,
121 	{ 0x54, 0x45, 0x52, 0x52, 0x54, 0x4F, 0x4F, 0x53 }
122 };
123 static TEEC_UUID UUID_TTA_answerSuccessTo_OpenSession_Invoke = {
124 	0x534D4152, 0x542D, 0x4353,
125 	{ 0x4C, 0x54, 0x2D, 0x54, 0x41, 0x2D, 0x53, 0x55 }
126 };
127 static TEEC_UUID UUID_Unknown = {
128 	0x534D4152, 0x542D, 0x4355,
129 	{ 0x4E, 0x4B, 0x2D, 0x4E, 0x4F, 0x2D, 0x57, 0x4E }
130 };
131 static TEEC_UUID UUID_TTA_testingClientAPI_Parameters_OpenSession = {
132 	0x534D4152, 0x5443, 0x534C,
133 	{ 0x54, 0x43, 0x4C, 0x49, 0x50, 0x4F, 0x50, 0x53 }
134 };
135 static TEEC_UUID UUID_TTA_testingClientAPI = {
136 	0x534D4152, 0x542D, 0x4353,
137 	{ 0x4C, 0x54, 0x2D, 0x54, 0x41, 0x2D, 0x53, 0x54 }
138 };
139 static TEEC_UUID UUID_TTA_answerErrorTo_Invoke = {
140 	0x534D4152, 0x542D, 0x4353,
141 	{ 0x4C, 0x54, 0x2D, 0x54, 0x41, 0x2D, 0x45, 0x52 }
142 };
143 /* TTA_testingClientAPI_Parameters_Invoke */
144 static TEEC_UUID UUID_TTA_testingClientAPI_Parameters = {
145 	0x534D4152, 0x5443, 0x534C,
146 	{ 0x54, 0x43, 0x4C, 0x49, 0x50, 0x41, 0x52, 0x41 }
147 };
148 
149 /*Registers the TEEC_SharedMemory to the TEE*/
RegisterSharedMemory(TEEC_Context * ctx,TEEC_SharedMemory * shm,uint32_t size,uint32_t flags)150 static TEEC_Result RegisterSharedMemory(TEEC_Context *ctx,
151 					TEEC_SharedMemory *shm,
152 					uint32_t size, uint32_t flags)
153 {
154 	shm->flags = flags;
155 	shm->size = size;
156 	shm->buffer = malloc(size);
157 	return TEEC_RegisterSharedMemory(ctx, shm);
158 }
159 
160 /*Allocates temporary memory area*/
161 #define AllocateTempMemory(temp_mem, size) \
162 	temp_mem = malloc(size)
163 
164 /*Releases temporary memory area*/
165 #define ReleaseTempMemory(temp_mem) \
166 	do { \
167 		if (temp_mem != NULL) { \
168 			free(temp_mem); \
169 			temp_mem = NULL; \
170 		} \
171 	} while (0)
172 
173 
174 /* Assigns a and b to the value parameter */
TEEC_prepare_OperationEachParameter_value(TEEC_Operation * op,size_t n,uint32_t a,uint32_t b)175 static inline void TEEC_prepare_OperationEachParameter_value(TEEC_Operation *op,
176 							     size_t n,
177 							     uint32_t a,
178 							     uint32_t b)
179 {
180 	if (IGNORE != a)
181 		op->params[n].value.a = a;
182 
183 	if (IGNORE != b)
184 		op->params[n].value.b = b;
185 
186 }
187 
188 /*Define TEEC_SharedMemory memory content.*/
189 #define TEEC_defineMemoryContent_sharedMemory(sh_mem, val, size_val) \
190 	memcpy(sh_mem->buffer, &val, size_val)
191 
192 /*Define temp memory content.*/
193 #define TEEC_defineMemoryContent_tmpMemory(buf, val, size_val) \
194 	memcpy(buf, &(val), size_val)
195 
196 #define INVOKE_REMEMBER_EXP_PARAM_TYPES(session, cmd, p0, p1, p2, p3, exp) \
197 	do { \
198 		uint32_t ret_orig = 0; \
199  \
200 		memset(OPERATION01, 0x00, sizeof(TEEC_Operation)); \
201 		OPERATION01->paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, \
202 							   TEEC_NONE, \
203 							   TEEC_NONE, \
204 							   TEEC_NONE); \
205 		OPERATION01->params[0].value.a = \
206 			TEEC_PARAM_TYPES((p0), (p1), (p2), (p3)); \
207 		ADBG_EXPECT(c, exp, \
208 			    TEEC_InvokeCommand(session, cmd, OPERATION01, \
209 					       &ret_orig));  \
210 		ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP, \
211 					      ret_orig); \
212 	} while (0)
213 
store_param_info(TEEC_Operation * op,uint32_t param_num,uint32_t pt,uint32_t size_in,uint32_t value_in,uint32_t size_out,uint32_t value_out)214 static void store_param_info(TEEC_Operation *op, uint32_t param_num,
215 			     uint32_t pt, uint32_t size_in, uint32_t value_in,
216 			     uint32_t size_out, uint32_t value_out)
217 {
218 	memset(op, 0, sizeof(*op));
219 	op->params[0].value.a = param_num;
220 	op->params[0].value.b = pt;
221 	switch (pt) {
222 	case TEE_PARAM_TYPE_MEMREF_INPUT:
223 	case TEE_PARAM_TYPE_MEMREF_OUTPUT:
224 	case TEE_PARAM_TYPE_MEMREF_INOUT:
225 		op->paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
226 						  TEEC_VALUE_INPUT,
227 						  TEEC_VALUE_INPUT,
228 						  TEEC_NONE);
229 		if (size_in != IGNORE)
230 			op->params[1].value.a = size_in;
231 		if (value_in != IGNORE)
232 			op->params[1].value.b = value_in;
233 		if (size_out != IGNORE)
234 			op->params[2].value.a = size_out;
235 		if (value_out != IGNORE)
236 			op->params[2].value.b = value_out;
237 		break;
238 	default:
239 		op->paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
240 						  TEEC_NONE, TEEC_NONE);
241 		break;
242 	}
243 }
244 
245 #define INVOKE_STORE_EXP_PARAM_INFO(session, cmd, paramNumber, paramType, \
246 				    sizeIN, valueIN, sizeOUT, valueOUT, \
247 				    expReturnOrigin, expTEEC_Result) \
248 	do { \
249 		uint32_t ret_orig = 0; \
250  \
251 		store_param_info(OPERATION01, paramNumber, paramType, sizeIN, \
252 				 valueIN, sizeOUT, valueOUT); \
253 		ADBG_EXPECT(c, expTEEC_Result, \
254 			    TEEC_InvokeCommand(session, cmd, OPERATION01, \
255 					       &ret_orig));  \
256 		ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, expReturnOrigin, ret_orig); \
257 	} while (0)
258 
init_mem(uint8_t * buf,size_t buf_size,size_t begin_size,size_t middle_size,uint8_t begin_value,uint8_t middle_value,uint8_t end_value)259 static void init_mem(uint8_t *buf, size_t buf_size, size_t begin_size,
260 		     size_t middle_size, uint8_t begin_value,
261 		     uint8_t middle_value, uint8_t end_value)
262 {
263 	memset(buf, begin_value, begin_size);
264 	memset(buf + begin_size, middle_value, middle_size);
265 	memset(buf + begin_size + middle_size, end_value,
266 	       buf_size - begin_size - middle_size);
267 }
268 
269 #define TEEC_initialize_memory(shm, tmpMem, offset, _size, value_beginning, \
270 			       value_middle, value_end) \
271 	do { \
272 		if ((unsigned long)shm != IGNORE) {\
273 			TEEC_SharedMemory *__shm = (void *)(long)shm; \
274 			init_mem(__shm->buffer, __shm->size, offset, _size, \
275 				 value_beginning, value_middle, value_end); \
276 			assert(tempMem == IGNORE); \
277 		} else if ((unsigned long)tmpMem != IGNORE) {\
278 			/* \
279 			 * We can't tell the size of tmpMem, so we assume \
280 			 * it's offset + size large. \
281 			 */ \
282 			init_mem((void *)(long)tmpMem, offset + _size, offset, \
283 				 _size, value_beginning, value_middle, \
284 				 value_end); \
285 		} else { \
286 			assert(0); \
287 		} \
288 	} while (0)
289 
TEEC_prepare_OperationEachParameter_memref(TEEC_Operation * op,size_t param_num,TEEC_SharedMemory * shm,size_t offs,size_t sz)290 static void TEEC_prepare_OperationEachParameter_memref(TEEC_Operation *op,
291 						      size_t param_num,
292 						      TEEC_SharedMemory *shm,
293 						      size_t offs, size_t sz)
294 {
295 	op->params[param_num] = (TEEC_Parameter){
296 		.memref = {
297 			.parent = shm, .size = sz, .offset = offs,
298 		}
299 	};
300 }
301 
TEEC_prepare_OperationEachParameter_tmpref(TEEC_Operation * op,size_t param_num,void * buf,size_t sz)302 static void TEEC_prepare_OperationEachParameter_tmpref(TEEC_Operation *op,
303 						      size_t param_num,
304 						      void *buf, size_t sz)
305 {
306 	op->params[param_num] = (TEEC_Parameter){
307 		.tmpref = {
308 			.buffer = buf, .size = sz,
309 		}
310 	};
311 }
312 
313 /*Compares two memories and checks if their length and content is the same */
314 #define TEEC_checkMemoryContent_sharedMemory(op, param_num, shrm, exp_buf, \
315 					     exp_blen) \
316 	do { \
317 		if ((exp_buf) == IGNORE) { \
318 			ADBG_EXPECT((c), exp_blen, \
319 				    (op)->params[(param_num)].memref.size); \
320 		} else { \
321 			ADBG_EXPECT_COMPARE_POINTER((c), (shrm), ==, \
322 						    (op)->params[(param_num)].\
323 							memref.parent); \
324 			ADBG_EXPECT_BUFFER((c), &(exp_buf), (exp_blen), \
325 					   (shrm)->buffer, \
326 					   (op)->params[(param_num)].\
327 						memref.size); \
328 		} \
329 	} while (0)
330 
331 /*
332  * Compares the content of the memory cells in OP with the expected value
333  * contained.
334  */
335 #define TEEC_checkMemoryContent_tmpMemory(op, param_num, \
336 	buf, exp_buf, exp_blen) \
337 	do { \
338 		if ((exp_buf) == 0) { \
339 			ADBG_EXPECT((c), exp_blen, \
340 				    (op)->params[(param_num)].tmpref.size); \
341 		} else { \
342 			ADBG_EXPECT_COMPARE_POINTER((c), (buf), ==, \
343 						    (op)->params[(param_num)].\
344 							tmpref.buffer); \
345 			ADBG_EXPECT_BUFFER((c), &(exp_buf), (exp_blen), \
346 					   (buf), \
347 					   (op)->params[(param_num)].\
348 						memref.size); \
349 		} \
350 	} while (0)
351 
352 /*
353  * Compares the content of the memory cells in OP with the expected value
354  * contained.
355  */
356 #define TEEC_checkContent_Parameter_value(op, param_num, exp_a, exp_b) \
357 	do { \
358 		if (IGNORE != exp_a) \
359 			ADBG_EXPECT((c), exp_a, \
360 				    (op)->params[(param_num)].value.a); \
361 		if (IGNORE != exp_b) \
362 			ADBG_EXPECT((c), exp_b, \
363 				    (op)->params[(param_num)].value.b); \
364 	} while (0)
365 
366 /*Invoke command using TEEC_InvokeCommand and check the returned value.*/
367 #define XML_InvokeCommand(c, session, cmd, operation, returnOrigin, expected) \
368 	do { \
369 		uint32_t ret_orig = 0; \
370  \
371 		ADBG_EXPECT(c, expected, \
372 			    TEEC_InvokeCommand(session, cmd, operation, \
373 					       &ret_orig)); \
374 		if (returnOrigin) \
375 			ADBG_EXPECT(c, (unsigned long)returnOrigin, ret_orig); \
376 	} while (0)
377 
378 #endif /* XML_CLIENT_API_H_ */
379