blob: 879bf4853c3c95ea9c2807261b3e18ec7205be35 [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{
54 TEEC_Result res;
55 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
56 uint32_t ret_orig;
57
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{
86 TEEC_Result res;
87 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
88 uint32_t ret_orig;
89
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{
137 struct tee_attr_packed *a;
138 uint8_t *b;
139 size_t bl;
140 size_t n;
141
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{
205 TEEC_Result res;
206 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
207 uint32_t ret_orig;
208 uint8_t *buf;
209 size_t blen;
210
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{
241 TEEC_Result res;
242 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
243 uint32_t ret_orig;
244
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{
268 TEEC_Result res;
269 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
270 uint32_t ret_orig;
271
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{
293 TEEC_Result res;
294 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
295 uint32_t ret_orig;
296 uint8_t *buf;
297 size_t blen;
298
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{
334 TEEC_Result res;
335 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
336 uint32_t ret_orig;
337
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{
366 TEEC_Result res;
367 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
368 uint32_t ret_orig;
369
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
386#define SWAP_BYTES_16(w16) ((((w16) & 0xFF00) >> 8) | (((w16) & 0xFF) << 8))
387#define SWAP_BYTES_32(w32) ((((w32) & 0xFF000000) >> 24) |\
388 (((w32) & 0xFF0000) >> 8) |\
389 (((w32) & 0xFF00) << 8) |\
390 (((w32) & 0xFF) << 24))
391
392int ree_fs_get_ta_dirname(TEEC_UUID *p_uuid, char *buffer, uint32_t len)
393{
394
395 if (p_uuid == NULL || buffer == NULL)
396 return 0;
397
398 return snprintf(buffer, len,
399 "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
400 SWAP_BYTES_32(p_uuid->timeLow),
401 SWAP_BYTES_16(p_uuid->timeMid),
402 SWAP_BYTES_16(p_uuid->timeHiAndVersion),
403 p_uuid->clockSeqAndNode[0],
404 p_uuid->clockSeqAndNode[1],
405 p_uuid->clockSeqAndNode[2],
406 p_uuid->clockSeqAndNode[3],
407 p_uuid->clockSeqAndNode[4],
408 p_uuid->clockSeqAndNode[5],
409 p_uuid->clockSeqAndNode[6],
410 p_uuid->clockSeqAndNode[7]);
411}
Jens Wiklandere2ca6062016-12-21 14:00:30 +0100412
413
414void xtest_mutex_init(pthread_mutex_t *mutex)
415{
416 int e = pthread_mutex_init(mutex, NULL);
417
418 if (e)
419 errx(1, "pthread_mutex_init: %s", strerror(e));
420}
421
422void xtest_mutex_destroy(pthread_mutex_t *mutex)
423{
424 int e = pthread_mutex_destroy(mutex);
425
426 if (e)
427 errx(1, "pthread_mutex_destroy: %s", strerror(e));
428}
429
430void xtest_mutex_lock(pthread_mutex_t *mutex)
431{
432 int e = pthread_mutex_lock(mutex);
433
434 if (e)
435 errx(1, "pthread_mutex_lock: %s", strerror(e));
436}
437
438void xtest_mutex_unlock(pthread_mutex_t *mutex)
439{
440 int e = pthread_mutex_unlock(mutex);
441
442 if (e)
443 errx(1, "pthread_mutex_unlock: %s", strerror(e));
444}
445
446void xtest_barrier_init(pthread_barrier_t *barrier, unsigned count)
447{
448 int e = pthread_barrier_init(barrier, NULL, count);
449
450 if (e)
451 errx(1, "pthread_barrier_init: %s", strerror(e));
452}
453
454void xtest_barrier_destroy(pthread_barrier_t *barrier)
455{
456 int e = pthread_barrier_destroy(barrier);
457
458 if (e)
459 errx(1, "pthread_barrier_destroy: %s", strerror(e));
460}
461
462int xtest_barrier_wait(pthread_barrier_t *barrier)
463{
464 int e = pthread_barrier_wait(barrier);
465
466 if (e && e != PTHREAD_BARRIER_SERIAL_THREAD)
467 errx(1, "pthread _barrier_wait: %s", strerror(e));
468 return e;
469}