1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11 
12 #include "xtest_test.h"
13 #include "xtest_helpers.h"
14 #include "tee_api_defines.h"
15 #include "tee_client_api.h"
16 
17 #define OFFSET0 0
18 
19 #define PARAM_0 0
20 #define PARAM_1 1
21 #define PARAM_2 2
22 #define PARAM_3 3
23 
24 struct xtest_session {
25 	ADBG_Case_t *c;
26 	TEEC_Session session;
27 	TEEC_Context context;
28 };
29 
30 /* Compares two memories and checks if their length and content is the same */
31 #define EXPECT_SHARED_MEM_BUFFER(c, exp_buf, exp_blen, op, param_num, shrm) \
32 	do { \
33 		if ((exp_buf) == NULL) { \
34 			ADBG_EXPECT((c), exp_blen, \
35 				    (op)->params[(param_num)].memref.size); \
36 		} else { \
37 			ADBG_EXPECT_COMPARE_POINTER((c), (shrm), ==, \
38 			    (op)->params[(param_num)].memref.parent); \
39 			ADBG_EXPECT_BUFFER((c), (exp_buf), (exp_blen), \
40 			   (shrm)->buffer, \
41 			   (op)->params[(param_num)].memref.size); \
42 		} \
43 	} while (0)
44 
45 /*
46  * Compares the content of the memory cells in OP with the expected value
47  * contained.
48  */
49 #define EXPECT_OP_TMP_MEM_BUFFER(c, exp_buf, exp_blen, op, param_num, buf) \
50 	do { \
51 		if ((exp_buf) == NULL) { \
52 			ADBG_EXPECT((c), exp_blen, \
53 			    (op)->params[(param_num)].tmpref.size); \
54 		} else { \
55 			ADBG_EXPECT_COMPARE_POINTER((c), (buf), ==, \
56 			    (op)->params[(param_num)].tmpref.buffer); \
57 			ADBG_EXPECT_BUFFER((c), (exp_buf), (exp_blen), \
58 			   (buf), \
59 			   (op)->params[(param_num)].memref.size); \
60 		} \
61 	} while (0)
62 
63 /* Registers the TEEC_SharedMemory to the TEE. */
RegisterSharedMemory(TEEC_Context * ctx,TEEC_SharedMemory * shm,size_t size,uint32_t flags)64 static TEEC_Result RegisterSharedMemory(TEEC_Context *ctx,
65 					TEEC_SharedMemory *shm, size_t size,
66 					uint32_t flags)
67 {
68 	shm->flags = flags;
69 	shm->size = size;
70 	return TEEC_RegisterSharedMemory(ctx, shm);
71 }
72 
73 /* Allocates shared memory inside of the TEE. */
AllocateSharedMemory(TEEC_Context * ctx,TEEC_SharedMemory * shm,size_t size,uint32_t flags)74 static TEEC_Result AllocateSharedMemory(TEEC_Context *ctx,
75 					TEEC_SharedMemory *shm, size_t size,
76 					uint32_t flags)
77 {
78 	shm->flags = flags;
79 	shm->size = size;
80 	return TEEC_AllocateSharedMemory(ctx, shm);
81 }
82 
CloseSession_null(struct xtest_session * cs)83 static void CloseSession_null(struct xtest_session *cs)
84 {
85 	Do_ADBG_BeginSubCase(cs->c, "CloseSession_null");
86 	{
87 		/* In reality doesn't test anything. */
88 		TEEC_CloseSession(NULL);
89 	}
90 	Do_ADBG_EndSubCase(cs->c, "CloseSession_null");
91 }
92 
Allocate_In(struct xtest_session * cs)93 static void Allocate_In(struct xtest_session *cs)
94 {
95 	Do_ADBG_BeginSubCase(cs->c, "Allocate_In");
96 	{
97 		TEEC_SharedMemory shm = { };
98 		size_t size = 1024;
99 
100 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
101 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
102 			goto out;
103 
104 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
105 			AllocateSharedMemory(&cs->context, &shm, size,
106 					     TEEC_MEM_INPUT)))
107 			goto out_final;
108 
109 		TEEC_ReleaseSharedMemory(&shm);
110 out_final:
111 		TEEC_FinalizeContext(&cs->context);
112 	}
113 out:
114 	Do_ADBG_EndSubCase(cs->c, "Allocate_In");
115 }
116 
Allocate_out_of_memory(struct xtest_session * cs)117 static void Allocate_out_of_memory(struct xtest_session *cs)
118 {
119 	Do_ADBG_BeginSubCase(cs->c, "Allocate_out_of_memory");
120 	{
121 		TEEC_SharedMemory shm = { };
122 		size_t SIZE_OVER_MEMORY_CAPACITY = SIZE_MAX;
123 
124 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
125 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
126 			goto out;
127 
128 		ADBG_EXPECT_TEEC_RESULT(cs->c, TEEC_ERROR_OUT_OF_MEMORY,
129 			AllocateSharedMemory(&cs->context, &shm,
130 					     SIZE_OVER_MEMORY_CAPACITY,
131 					     TEEC_MEM_INPUT));
132 		TEEC_FinalizeContext(&cs->context);
133 	}
134 out:
135 	Do_ADBG_EndSubCase(cs->c, "Allocate_out_of_memory");
136 }
137 
OpenSession_error_notExistingTA(struct xtest_session * cs)138 static void OpenSession_error_notExistingTA(struct xtest_session *cs)
139 {
140 	Do_ADBG_BeginSubCase(cs->c, "OpenSession_error_notExistingTA");
141 	{
142 		TEEC_UUID NONEXISTING_TA_UUID = { 0x534D1192, 0x6143, 0x234C,
143 						  { 0x47, 0x55, 0x53, 0x52,
144 						    0x54, 0x4F, 0x4F, 0x59 } };
145 		uint32_t ret_orig = 0;
146 
147 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
148 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
149 			goto out;
150 
151 		ADBG_EXPECT_COMPARE_UNSIGNED(cs->c, TEEC_SUCCESS, !=,
152 			TEEC_OpenSession(&cs->context, &cs->session,
153 					 &NONEXISTING_TA_UUID,
154 					 TEEC_LOGIN_PUBLIC, NULL, NULL,
155 					 &ret_orig));
156 		ADBG_EXPECT_COMPARE_UNSIGNED(cs->c, TEEC_ORIGIN_TRUSTED_APP, !=,
157 					     ret_orig);
158 		TEEC_FinalizeContext(&cs->context);
159 	}
160 out:
161 	Do_ADBG_EndSubCase(cs->c, "OpenSession_error_notExistingTA");
162 }
163 
Allocate_InOut(struct xtest_session * cs)164 static void Allocate_InOut(struct xtest_session *cs)
165 {
166 	Do_ADBG_BeginSubCase(cs->c, "Allocate_InOut");
167 	{
168 		TEEC_SharedMemory shm = { };
169 		uint8_t val[] = { 54, 76, 98, 32 };
170 
171 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
172 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
173 			goto out;
174 
175 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
176 			AllocateSharedMemory(&cs->context, &shm, sizeof(val),
177 					     TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)))
178 			goto out_final;
179 
180 		TEEC_ReleaseSharedMemory(&shm);
181 out_final:
182 		TEEC_FinalizeContext(&cs->context);
183 	}
184 out:
185 	Do_ADBG_EndSubCase(cs->c, "Allocate_InOut");
186 }
187 
Register_In(struct xtest_session * cs)188 static void Register_In(struct xtest_session *cs)
189 {
190 	Do_ADBG_BeginSubCase(cs->c, "Register_In");
191 	{
192 		TEEC_SharedMemory shm = { };
193 		uint8_t val[] = { 32, 65, 43, 21, 98 };
194 
195 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
196 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
197 			goto out;
198 
199 		shm.buffer = val;
200 
201 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
202 			RegisterSharedMemory(&cs->context, &shm, sizeof(val),
203 					     TEEC_MEM_INPUT)))
204 			goto out_final;
205 
206 		TEEC_ReleaseSharedMemory(&shm);
207 out_final:
208 		TEEC_FinalizeContext(&cs->context);
209 	}
210 out:
211 	Do_ADBG_EndSubCase(cs->c, "Register_In");
212 }
213 
Register_notZeroLength_Out(struct xtest_session * cs)214 static void Register_notZeroLength_Out(struct xtest_session *cs)
215 {
216 	Do_ADBG_BeginSubCase(cs->c, "Register_notZeroLength_Out");
217 	{
218 		TEEC_SharedMemory shm = { };
219 		uint8_t val[] = { 56, 67, 78, 99 };
220 
221 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
222 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
223 			goto out;
224 
225 		shm.buffer = val;
226 
227 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
228 			RegisterSharedMemory(&cs->context, &shm, sizeof(val),
229 					     TEEC_MEM_OUTPUT)))
230 			goto out_final;
231 
232 		TEEC_ReleaseSharedMemory(&shm);
233 out_final:
234 		TEEC_FinalizeContext(&cs->context);
235 	}
236 out:
237 	Do_ADBG_EndSubCase(cs->c, "Register_notZeroLength_Out");
238 }
239 
Register_InOut(struct xtest_session * cs)240 static void Register_InOut(struct xtest_session *cs)
241 {
242 	Do_ADBG_BeginSubCase(cs->c, "Register_InOut");
243 	{
244 		TEEC_SharedMemory shm = { };
245 		uint8_t val[] = { 54, 76, 23, 98, 255, 23, 86 };
246 
247 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
248 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
249 			goto out;
250 
251 		shm.buffer = val;
252 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
253 			RegisterSharedMemory(&cs->context, &shm, sizeof(val),
254 					     TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)))
255 			goto out_final;
256 
257 		TEEC_ReleaseSharedMemory(&shm);
258 out_final:
259 		TEEC_FinalizeContext(&cs->context);
260 	}
261 out:
262 	Do_ADBG_EndSubCase(cs->c, "Register_InOut");
263 }
264 
Register_zeroLength_Out(struct xtest_session * cs)265 static void Register_zeroLength_Out(struct xtest_session *cs)
266 {
267 	Do_ADBG_BeginSubCase(cs->c, "Register_zeroLength_Out");
268 	{
269 		uint8_t val[] = { 65, 76, 98, 32 };
270 		TEEC_SharedMemory shm = { };
271 
272 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
273 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
274 			goto out;
275 
276 		shm.buffer = val;
277 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
278 			RegisterSharedMemory(&cs->context, &shm, 0,
279 					     TEEC_MEM_OUTPUT)))
280 			goto out_final;
281 
282 		TEEC_ReleaseSharedMemory(&shm);
283 out_final:
284 		TEEC_FinalizeContext(&cs->context);
285 	}
286 out:
287 	Do_ADBG_EndSubCase(cs->c, "Register_zeroLength_Out");
288 }
289 
Allocate_Out(struct xtest_session * cs)290 static void Allocate_Out(struct xtest_session *cs)
291 {
292 	Do_ADBG_BeginSubCase(cs->c, "Allocate_Out");
293 	{
294 		TEEC_SharedMemory shm = { };
295 
296 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
297 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
298 			goto out;
299 
300 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
301 			AllocateSharedMemory(&cs->context, &shm, 0,
302 					     TEEC_MEM_OUTPUT)))
303 			goto out_final;
304 
305 		TEEC_ReleaseSharedMemory(&shm);
306 out_final:
307 		TEEC_FinalizeContext(&cs->context);
308 	}
309 out:
310 	Do_ADBG_EndSubCase(cs->c, "Allocate_Out");
311 }
312 
FinalizeContext_null(struct xtest_session * cs)313 static void FinalizeContext_null(struct xtest_session *cs)
314 {
315 	Do_ADBG_BeginSubCase(cs->c, "FinalizeContext_null");
316 	{
317 		TEEC_FinalizeContext(NULL);
318 	}
319 	Do_ADBG_EndSubCase(cs->c, "FinalizeContext_null");
320 }
321 
InitializeContext_NotExistingTEE(struct xtest_session * cs)322 static void InitializeContext_NotExistingTEE(struct xtest_session *cs)
323 {
324 	Do_ADBG_BeginSubCase(cs->c, "InitializeContext_NotExistingTEE");
325 	{
326 		if (!ADBG_EXPECT_COMPARE_UNSIGNED(cs->c, TEEC_SUCCESS, !=,
327 			TEEC_InitializeContext("Invalid TEE name",
328 					       &cs->context)))
329 			TEEC_FinalizeContext(&cs->context);
330 	}
331 	Do_ADBG_EndSubCase(cs->c, "InitializeContext_NotExistingTEE");
332 }
333 
AllocateThenRegister_SameMemory(struct xtest_session * cs)334 static void AllocateThenRegister_SameMemory(struct xtest_session *cs)
335 {
336 	Do_ADBG_BeginSubCase(cs->c, "AllocateThenRegister_SameMemory");
337 	{
338 		TEEC_SharedMemory shm = { };
339 		size_t size_allocation = 32;
340 
341 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
342 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
343 			goto out;
344 
345 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
346 			AllocateSharedMemory(&cs->context, &shm,
347 					     size_allocation, TEEC_MEM_INPUT)))
348 			goto out_final;
349 
350 		ADBG_EXPECT_TEEC_SUCCESS(cs->c,
351 			RegisterSharedMemory(&cs->context, &shm,
352 					     size_allocation, TEEC_MEM_INPUT));
353 
354 		TEEC_ReleaseSharedMemory(&shm);
355 out_final:
356 		TEEC_FinalizeContext(&cs->context);
357 	}
358 out:
359 	Do_ADBG_EndSubCase(cs->c, "AllocateThenRegister_SameMemory");
360 }
361 
AllocateSameMemory_twice(struct xtest_session * cs)362 static void AllocateSameMemory_twice(struct xtest_session *cs)
363 {
364 	Do_ADBG_BeginSubCase(cs->c, "AllocateSameMemory_twice");
365 	{
366 		TEEC_SharedMemory shm = { };
367 		size_t size_allocation = 32;
368 
369 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
370 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
371 			goto out;
372 
373 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
374 			AllocateSharedMemory(&cs->context, &shm,
375 					     size_allocation, TEEC_MEM_INPUT)))
376 			goto out_final;
377 
378 		ADBG_EXPECT_TEEC_SUCCESS(cs->c,
379 			AllocateSharedMemory(&cs->context, &shm,
380 					     size_allocation, TEEC_MEM_INPUT));
381 
382 		TEEC_ReleaseSharedMemory(&shm);
383 out_final:
384 		TEEC_FinalizeContext(&cs->context);
385 	}
386 out:
387 	Do_ADBG_EndSubCase(cs->c, "AllocateSameMemory_twice");
388 }
389 
RegisterSameMemory_twice(struct xtest_session * cs)390 static void RegisterSameMemory_twice(struct xtest_session *cs)
391 {
392 	Do_ADBG_BeginSubCase(cs->c, "RegisterSameMemory_twice");
393 	{
394 		uint8_t val[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
395 		TEEC_SharedMemory shm = { };
396 
397 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
398 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
399 			goto out;
400 
401 		shm.buffer = val;
402 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
403 			RegisterSharedMemory(&cs->context, &shm, sizeof(val),
404 					     TEEC_MEM_INPUT)))
405 			goto out_final;
406 
407 		ADBG_EXPECT_TEEC_SUCCESS(cs->c,
408 			RegisterSharedMemory(&cs->context, &shm, sizeof(val),
409 					     TEEC_MEM_INPUT));
410 
411 		TEEC_ReleaseSharedMemory(&shm);
412 out_final:
413 		TEEC_FinalizeContext(&cs->context);
414 	}
415 out:
416 	Do_ADBG_EndSubCase(cs->c, "RegisterSameMemory_twice");
417 }
418 
419 #ifndef MIN
420 #define MIN(a,b)	((a) < (b) ? (a) : (b))
421 #endif
422 
Allocate_sharedMemory_32k(struct xtest_session * cs)423 static void Allocate_sharedMemory_32k(struct xtest_session *cs)
424 {
425 	Do_ADBG_BeginSubCase(cs->c, "Allocate_sharedMemory_32k");
426 	{
427 		size_t size = MIN(32 * 1024,
428 				  TEEC_CONFIG_SHAREDMEM_MAX_SIZE);
429 		TEEC_SharedMemory shm = { };
430 
431 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
432 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
433 			goto out;
434 
435 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
436 			AllocateSharedMemory(&cs->context, &shm, size,
437 					     TEEC_MEM_INPUT)))
438 			goto out_final;
439 
440 		TEEC_ReleaseSharedMemory(&shm);
441 out_final:
442 		TEEC_FinalizeContext(&cs->context);
443 	}
444 out:
445 	Do_ADBG_EndSubCase(cs->c, "Allocate_sharedMemory_32k");
446 }
447 
448 #define SHM_32K_SIZE	MIN(32 * 1024, TEEC_CONFIG_SHAREDMEM_MAX_SIZE)
449 
Register_sharedMemory_32k(struct xtest_session * cs)450 static void Register_sharedMemory_32k(struct xtest_session *cs)
451 {
452 	Do_ADBG_BeginSubCase(cs->c, "Register_sharedMemory_32k");
453 	{
454 		uint8_t val[SHM_32K_SIZE] = { };
455 		TEEC_SharedMemory shm = { };
456 
457 		if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS,
458 			TEEC_InitializeContext(xtest_tee_name, &cs->context)))
459 			goto out;
460 
461 		shm.buffer = val;
462 		if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c,
463 			RegisterSharedMemory(&cs->context, &shm, SHM_32K_SIZE,
464 					     TEEC_MEM_INPUT)))
465 			goto out_final;
466 
467 		TEEC_ReleaseSharedMemory(&shm);
468 out_final:
469 		TEEC_FinalizeContext(&cs->context);
470 	}
471 out:
472 	Do_ADBG_EndSubCase(cs->c, "Register_sharedMemory_32k");
473 }
474 
xtest_teec_TEE(ADBG_Case_t * c)475 static void xtest_teec_TEE(ADBG_Case_t *c)
476 {
477 	struct xtest_session connection = { c };
478 
479 	CloseSession_null(&connection);
480 
481 	Allocate_In(&connection);
482 
483 	Allocate_out_of_memory(&connection);
484 
485 	OpenSession_error_notExistingTA(&connection);
486 
487 	Allocate_InOut(&connection);
488 
489 	Register_In(&connection);
490 
491 	Register_notZeroLength_Out(&connection);
492 
493 	Register_InOut(&connection);
494 
495 	Register_zeroLength_Out(&connection);
496 
497 	Allocate_Out(&connection);
498 
499 	FinalizeContext_null(&connection);
500 
501 	InitializeContext_NotExistingTEE(&connection);
502 
503 	AllocateThenRegister_SameMemory(&connection);
504 
505 	AllocateSameMemory_twice(&connection);
506 
507 	RegisterSameMemory_twice(&connection);
508 
509 	Allocate_sharedMemory_32k(&connection);
510 
511 	Register_sharedMemory_32k(&connection);
512 }
513 
514 ADBG_CASE_DEFINE(regression, 5006, xtest_teec_TEE,
515 		"Tests for Global platform TEEC");
516