blob: 6506fc1507b297ce70e8b6ada270f719f611ef13 [file] [log] [blame]
Etienne Carriere9b7b70d2020-05-16 10:27:23 +02001// SPDX-License-Identifier: GPL-2.0
Pascal Brandc639ac82015-07-02 08:53:34 +02002/*
3 * Copyright (c) 2014, STMicroelectronics International N.V.
Pascal Brandc639ac82015-07-02 08:53:34 +02004 */
5
Jens Wiklandere2ca6062016-12-21 14:00:30 +01006#include <assert.h>
7#include <err.h>
8#include <malloc.h>
9#include <pthread.h>
10#include <stdio.h>
11#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020012#include <ta_crypt.h>
Vesa Jääskeläinene8c0c8d2020-04-05 20:11:53 +030013#include <ta_os_test.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020014#include <utee_defines.h>
15
Jens Wiklandere2ca6062016-12-21 14:00:30 +010016#include "xtest_helpers.h"
17#include "xtest_test.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020018
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
22TEEC_Context xtest_teec_ctx;
23
24TEEC_Result xtest_teec_ctx_init(void)
25{
Etienne Carriereb11820c2020-05-26 11:55:33 +020026 return TEEC_InitializeContext(xtest_tee_name, &xtest_teec_ctx);
Pascal Brandc639ac82015-07-02 08:53:34 +020027}
28
29TEEC_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
37void xtest_teec_ctx_deinit(void)
38{
39 TEEC_FinalizeContext(&xtest_teec_ctx);
40}
41
42TEEC_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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010047 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +020048 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010049 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020050
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
73TEEC_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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010079 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +020080 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010081 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020082
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
103void 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
Pascal Brande61133f2015-07-08 15:38:37 +0200112void 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
Pascal Brandc639ac82015-07-02 08:53:34 +0200121struct tee_attr_packed {
122 uint32_t attr_id;
123 uint32_t a;
124 uint32_t b;
125};
126
127TEE_Result pack_attrs(const TEE_Attribute *attrs, uint32_t attr_count,
128 uint8_t **buf, size_t *blen)
129{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100130 struct tee_attr_packed *a = NULL;
131 uint8_t *b = NULL;
132 size_t bl = 0;
133 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200134
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
192TEEC_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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100198 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200199 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100200 uint32_t ret_orig = 0;
201 uint8_t *buf = NULL;
202 size_t blen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200203
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
Jens Wiklander70a0b2c2016-05-18 08:39:35 +0200221 if (res != TEEC_SUCCESS && res != TEEC_ERROR_TARGET_DEAD) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200222 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
223 ret_orig);
224 }
225
226 free(buf);
227 return res;
228}
229
230TEE_Result ta_crypt_cmd_set_operation_key(ADBG_Case_t *c, TEEC_Session *s,
231 TEE_OperationHandle oph,
232 TEE_ObjectHandle key)
233{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100234 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200235 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100236 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200237
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
258TEEC_Result ta_crypt_cmd_free_transient_object(ADBG_Case_t *c, TEEC_Session *s,
259 TEE_ObjectHandle o)
260{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100261 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200262 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100263 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200264
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
281TEEC_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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100286 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200287 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100288 uint32_t ret_orig = 0;
289 uint8_t *buf = NULL;
290 size_t blen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200291
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
321TEEC_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{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100327 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200328 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100329 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200330
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
356TEEC_Result ta_crypt_cmd_free_operation(ADBG_Case_t *c, TEEC_Session *s,
357 TEE_OperationHandle oph)
358{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100359 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200360 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100361 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200362
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}
Jerome Forissiere3854162016-08-12 12:40:12 +0200378
Jerome Forissier6635c962020-01-22 17:49:00 +0100379bool 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
Vesa Jääskeläinene8c0c8d2020-04-05 20:11:53 +0300409TEEC_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
Jens Wiklandere2ca6062016-12-21 14:00:30 +0100434void 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
442void 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
450void 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
458void 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
466void 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
474void 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
482int 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}