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