1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 
6 #include <assert.h>
7 #include <err.h>
8 #include <malloc.h>
9 #include <pthread.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <ta_crypt.h>
13 #include <ta_os_test.h>
14 #include <utee_defines.h>
15 
16 #include "xtest_helpers.h"
17 #include "xtest_test.h"
18 
19 /* Round up the even multiple of size, size has to be a multiple of 2 */
20 #define ROUNDUP(v, size) (((v) + (size - 1)) & ~(size - 1))
21 
22 TEEC_Context xtest_teec_ctx;
23 
xtest_teec_ctx_init(void)24 TEEC_Result xtest_teec_ctx_init(void)
25 {
26 	return TEEC_InitializeContext(xtest_tee_name, &xtest_teec_ctx);
27 }
28 
xtest_teec_open_session(TEEC_Session * session,const TEEC_UUID * uuid,TEEC_Operation * op,uint32_t * ret_orig)29 TEEC_Result xtest_teec_open_session(TEEC_Session *session,
30 				    const TEEC_UUID *uuid, TEEC_Operation *op,
31 				    uint32_t *ret_orig)
32 {
33 	return TEEC_OpenSession(&xtest_teec_ctx, session, uuid,
34 				TEEC_LOGIN_PUBLIC, NULL, op, ret_orig);
35 }
36 
xtest_teec_ctx_deinit(void)37 void xtest_teec_ctx_deinit(void)
38 {
39 	TEEC_FinalizeContext(&xtest_teec_ctx);
40 }
41 
ta_crypt_cmd_allocate_operation(ADBG_Case_t * c,TEEC_Session * s,TEE_OperationHandle * oph,uint32_t algo,uint32_t mode,uint32_t max_key_size)42 TEEC_Result ta_crypt_cmd_allocate_operation(ADBG_Case_t *c, TEEC_Session *s,
43 					    TEE_OperationHandle *oph,
44 					    uint32_t algo, uint32_t mode,
45 					    uint32_t max_key_size)
46 {
47 	TEEC_Result res = TEEC_ERROR_GENERIC;
48 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
49 	uint32_t ret_orig = 0;
50 
51 	op.params[0].value.a = 0;
52 	op.params[0].value.b = algo;
53 	op.params[1].value.a = mode;
54 	op.params[1].value.b = max_key_size;
55 
56 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_VALUE_INPUT,
57 					 TEEC_NONE, TEEC_NONE);
58 
59 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_OPERATION, &op,
60 				 &ret_orig);
61 
62 	if (res != TEEC_SUCCESS) {
63 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
64 						    ret_orig);
65 	}
66 
67 	if (res == TEEC_SUCCESS)
68 		*oph = (TEE_OperationHandle)(uintptr_t)op.params[0].value.a;
69 
70 	return res;
71 }
72 
ta_crypt_cmd_allocate_transient_object(ADBG_Case_t * c,TEEC_Session * s,TEE_ObjectType obj_type,uint32_t max_obj_size,TEE_ObjectHandle * o)73 TEEC_Result ta_crypt_cmd_allocate_transient_object(ADBG_Case_t *c,
74 						   TEEC_Session *s,
75 						   TEE_ObjectType obj_type,
76 						   uint32_t max_obj_size,
77 						   TEE_ObjectHandle *o)
78 {
79 	TEEC_Result res = TEEC_ERROR_GENERIC;
80 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
81 	uint32_t ret_orig = 0;
82 
83 	op.params[0].value.a = obj_type;
84 	op.params[0].value.b = max_obj_size;
85 
86 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
87 					 TEEC_NONE, TEEC_NONE);
88 
89 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_TRANSIENT_OBJECT, &op,
90 				 &ret_orig);
91 
92 	if (res != TEEC_SUCCESS) {
93 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
94 			    ret_orig);
95 	}
96 
97 	if (res == TEEC_SUCCESS)
98 		*o = (TEE_ObjectHandle)(uintptr_t)op.params[1].value.a;
99 
100 	return res;
101 }
102 
xtest_add_attr(size_t * attr_count,TEE_Attribute * attrs,uint32_t attr_id,const void * buf,size_t len)103 void xtest_add_attr(size_t *attr_count, TEE_Attribute *attrs, uint32_t attr_id,
104 		    const void *buf, size_t len)
105 {
106 	attrs[*attr_count].attributeID = attr_id;
107 	attrs[*attr_count].content.ref.buffer = (void *)buf;
108 	attrs[*attr_count].content.ref.length = len;
109 	(*attr_count)++;
110 }
111 
xtest_add_attr_value(size_t * attr_count,TEE_Attribute * attrs,uint32_t attr_id,uint32_t value_a,uint32_t value_b)112 void xtest_add_attr_value(size_t *attr_count, TEE_Attribute *attrs,
113 			  uint32_t attr_id, uint32_t value_a, uint32_t value_b)
114 {
115 	attrs[*attr_count].attributeID = attr_id;
116 	attrs[*attr_count].content.value.a = value_a;
117 	attrs[*attr_count].content.value.b = value_b;
118 	(*attr_count)++;
119 }
120 
121 struct tee_attr_packed {
122 	uint32_t attr_id;
123 	uint32_t a;
124 	uint32_t b;
125 };
126 
pack_attrs(const TEE_Attribute * attrs,uint32_t attr_count,uint8_t ** buf,size_t * blen)127 TEE_Result pack_attrs(const TEE_Attribute *attrs, uint32_t attr_count,
128 		      uint8_t **buf, size_t *blen)
129 {
130 	struct tee_attr_packed *a = NULL;
131 	uint8_t *b = NULL;
132 	size_t bl = 0;
133 	size_t n = 0;
134 
135 	*buf = NULL;
136 	*blen = 0;
137 	if (attr_count == 0)
138 		return TEE_SUCCESS;
139 
140 	bl = sizeof(uint32_t) + sizeof(struct tee_attr_packed) * attr_count;
141 	for (n = 0; n < attr_count; n++) {
142 		if ((attrs[n].attributeID & TEE_ATTR_BIT_VALUE) != 0)
143 			continue; /* Only memrefs need to be updated */
144 
145 		if (!attrs[n].content.ref.buffer)
146 			continue;
147 
148 		/* Make room for padding */
149 		bl += ROUNDUP(attrs[n].content.ref.length, 4);
150 	}
151 
152 	b = calloc(1, bl);
153 	if (!b)
154 		return TEE_ERROR_OUT_OF_MEMORY;
155 
156 	*buf = b;
157 	*blen = bl;
158 
159 	*(uint32_t *)(void *)b = attr_count;
160 	b += sizeof(uint32_t);
161 	a = (struct tee_attr_packed *)(void *)b;
162 	b += sizeof(struct tee_attr_packed) * attr_count;
163 
164 	for (n = 0; n < attr_count; n++) {
165 		a[n].attr_id = attrs[n].attributeID;
166 		if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
167 			a[n].a = attrs[n].content.value.a;
168 			a[n].b = attrs[n].content.value.b;
169 			continue;
170 		}
171 
172 		a[n].b = attrs[n].content.ref.length;
173 
174 		if (!attrs[n].content.ref.buffer) {
175 			a[n].a = 0;
176 			continue;
177 		}
178 
179 		memcpy(b, attrs[n].content.ref.buffer,
180 		       attrs[n].content.ref.length);
181 
182 		/* Make buffer pointer relative to *buf */
183 		a[n].a = (uint32_t)(uintptr_t)(b - *buf);
184 
185 		/* Round up to good alignment */
186 		b += ROUNDUP(attrs[n].content.ref.length, 4);
187 	}
188 
189 	return TEE_SUCCESS;
190 }
191 
ta_crypt_cmd_populate_transient_object(ADBG_Case_t * c,TEEC_Session * s,TEE_ObjectHandle o,const TEE_Attribute * attrs,uint32_t attr_count)192 TEEC_Result ta_crypt_cmd_populate_transient_object(ADBG_Case_t *c,
193 						   TEEC_Session *s,
194 						   TEE_ObjectHandle o,
195 						   const TEE_Attribute *attrs,
196 						   uint32_t attr_count)
197 {
198 	TEEC_Result res = TEEC_ERROR_GENERIC;
199 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
200 	uint32_t ret_orig = 0;
201 	uint8_t *buf = NULL;
202 	size_t blen = 0;
203 
204 	res = pack_attrs(attrs, attr_count, &buf, &blen);
205 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
206 		return res;
207 
208 	assert((uintptr_t)o <= UINT32_MAX);
209 	op.params[0].value.a = (uint32_t)(uintptr_t)o;
210 
211 	op.params[1].tmpref.buffer = buf;
212 	op.params[1].tmpref.size = blen;
213 
214 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
215 					 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
216 					 TEEC_NONE);
217 
218 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_POPULATE_TRANSIENT_OBJECT, &op,
219 				 &ret_orig);
220 
221 	if (res != TEEC_SUCCESS && res != TEEC_ERROR_TARGET_DEAD) {
222 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
223 						    ret_orig);
224 	}
225 
226 	free(buf);
227 	return res;
228 }
229 
ta_crypt_cmd_set_operation_key(ADBG_Case_t * c,TEEC_Session * s,TEE_OperationHandle oph,TEE_ObjectHandle key)230 TEE_Result ta_crypt_cmd_set_operation_key(ADBG_Case_t *c, TEEC_Session *s,
231 					  TEE_OperationHandle oph,
232 					  TEE_ObjectHandle key)
233 {
234 	TEEC_Result res = TEEC_ERROR_GENERIC;
235 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
236 	uint32_t ret_orig = 0;
237 
238 	assert((uintptr_t)oph <= UINT32_MAX);
239 	op.params[0].value.a = (uint32_t)(uintptr_t)oph;
240 
241 	assert((uintptr_t)key <= UINT32_MAX);
242 	op.params[0].value.b = (uint32_t)(uintptr_t)key;
243 
244 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
245 					 TEEC_NONE);
246 
247 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_SET_OPERATION_KEY, &op,
248 				 &ret_orig);
249 
250 	if (res != TEEC_SUCCESS) {
251 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
252 						    ret_orig);
253 	}
254 
255 	return res;
256 }
257 
ta_crypt_cmd_free_transient_object(ADBG_Case_t * c,TEEC_Session * s,TEE_ObjectHandle o)258 TEEC_Result ta_crypt_cmd_free_transient_object(ADBG_Case_t *c, TEEC_Session *s,
259 					       TEE_ObjectHandle o)
260 {
261 	TEEC_Result res = TEEC_ERROR_GENERIC;
262 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
263 	uint32_t ret_orig = 0;
264 
265 	assert((uintptr_t)o <= UINT32_MAX);
266 	op.params[0].value.a = (uint32_t)(uintptr_t)o;
267 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
268 					 TEEC_NONE);
269 
270 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_TRANSIENT_OBJECT, &op,
271 				 &ret_orig);
272 
273 	if (res != TEEC_SUCCESS) {
274 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
275 						    ret_orig);
276 	}
277 
278 	return res;
279 }
280 
ta_crypt_cmd_derive_key(ADBG_Case_t * c,TEEC_Session * s,TEE_OperationHandle oph,TEE_ObjectHandle o,const TEE_Attribute * params,uint32_t paramCount)281 TEEC_Result ta_crypt_cmd_derive_key(ADBG_Case_t *c, TEEC_Session *s,
282 				    TEE_OperationHandle oph, TEE_ObjectHandle o,
283 				    const TEE_Attribute *params,
284 				    uint32_t paramCount)
285 {
286 	TEEC_Result res = TEEC_ERROR_GENERIC;
287 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
288 	uint32_t ret_orig = 0;
289 	uint8_t *buf = NULL;
290 	size_t blen = 0;
291 
292 	res = pack_attrs(params, paramCount, &buf, &blen);
293 
294 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
295 		return res;
296 
297 	assert((uintptr_t)oph <= UINT32_MAX);
298 	op.params[0].value.a = (uint32_t)(uintptr_t)oph;
299 
300 	assert((uintptr_t)o <= UINT32_MAX);
301 	op.params[0].value.b = (uint32_t)(uintptr_t)o;
302 
303 	op.params[1].tmpref.buffer = buf;
304 	op.params[1].tmpref.size = blen;
305 
306 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
307 					 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
308 					 TEEC_NONE);
309 
310 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_DERIVE_KEY, &op, &ret_orig);
311 
312 	if (res != TEEC_SUCCESS) {
313 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
314 						    ret_orig);
315 	}
316 
317 	free(buf);
318 	return res;
319 }
320 
ta_crypt_cmd_get_object_buffer_attribute(ADBG_Case_t * c,TEEC_Session * s,TEE_ObjectHandle o,uint32_t attr_id,void * buf,size_t * blen)321 TEEC_Result ta_crypt_cmd_get_object_buffer_attribute(ADBG_Case_t *c,
322 						     TEEC_Session *s,
323 						     TEE_ObjectHandle o,
324 						     uint32_t attr_id,
325 						     void *buf, size_t *blen)
326 {
327 	TEEC_Result res = TEEC_ERROR_GENERIC;
328 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
329 	uint32_t ret_orig = 0;
330 
331 	assert((uintptr_t)o <= UINT32_MAX);
332 	op.params[0].value.a = (uint32_t)(uintptr_t)o;
333 	op.params[0].value.b = attr_id;
334 
335 	op.params[1].tmpref.buffer = buf;
336 	op.params[1].tmpref.size = *blen;
337 
338 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
339 					 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE,
340 					 TEEC_NONE);
341 
342 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_GET_OBJECT_BUFFER_ATTRIBUTE,
343 				 &op, &ret_orig);
344 
345 	if (res != TEEC_SUCCESS) {
346 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
347 						    ret_orig);
348 	}
349 
350 	if (res == TEEC_SUCCESS)
351 		*blen = op.params[1].tmpref.size;
352 
353 	return res;
354 }
355 
ta_crypt_cmd_free_operation(ADBG_Case_t * c,TEEC_Session * s,TEE_OperationHandle oph)356 TEEC_Result ta_crypt_cmd_free_operation(ADBG_Case_t *c, TEEC_Session *s,
357 					TEE_OperationHandle oph)
358 {
359 	TEEC_Result res = TEEC_ERROR_GENERIC;
360 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
361 	uint32_t ret_orig = 0;
362 
363 	op.params[0].value.a = (uint32_t)(uintptr_t)oph;
364 
365 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
366 					 TEEC_NONE);
367 
368 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_OPERATION, &op,
369 				 &ret_orig);
370 
371 	if (res != TEEC_SUCCESS) {
372 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
373 						    ret_orig);
374 	}
375 
376 	return res;
377 }
378 
ta_crypt_cmd_is_algo_supported(ADBG_Case_t * c,TEEC_Session * s,uint32_t algo,uint32_t element)379 bool ta_crypt_cmd_is_algo_supported(ADBG_Case_t *c, TEEC_Session *s,
380 				    uint32_t algo, uint32_t element)
381 {
382 	TEEC_Result res = TEEC_ERROR_GENERIC;
383 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
384 	uint32_t ret_orig = 0;
385 	TEEC_Result st = TEEC_ERROR_GENERIC;
386 
387 	op.params[0].value.a = algo;
388 	op.params[0].value.b = element;
389 
390 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
391 					 TEEC_NONE, TEEC_NONE);
392 
393 	res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_IS_ALGO_SUPPORTED, &op,
394 				 &ret_orig);
395 	if (res != TEEC_SUCCESS) {
396 		(void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
397 						    ret_orig);
398 		return res;
399 	}
400 
401 	st = op.params[1].value.a;
402 	ADBG_EXPECT_TRUE(c, st == TEEC_SUCCESS ||
403 			 st == TEEC_ERROR_NOT_SUPPORTED);
404 	if (st == TEE_SUCCESS)
405 		return true;
406 	return false;
407 }
408 
ta_os_test_cmd_client_identity(TEEC_Session * session,uint32_t * login,TEEC_UUID * client_uuid)409 TEEC_Result ta_os_test_cmd_client_identity(TEEC_Session *session,
410 					   uint32_t *login,
411 					   TEEC_UUID *client_uuid)
412 {
413 	TEEC_Operation operation = { };
414 	TEEC_Result result = TEEC_ERROR_GENERIC;
415 
416 	operation.params[1].tmpref.buffer = client_uuid;
417 	operation.params[1].tmpref.size = sizeof(*client_uuid);
418 
419 	operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
420 						TEEC_MEMREF_TEMP_OUTPUT,
421 						TEEC_NONE, TEEC_NONE);
422 
423 	result = TEEC_InvokeCommand(session, TA_OS_TEST_CMD_CLIENT_IDENTITY,
424 				    &operation, NULL);
425 
426 	if (result != TEEC_SUCCESS)
427 		return result;
428 
429 	*login = operation.params[0].value.a;
430 
431 	return TEEC_SUCCESS;
432 }
433 
xtest_mutex_init(pthread_mutex_t * mutex)434 void xtest_mutex_init(pthread_mutex_t *mutex)
435 {
436 	int e = pthread_mutex_init(mutex, NULL);
437 
438 	if (e)
439 		errx(1, "pthread_mutex_init: %s", strerror(e));
440 }
441 
xtest_mutex_destroy(pthread_mutex_t * mutex)442 void xtest_mutex_destroy(pthread_mutex_t *mutex)
443 {
444 	int e = pthread_mutex_destroy(mutex);
445 
446 	if (e)
447 		errx(1, "pthread_mutex_destroy: %s", strerror(e));
448 }
449 
xtest_mutex_lock(pthread_mutex_t * mutex)450 void xtest_mutex_lock(pthread_mutex_t *mutex)
451 {
452 	int e = pthread_mutex_lock(mutex);
453 
454 	if (e)
455 		errx(1, "pthread_mutex_lock: %s", strerror(e));
456 }
457 
xtest_mutex_unlock(pthread_mutex_t * mutex)458 void xtest_mutex_unlock(pthread_mutex_t *mutex)
459 {
460 	int e = pthread_mutex_unlock(mutex);
461 
462 	if (e)
463 		errx(1, "pthread_mutex_unlock: %s", strerror(e));
464 }
465 
xtest_barrier_init(pthread_barrier_t * barrier,unsigned count)466 void xtest_barrier_init(pthread_barrier_t *barrier, unsigned count)
467 {
468 	int e = pthread_barrier_init(barrier, NULL, count);
469 
470 	if (e)
471 		errx(1, "pthread_barrier_init: %s", strerror(e));
472 }
473 
xtest_barrier_destroy(pthread_barrier_t * barrier)474 void xtest_barrier_destroy(pthread_barrier_t *barrier)
475 {
476 	int e = pthread_barrier_destroy(barrier);
477 
478 	if (e)
479 		errx(1, "pthread_barrier_destroy: %s", strerror(e));
480 }
481 
xtest_barrier_wait(pthread_barrier_t * barrier)482 int xtest_barrier_wait(pthread_barrier_t *barrier)
483 {
484 	int e = pthread_barrier_wait(barrier);
485 
486 	if (e && e != PTHREAD_BARRIER_SERIAL_THREAD)
487 		errx(1, "pthread _barrier_wait: %s", strerror(e));
488 	return e;
489 }
490