blob: d8b286fdc3aeb93fcd50cc16eddc77dd811a3548 [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>
21#include <utee_defines.h>
22
Jens Wiklandere2ca6062016-12-21 14:00:30 +010023#include "xtest_helpers.h"
24#include "xtest_test.h"
Pascal Brandc639ac82015-07-02 08:53:34 +020025
26/* Round up the even multiple of size, size has to be a multiple of 2 */
27#define ROUNDUP(v, size) (((v) + (size - 1)) & ~(size - 1))
28
29TEEC_Context xtest_teec_ctx;
30
31TEEC_Result xtest_teec_ctx_init(void)
32{
33 return TEEC_InitializeContext(_device, &xtest_teec_ctx);
34}
35
36TEEC_Result xtest_teec_open_session(TEEC_Session *session,
37 const TEEC_UUID *uuid, TEEC_Operation *op,
38 uint32_t *ret_orig)
39{
40 return TEEC_OpenSession(&xtest_teec_ctx, session, uuid,
41 TEEC_LOGIN_PUBLIC, NULL, op, ret_orig);
42}
43
44void xtest_teec_ctx_deinit(void)
45{
46 TEEC_FinalizeContext(&xtest_teec_ctx);
47}
48
49TEEC_Result ta_crypt_cmd_allocate_operation(ADBG_Case_t *c, TEEC_Session *s,
50 TEE_OperationHandle *oph,
51 uint32_t algo, uint32_t mode,
52 uint32_t max_key_size)
53{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010054 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +020055 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010056 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020057
58 op.params[0].value.a = 0;
59 op.params[0].value.b = algo;
60 op.params[1].value.a = mode;
61 op.params[1].value.b = max_key_size;
62
63 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_VALUE_INPUT,
64 TEEC_NONE, TEEC_NONE);
65
66 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_OPERATION, &op,
67 &ret_orig);
68
69 if (res != TEEC_SUCCESS) {
70 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
71 ret_orig);
72 }
73
74 if (res == TEEC_SUCCESS)
75 *oph = (TEE_OperationHandle)(uintptr_t)op.params[0].value.a;
76
77 return res;
78}
79
80TEEC_Result ta_crypt_cmd_allocate_transient_object(ADBG_Case_t *c,
81 TEEC_Session *s,
82 TEE_ObjectType obj_type,
83 uint32_t max_obj_size,
84 TEE_ObjectHandle *o)
85{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010086 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +020087 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010088 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +020089
90 op.params[0].value.a = obj_type;
91 op.params[0].value.b = max_obj_size;
92
93 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
94 TEEC_NONE, TEEC_NONE);
95
96 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_TRANSIENT_OBJECT, &op,
97 &ret_orig);
98
99 if (res != TEEC_SUCCESS) {
100 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
101 ret_orig);
102 }
103
104 if (res == TEEC_SUCCESS)
105 *o = (TEE_ObjectHandle)(uintptr_t)op.params[1].value.a;
106
107 return res;
108}
109
110void xtest_add_attr(size_t *attr_count, TEE_Attribute *attrs, uint32_t attr_id,
111 const void *buf, size_t len)
112{
113 attrs[*attr_count].attributeID = attr_id;
114 attrs[*attr_count].content.ref.buffer = (void *)buf;
115 attrs[*attr_count].content.ref.length = len;
116 (*attr_count)++;
117}
118
Pascal Brande61133f2015-07-08 15:38:37 +0200119void xtest_add_attr_value(size_t *attr_count, TEE_Attribute *attrs,
120 uint32_t attr_id, uint32_t value_a, uint32_t value_b)
121{
122 attrs[*attr_count].attributeID = attr_id;
123 attrs[*attr_count].content.value.a = value_a;
124 attrs[*attr_count].content.value.b = value_b;
125 (*attr_count)++;
126}
127
Pascal Brandc639ac82015-07-02 08:53:34 +0200128struct tee_attr_packed {
129 uint32_t attr_id;
130 uint32_t a;
131 uint32_t b;
132};
133
134TEE_Result pack_attrs(const TEE_Attribute *attrs, uint32_t attr_count,
135 uint8_t **buf, size_t *blen)
136{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100137 struct tee_attr_packed *a = NULL;
138 uint8_t *b = NULL;
139 size_t bl = 0;
140 size_t n = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200141
142 *buf = NULL;
143 *blen = 0;
144 if (attr_count == 0)
145 return TEE_SUCCESS;
146
147 bl = sizeof(uint32_t) + sizeof(struct tee_attr_packed) * attr_count;
148 for (n = 0; n < attr_count; n++) {
149 if ((attrs[n].attributeID & TEE_ATTR_BIT_VALUE) != 0)
150 continue; /* Only memrefs need to be updated */
151
152 if (!attrs[n].content.ref.buffer)
153 continue;
154
155 /* Make room for padding */
156 bl += ROUNDUP(attrs[n].content.ref.length, 4);
157 }
158
159 b = calloc(1, bl);
160 if (!b)
161 return TEE_ERROR_OUT_OF_MEMORY;
162
163 *buf = b;
164 *blen = bl;
165
166 *(uint32_t *)(void *)b = attr_count;
167 b += sizeof(uint32_t);
168 a = (struct tee_attr_packed *)(void *)b;
169 b += sizeof(struct tee_attr_packed) * attr_count;
170
171 for (n = 0; n < attr_count; n++) {
172 a[n].attr_id = attrs[n].attributeID;
173 if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
174 a[n].a = attrs[n].content.value.a;
175 a[n].b = attrs[n].content.value.b;
176 continue;
177 }
178
179 a[n].b = attrs[n].content.ref.length;
180
181 if (!attrs[n].content.ref.buffer) {
182 a[n].a = 0;
183 continue;
184 }
185
186 memcpy(b, attrs[n].content.ref.buffer,
187 attrs[n].content.ref.length);
188
189 /* Make buffer pointer relative to *buf */
190 a[n].a = (uint32_t)(uintptr_t)(b - *buf);
191
192 /* Round up to good alignment */
193 b += ROUNDUP(attrs[n].content.ref.length, 4);
194 }
195
196 return TEE_SUCCESS;
197}
198
199TEEC_Result ta_crypt_cmd_populate_transient_object(ADBG_Case_t *c,
200 TEEC_Session *s,
201 TEE_ObjectHandle o,
202 const TEE_Attribute *attrs,
203 uint32_t attr_count)
204{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100205 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200206 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100207 uint32_t ret_orig = 0;
208 uint8_t *buf = NULL;
209 size_t blen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200210
211 res = pack_attrs(attrs, attr_count, &buf, &blen);
212 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
213 return res;
214
215 assert((uintptr_t)o <= UINT32_MAX);
216 op.params[0].value.a = (uint32_t)(uintptr_t)o;
217
218 op.params[1].tmpref.buffer = buf;
219 op.params[1].tmpref.size = blen;
220
221 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
222 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
223 TEEC_NONE);
224
225 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_POPULATE_TRANSIENT_OBJECT, &op,
226 &ret_orig);
227
Jens Wiklander70a0b2c2016-05-18 08:39:35 +0200228 if (res != TEEC_SUCCESS && res != TEEC_ERROR_TARGET_DEAD) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200229 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
230 ret_orig);
231 }
232
233 free(buf);
234 return res;
235}
236
237TEE_Result ta_crypt_cmd_set_operation_key(ADBG_Case_t *c, TEEC_Session *s,
238 TEE_OperationHandle oph,
239 TEE_ObjectHandle key)
240{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100241 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200242 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100243 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200244
245 assert((uintptr_t)oph <= UINT32_MAX);
246 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
247
248 assert((uintptr_t)key <= UINT32_MAX);
249 op.params[0].value.b = (uint32_t)(uintptr_t)key;
250
251 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
252 TEEC_NONE);
253
254 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_SET_OPERATION_KEY, &op,
255 &ret_orig);
256
257 if (res != TEEC_SUCCESS) {
258 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
259 ret_orig);
260 }
261
262 return res;
263}
264
265TEEC_Result ta_crypt_cmd_free_transient_object(ADBG_Case_t *c, TEEC_Session *s,
266 TEE_ObjectHandle o)
267{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100268 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200269 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100270 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200271
272 assert((uintptr_t)o <= UINT32_MAX);
273 op.params[0].value.a = (uint32_t)(uintptr_t)o;
274 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
275 TEEC_NONE);
276
277 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_TRANSIENT_OBJECT, &op,
278 &ret_orig);
279
280 if (res != TEEC_SUCCESS) {
281 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
282 ret_orig);
283 }
284
285 return res;
286}
287
288TEEC_Result ta_crypt_cmd_derive_key(ADBG_Case_t *c, TEEC_Session *s,
289 TEE_OperationHandle oph, TEE_ObjectHandle o,
290 const TEE_Attribute *params,
291 uint32_t paramCount)
292{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100293 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200294 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100295 uint32_t ret_orig = 0;
296 uint8_t *buf = NULL;
297 size_t blen = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200298
299 res = pack_attrs(params, paramCount, &buf, &blen);
300
301 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
302 return res;
303
304 assert((uintptr_t)oph <= UINT32_MAX);
305 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
306
307 assert((uintptr_t)o <= UINT32_MAX);
308 op.params[0].value.b = (uint32_t)(uintptr_t)o;
309
310 op.params[1].tmpref.buffer = buf;
311 op.params[1].tmpref.size = blen;
312
313 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
314 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
315 TEEC_NONE);
316
317 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_DERIVE_KEY, &op, &ret_orig);
318
319 if (res != TEEC_SUCCESS) {
320 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
321 ret_orig);
322 }
323
324 free(buf);
325 return res;
326}
327
328TEEC_Result ta_crypt_cmd_get_object_buffer_attribute(ADBG_Case_t *c,
329 TEEC_Session *s,
330 TEE_ObjectHandle o,
331 uint32_t attr_id,
332 void *buf, size_t *blen)
333{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100334 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200335 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100336 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200337
338 assert((uintptr_t)o <= UINT32_MAX);
339 op.params[0].value.a = (uint32_t)(uintptr_t)o;
340 op.params[0].value.b = attr_id;
341
342 op.params[1].tmpref.buffer = buf;
343 op.params[1].tmpref.size = *blen;
344
345 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
346 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE,
347 TEEC_NONE);
348
349 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_GET_OBJECT_BUFFER_ATTRIBUTE,
350 &op, &ret_orig);
351
352 if (res != TEEC_SUCCESS) {
353 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
354 ret_orig);
355 }
356
357 if (res == TEEC_SUCCESS)
358 *blen = op.params[1].tmpref.size;
359
360 return res;
361}
362
363TEEC_Result ta_crypt_cmd_free_operation(ADBG_Case_t *c, TEEC_Session *s,
364 TEE_OperationHandle oph)
365{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100366 TEEC_Result res = TEEC_ERROR_GENERIC;
Pascal Brandc639ac82015-07-02 08:53:34 +0200367 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100368 uint32_t ret_orig = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200369
370 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
371
372 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
373 TEEC_NONE);
374
375 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_OPERATION, &op,
376 &ret_orig);
377
378 if (res != TEEC_SUCCESS) {
379 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
380 ret_orig);
381 }
382
383 return res;
384}
Jerome Forissiere3854162016-08-12 12:40:12 +0200385
Jerome Forissier6635c962020-01-22 17:49:00 +0100386bool ta_crypt_cmd_is_algo_supported(ADBG_Case_t *c, TEEC_Session *s,
387 uint32_t algo, uint32_t element)
388{
389 TEEC_Result res = TEEC_ERROR_GENERIC;
390 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
391 uint32_t ret_orig = 0;
392 TEEC_Result st = TEEC_ERROR_GENERIC;
393
394 op.params[0].value.a = algo;
395 op.params[0].value.b = element;
396
397 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
398 TEEC_NONE, TEEC_NONE);
399
400 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_IS_ALGO_SUPPORTED, &op,
401 &ret_orig);
402 if (res != TEEC_SUCCESS) {
403 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
404 ret_orig);
405 return res;
406 }
407
408 st = op.params[1].value.a;
409 ADBG_EXPECT_TRUE(c, st == TEEC_SUCCESS ||
410 st == TEEC_ERROR_NOT_SUPPORTED);
411 if (st == TEE_SUCCESS)
412 return true;
413 return false;
414}
415
Jens Wiklandere2ca6062016-12-21 14:00:30 +0100416void xtest_mutex_init(pthread_mutex_t *mutex)
417{
418 int e = pthread_mutex_init(mutex, NULL);
419
420 if (e)
421 errx(1, "pthread_mutex_init: %s", strerror(e));
422}
423
424void xtest_mutex_destroy(pthread_mutex_t *mutex)
425{
426 int e = pthread_mutex_destroy(mutex);
427
428 if (e)
429 errx(1, "pthread_mutex_destroy: %s", strerror(e));
430}
431
432void xtest_mutex_lock(pthread_mutex_t *mutex)
433{
434 int e = pthread_mutex_lock(mutex);
435
436 if (e)
437 errx(1, "pthread_mutex_lock: %s", strerror(e));
438}
439
440void xtest_mutex_unlock(pthread_mutex_t *mutex)
441{
442 int e = pthread_mutex_unlock(mutex);
443
444 if (e)
445 errx(1, "pthread_mutex_unlock: %s", strerror(e));
446}
447
448void xtest_barrier_init(pthread_barrier_t *barrier, unsigned count)
449{
450 int e = pthread_barrier_init(barrier, NULL, count);
451
452 if (e)
453 errx(1, "pthread_barrier_init: %s", strerror(e));
454}
455
456void xtest_barrier_destroy(pthread_barrier_t *barrier)
457{
458 int e = pthread_barrier_destroy(barrier);
459
460 if (e)
461 errx(1, "pthread_barrier_destroy: %s", strerror(e));
462}
463
464int xtest_barrier_wait(pthread_barrier_t *barrier)
465{
466 int e = pthread_barrier_wait(barrier);
467
468 if (e && e != PTHREAD_BARRIER_SERIAL_THREAD)
469 errx(1, "pthread _barrier_wait: %s", strerror(e));
470 return e;
471}