blob: 5126c1231cebe9824ab2a16843e5854e0bd1a0ea [file] [log] [blame]
Pascal Brandc639ac82015-07-02 08:53:34 +02001/*
2 * Copyright (c) 2014, STMicroelectronics International N.V.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Jens Wiklandere2ca6062016-12-21 14:00:30 +010014#include <assert.h>
15#include <err.h>
16#include <malloc.h>
17#include <pthread.h>
18#include <stdio.h>
19#include <string.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020020#include <ta_crypt.h>
Vesa Jääskeläinene8c0c8d2020-04-05 20:11:53 +030021#include <ta_os_test.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020022#include <utee_defines.h>
23
Jens Wiklandere2ca6062016-12-21 14:00:30 +010024#include "xtest_helpers.h"
25#include "xtest_test.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020026
27/* Round up the even multiple of size, size has to be a multiple of 2 */
28#define ROUNDUP(v, size) (((v) + (size - 1)) & ~(size - 1))
29
30TEEC_Context xtest_teec_ctx;
31
32TEEC_Result xtest_teec_ctx_init(void)
33{
34 return TEEC_InitializeContext(_device, &xtest_teec_ctx);
35}
36
37TEEC_Result xtest_teec_open_session(TEEC_Session *session,
38 const TEEC_UUID *uuid, TEEC_Operation *op,
39 uint32_t *ret_orig)
40{
41 return TEEC_OpenSession(&xtest_teec_ctx, session, uuid,
42 TEEC_LOGIN_PUBLIC, NULL, op, ret_orig);
43}
44
45void xtest_teec_ctx_deinit(void)
46{
47 TEEC_FinalizeContext(&xtest_teec_ctx);
48}
49
50TEEC_Result ta_crypt_cmd_allocate_operation(ADBG_Case_t *c, TEEC_Session *s,
51 TEE_OperationHandle *oph,
52 uint32_t algo, uint32_t mode,
53 uint32_t max_key_size)
54{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010055 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +020056 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010057 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020058
59 op.params[0].value.a = 0;
60 op.params[0].value.b = algo;
61 op.params[1].value.a = mode;
62 op.params[1].value.b = max_key_size;
63
64 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_VALUE_INPUT,
65 TEEC_NONE, TEEC_NONE);
66
67 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_OPERATION, &op,
68 &ret_orig);
69
70 if (res != TEEC_SUCCESS) {
71 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
72 ret_orig);
73 }
74
75 if (res == TEEC_SUCCESS)
76 *oph = (TEE_OperationHandle)(uintptr_t)op.params[0].value.a;
77
78 return res;
79}
80
81TEEC_Result ta_crypt_cmd_allocate_transient_object(ADBG_Case_t *c,
82 TEEC_Session *s,
83 TEE_ObjectType obj_type,
84 uint32_t max_obj_size,
85 TEE_ObjectHandle *o)
86{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010087 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +020088 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010089 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020090
91 op.params[0].value.a = obj_type;
92 op.params[0].value.b = max_obj_size;
93
94 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
95 TEEC_NONE, TEEC_NONE);
96
97 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_TRANSIENT_OBJECT, &op,
98 &ret_orig);
99
100 if (res != TEEC_SUCCESS) {
101 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
102 ret_orig);
103 }
104
105 if (res == TEEC_SUCCESS)
106 *o = (TEE_ObjectHandle)(uintptr_t)op.params[1].value.a;
107
108 return res;
109}
110
111void xtest_add_attr(size_t *attr_count, TEE_Attribute *attrs, uint32_t attr_id,
112 const void *buf, size_t len)
113{
114 attrs[*attr_count].attributeID = attr_id;
115 attrs[*attr_count].content.ref.buffer = (void *)buf;
116 attrs[*attr_count].content.ref.length = len;
117 (*attr_count)++;
118}
119
Pascal Brande61133f2015-07-08 15:38:37 +0200120void xtest_add_attr_value(size_t *attr_count, TEE_Attribute *attrs,
121 uint32_t attr_id, uint32_t value_a, uint32_t value_b)
122{
123 attrs[*attr_count].attributeID = attr_id;
124 attrs[*attr_count].content.value.a = value_a;
125 attrs[*attr_count].content.value.b = value_b;
126 (*attr_count)++;
127}
128
Pascal Brandc639ac82015-07-02 08:53:34 +0200129struct tee_attr_packed {
130 uint32_t attr_id;
131 uint32_t a;
132 uint32_t b;
133};
134
135TEE_Result pack_attrs(const TEE_Attribute *attrs, uint32_t attr_count,
136 uint8_t **buf, size_t *blen)
137{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100138 struct tee_attr_packed *a = NULL;
139 uint8_t *b = NULL;
140 size_t bl = 0;
141 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200142
143 *buf = NULL;
144 *blen = 0;
145 if (attr_count == 0)
146 return TEE_SUCCESS;
147
148 bl = sizeof(uint32_t) + sizeof(struct tee_attr_packed) * attr_count;
149 for (n = 0; n < attr_count; n++) {
150 if ((attrs[n].attributeID & TEE_ATTR_BIT_VALUE) != 0)
151 continue; /* Only memrefs need to be updated */
152
153 if (!attrs[n].content.ref.buffer)
154 continue;
155
156 /* Make room for padding */
157 bl += ROUNDUP(attrs[n].content.ref.length, 4);
158 }
159
160 b = calloc(1, bl);
161 if (!b)
162 return TEE_ERROR_OUT_OF_MEMORY;
163
164 *buf = b;
165 *blen = bl;
166
167 *(uint32_t *)(void *)b = attr_count;
168 b += sizeof(uint32_t);
169 a = (struct tee_attr_packed *)(void *)b;
170 b += sizeof(struct tee_attr_packed) * attr_count;
171
172 for (n = 0; n < attr_count; n++) {
173 a[n].attr_id = attrs[n].attributeID;
174 if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
175 a[n].a = attrs[n].content.value.a;
176 a[n].b = attrs[n].content.value.b;
177 continue;
178 }
179
180 a[n].b = attrs[n].content.ref.length;
181
182 if (!attrs[n].content.ref.buffer) {
183 a[n].a = 0;
184 continue;
185 }
186
187 memcpy(b, attrs[n].content.ref.buffer,
188 attrs[n].content.ref.length);
189
190 /* Make buffer pointer relative to *buf */
191 a[n].a = (uint32_t)(uintptr_t)(b - *buf);
192
193 /* Round up to good alignment */
194 b += ROUNDUP(attrs[n].content.ref.length, 4);
195 }
196
197 return TEE_SUCCESS;
198}
199
200TEEC_Result ta_crypt_cmd_populate_transient_object(ADBG_Case_t *c,
201 TEEC_Session *s,
202 TEE_ObjectHandle o,
203 const TEE_Attribute *attrs,
204 uint32_t attr_count)
205{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100206 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200207 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100208 uint32_t ret_orig = 0;
209 uint8_t *buf = NULL;
210 size_t blen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200211
212 res = pack_attrs(attrs, attr_count, &buf, &blen);
213 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
214 return res;
215
216 assert((uintptr_t)o <= UINT32_MAX);
217 op.params[0].value.a = (uint32_t)(uintptr_t)o;
218
219 op.params[1].tmpref.buffer = buf;
220 op.params[1].tmpref.size = blen;
221
222 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
223 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
224 TEEC_NONE);
225
226 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_POPULATE_TRANSIENT_OBJECT, &op,
227 &ret_orig);
228
Jens Wiklander70a0b2c2016-05-18 08:39:35 +0200229 if (res != TEEC_SUCCESS && res != TEEC_ERROR_TARGET_DEAD) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200230 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
231 ret_orig);
232 }
233
234 free(buf);
235 return res;
236}
237
238TEE_Result ta_crypt_cmd_set_operation_key(ADBG_Case_t *c, TEEC_Session *s,
239 TEE_OperationHandle oph,
240 TEE_ObjectHandle key)
241{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100242 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200243 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100244 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200245
246 assert((uintptr_t)oph <= UINT32_MAX);
247 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
248
249 assert((uintptr_t)key <= UINT32_MAX);
250 op.params[0].value.b = (uint32_t)(uintptr_t)key;
251
252 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
253 TEEC_NONE);
254
255 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_SET_OPERATION_KEY, &op,
256 &ret_orig);
257
258 if (res != TEEC_SUCCESS) {
259 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
260 ret_orig);
261 }
262
263 return res;
264}
265
266TEEC_Result ta_crypt_cmd_free_transient_object(ADBG_Case_t *c, TEEC_Session *s,
267 TEE_ObjectHandle o)
268{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100269 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200270 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100271 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200272
273 assert((uintptr_t)o <= UINT32_MAX);
274 op.params[0].value.a = (uint32_t)(uintptr_t)o;
275 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
276 TEEC_NONE);
277
278 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_TRANSIENT_OBJECT, &op,
279 &ret_orig);
280
281 if (res != TEEC_SUCCESS) {
282 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
283 ret_orig);
284 }
285
286 return res;
287}
288
289TEEC_Result ta_crypt_cmd_derive_key(ADBG_Case_t *c, TEEC_Session *s,
290 TEE_OperationHandle oph, TEE_ObjectHandle o,
291 const TEE_Attribute *params,
292 uint32_t paramCount)
293{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100294 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200295 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100296 uint32_t ret_orig = 0;
297 uint8_t *buf = NULL;
298 size_t blen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200299
300 res = pack_attrs(params, paramCount, &buf, &blen);
301
302 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
303 return res;
304
305 assert((uintptr_t)oph <= UINT32_MAX);
306 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
307
308 assert((uintptr_t)o <= UINT32_MAX);
309 op.params[0].value.b = (uint32_t)(uintptr_t)o;
310
311 op.params[1].tmpref.buffer = buf;
312 op.params[1].tmpref.size = blen;
313
314 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
315 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
316 TEEC_NONE);
317
318 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_DERIVE_KEY, &op, &ret_orig);
319
320 if (res != TEEC_SUCCESS) {
321 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
322 ret_orig);
323 }
324
325 free(buf);
326 return res;
327}
328
329TEEC_Result ta_crypt_cmd_get_object_buffer_attribute(ADBG_Case_t *c,
330 TEEC_Session *s,
331 TEE_ObjectHandle o,
332 uint32_t attr_id,
333 void *buf, size_t *blen)
334{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100335 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200336 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100337 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200338
339 assert((uintptr_t)o <= UINT32_MAX);
340 op.params[0].value.a = (uint32_t)(uintptr_t)o;
341 op.params[0].value.b = attr_id;
342
343 op.params[1].tmpref.buffer = buf;
344 op.params[1].tmpref.size = *blen;
345
346 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
347 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE,
348 TEEC_NONE);
349
350 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_GET_OBJECT_BUFFER_ATTRIBUTE,
351 &op, &ret_orig);
352
353 if (res != TEEC_SUCCESS) {
354 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
355 ret_orig);
356 }
357
358 if (res == TEEC_SUCCESS)
359 *blen = op.params[1].tmpref.size;
360
361 return res;
362}
363
364TEEC_Result ta_crypt_cmd_free_operation(ADBG_Case_t *c, TEEC_Session *s,
365 TEE_OperationHandle oph)
366{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100367 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200368 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100369 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200370
371 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
372
373 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
374 TEEC_NONE);
375
376 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_OPERATION, &op,
377 &ret_orig);
378
379 if (res != TEEC_SUCCESS) {
380 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
381 ret_orig);
382 }
383
384 return res;
385}
Jerome Forissiere3854162016-08-12 12:40:12 +0200386
Jerome Forissier6635c962020-01-22 17:49:00 +0100387bool ta_crypt_cmd_is_algo_supported(ADBG_Case_t *c, TEEC_Session *s,
388 uint32_t algo, uint32_t element)
389{
390 TEEC_Result res = TEEC_ERROR_GENERIC;
391 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
392 uint32_t ret_orig = 0;
393 TEEC_Result st = TEEC_ERROR_GENERIC;
394
395 op.params[0].value.a = algo;
396 op.params[0].value.b = element;
397
398 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
399 TEEC_NONE, TEEC_NONE);
400
401 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_IS_ALGO_SUPPORTED, &op,
402 &ret_orig);
403 if (res != TEEC_SUCCESS) {
404 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
405 ret_orig);
406 return res;
407 }
408
409 st = op.params[1].value.a;
410 ADBG_EXPECT_TRUE(c, st == TEEC_SUCCESS ||
411 st == TEEC_ERROR_NOT_SUPPORTED);
412 if (st == TEE_SUCCESS)
413 return true;
414 return false;
415}
416
Vesa Jääskeläinene8c0c8d2020-04-05 20:11:53 +0300417TEEC_Result ta_os_test_cmd_client_identity(TEEC_Session *session,
418 uint32_t *login,
419 TEEC_UUID *client_uuid)
420{
421 TEEC_Operation operation = { };
422 TEEC_Result result = TEEC_ERROR_GENERIC;
423
424 operation.params[1].tmpref.buffer = client_uuid;
425 operation.params[1].tmpref.size = sizeof(*client_uuid);
426
427 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
428 TEEC_MEMREF_TEMP_OUTPUT,
429 TEEC_NONE, TEEC_NONE);
430
431 result = TEEC_InvokeCommand(session, TA_OS_TEST_CMD_CLIENT_IDENTITY,
432 &operation, NULL);
433
434 if (result != TEEC_SUCCESS)
435 return result;
436
437 *login = operation.params[0].value.a;
438
439 return TEEC_SUCCESS;
440}
441
Jens Wiklandere2ca6062016-12-21 14:00:30 +0100442void xtest_mutex_init(pthread_mutex_t *mutex)
443{
444 int e = pthread_mutex_init(mutex, NULL);
445
446 if (e)
447 errx(1, "pthread_mutex_init: %s", strerror(e));
448}
449
450void xtest_mutex_destroy(pthread_mutex_t *mutex)
451{
452 int e = pthread_mutex_destroy(mutex);
453
454 if (e)
455 errx(1, "pthread_mutex_destroy: %s", strerror(e));
456}
457
458void xtest_mutex_lock(pthread_mutex_t *mutex)
459{
460 int e = pthread_mutex_lock(mutex);
461
462 if (e)
463 errx(1, "pthread_mutex_lock: %s", strerror(e));
464}
465
466void xtest_mutex_unlock(pthread_mutex_t *mutex)
467{
468 int e = pthread_mutex_unlock(mutex);
469
470 if (e)
471 errx(1, "pthread_mutex_unlock: %s", strerror(e));
472}
473
474void xtest_barrier_init(pthread_barrier_t *barrier, unsigned count)
475{
476 int e = pthread_barrier_init(barrier, NULL, count);
477
478 if (e)
479 errx(1, "pthread_barrier_init: %s", strerror(e));
480}
481
482void xtest_barrier_destroy(pthread_barrier_t *barrier)
483{
484 int e = pthread_barrier_destroy(barrier);
485
486 if (e)
487 errx(1, "pthread_barrier_destroy: %s", strerror(e));
488}
489
490int xtest_barrier_wait(pthread_barrier_t *barrier)
491{
492 int e = pthread_barrier_wait(barrier);
493
494 if (e && e != PTHREAD_BARRIER_SERIAL_THREAD)
495 errx(1, "pthread _barrier_wait: %s", strerror(e));
496 return e;
497}