blob: 7a91acd432d410976b4eb0b2f24054e7d0ae88fa [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
14#include "xtest_helpers.h"
15#include "xtest_test.h"
16
17#include <ta_crypt.h>
18#include <utee_defines.h>
19
20#include <string.h>
21#include <stdio.h>
22#include <malloc.h>
23#include <assert.h>
24
25/* Round up the even multiple of size, size has to be a multiple of 2 */
26#define ROUNDUP(v, size) (((v) + (size - 1)) & ~(size - 1))
27
28TEEC_Context xtest_teec_ctx;
29
30TEEC_Result xtest_teec_ctx_init(void)
31{
32 return TEEC_InitializeContext(_device, &xtest_teec_ctx);
33}
34
35TEEC_Result xtest_teec_open_session(TEEC_Session *session,
36 const TEEC_UUID *uuid, TEEC_Operation *op,
37 uint32_t *ret_orig)
38{
39 return TEEC_OpenSession(&xtest_teec_ctx, session, uuid,
40 TEEC_LOGIN_PUBLIC, NULL, op, ret_orig);
41}
42
43void xtest_teec_ctx_deinit(void)
44{
45 TEEC_FinalizeContext(&xtest_teec_ctx);
46}
47
48TEEC_Result ta_crypt_cmd_allocate_operation(ADBG_Case_t *c, TEEC_Session *s,
49 TEE_OperationHandle *oph,
50 uint32_t algo, uint32_t mode,
51 uint32_t max_key_size)
52{
53 TEEC_Result res;
54 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
55 uint32_t ret_orig;
56
57 op.params[0].value.a = 0;
58 op.params[0].value.b = algo;
59 op.params[1].value.a = mode;
60 op.params[1].value.b = max_key_size;
61
62 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_VALUE_INPUT,
63 TEEC_NONE, TEEC_NONE);
64
65 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_OPERATION, &op,
66 &ret_orig);
67
68 if (res != TEEC_SUCCESS) {
69 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
70 ret_orig);
71 }
72
73 if (res == TEEC_SUCCESS)
74 *oph = (TEE_OperationHandle)(uintptr_t)op.params[0].value.a;
75
76 return res;
77}
78
79TEEC_Result ta_crypt_cmd_allocate_transient_object(ADBG_Case_t *c,
80 TEEC_Session *s,
81 TEE_ObjectType obj_type,
82 uint32_t max_obj_size,
83 TEE_ObjectHandle *o)
84{
85 TEEC_Result res;
86 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
87 uint32_t ret_orig;
88
89 op.params[0].value.a = obj_type;
90 op.params[0].value.b = max_obj_size;
91
92 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
93 TEEC_NONE, TEEC_NONE);
94
95 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_ALLOCATE_TRANSIENT_OBJECT, &op,
96 &ret_orig);
97
98 if (res != TEEC_SUCCESS) {
99 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
100 ret_orig);
101 }
102
103 if (res == TEEC_SUCCESS)
104 *o = (TEE_ObjectHandle)(uintptr_t)op.params[1].value.a;
105
106 return res;
107}
108
109void xtest_add_attr(size_t *attr_count, TEE_Attribute *attrs, uint32_t attr_id,
110 const void *buf, size_t len)
111{
112 attrs[*attr_count].attributeID = attr_id;
113 attrs[*attr_count].content.ref.buffer = (void *)buf;
114 attrs[*attr_count].content.ref.length = len;
115 (*attr_count)++;
116}
117
Pascal Brande61133f2015-07-08 15:38:37 +0200118void xtest_add_attr_value(size_t *attr_count, TEE_Attribute *attrs,
119 uint32_t attr_id, uint32_t value_a, uint32_t value_b)
120{
121 attrs[*attr_count].attributeID = attr_id;
122 attrs[*attr_count].content.value.a = value_a;
123 attrs[*attr_count].content.value.b = value_b;
124 (*attr_count)++;
125}
126
Pascal Brandc639ac82015-07-02 08:53:34 +0200127struct tee_attr_packed {
128 uint32_t attr_id;
129 uint32_t a;
130 uint32_t b;
131};
132
133TEE_Result pack_attrs(const TEE_Attribute *attrs, uint32_t attr_count,
134 uint8_t **buf, size_t *blen)
135{
136 struct tee_attr_packed *a;
137 uint8_t *b;
138 size_t bl;
139 size_t n;
140
141 *buf = NULL;
142 *blen = 0;
143 if (attr_count == 0)
144 return TEE_SUCCESS;
145
146 bl = sizeof(uint32_t) + sizeof(struct tee_attr_packed) * attr_count;
147 for (n = 0; n < attr_count; n++) {
148 if ((attrs[n].attributeID & TEE_ATTR_BIT_VALUE) != 0)
149 continue; /* Only memrefs need to be updated */
150
151 if (!attrs[n].content.ref.buffer)
152 continue;
153
154 /* Make room for padding */
155 bl += ROUNDUP(attrs[n].content.ref.length, 4);
156 }
157
158 b = calloc(1, bl);
159 if (!b)
160 return TEE_ERROR_OUT_OF_MEMORY;
161
162 *buf = b;
163 *blen = bl;
164
165 *(uint32_t *)(void *)b = attr_count;
166 b += sizeof(uint32_t);
167 a = (struct tee_attr_packed *)(void *)b;
168 b += sizeof(struct tee_attr_packed) * attr_count;
169
170 for (n = 0; n < attr_count; n++) {
171 a[n].attr_id = attrs[n].attributeID;
172 if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
173 a[n].a = attrs[n].content.value.a;
174 a[n].b = attrs[n].content.value.b;
175 continue;
176 }
177
178 a[n].b = attrs[n].content.ref.length;
179
180 if (!attrs[n].content.ref.buffer) {
181 a[n].a = 0;
182 continue;
183 }
184
185 memcpy(b, attrs[n].content.ref.buffer,
186 attrs[n].content.ref.length);
187
188 /* Make buffer pointer relative to *buf */
189 a[n].a = (uint32_t)(uintptr_t)(b - *buf);
190
191 /* Round up to good alignment */
192 b += ROUNDUP(attrs[n].content.ref.length, 4);
193 }
194
195 return TEE_SUCCESS;
196}
197
198TEEC_Result ta_crypt_cmd_populate_transient_object(ADBG_Case_t *c,
199 TEEC_Session *s,
200 TEE_ObjectHandle o,
201 const TEE_Attribute *attrs,
202 uint32_t attr_count)
203{
204 TEEC_Result res;
205 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
206 uint32_t ret_orig;
207 uint8_t *buf;
208 size_t blen;
209
210 res = pack_attrs(attrs, attr_count, &buf, &blen);
211 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
212 return res;
213
214 assert((uintptr_t)o <= UINT32_MAX);
215 op.params[0].value.a = (uint32_t)(uintptr_t)o;
216
217 op.params[1].tmpref.buffer = buf;
218 op.params[1].tmpref.size = blen;
219
220 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
221 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
222 TEEC_NONE);
223
224 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_POPULATE_TRANSIENT_OBJECT, &op,
225 &ret_orig);
226
Jens Wiklander70a0b2c2016-05-18 08:39:35 +0200227 if (res != TEEC_SUCCESS && res != TEEC_ERROR_TARGET_DEAD) {
Pascal Brandc639ac82015-07-02 08:53:34 +0200228 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
229 ret_orig);
230 }
231
232 free(buf);
233 return res;
234}
235
236TEE_Result ta_crypt_cmd_set_operation_key(ADBG_Case_t *c, TEEC_Session *s,
237 TEE_OperationHandle oph,
238 TEE_ObjectHandle key)
239{
240 TEEC_Result res;
241 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
242 uint32_t ret_orig;
243
244 assert((uintptr_t)oph <= UINT32_MAX);
245 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
246
247 assert((uintptr_t)key <= UINT32_MAX);
248 op.params[0].value.b = (uint32_t)(uintptr_t)key;
249
250 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
251 TEEC_NONE);
252
253 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_SET_OPERATION_KEY, &op,
254 &ret_orig);
255
256 if (res != TEEC_SUCCESS) {
257 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
258 ret_orig);
259 }
260
261 return res;
262}
263
264TEEC_Result ta_crypt_cmd_free_transient_object(ADBG_Case_t *c, TEEC_Session *s,
265 TEE_ObjectHandle o)
266{
267 TEEC_Result res;
268 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
269 uint32_t ret_orig;
270
271 assert((uintptr_t)o <= UINT32_MAX);
272 op.params[0].value.a = (uint32_t)(uintptr_t)o;
273 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
274 TEEC_NONE);
275
276 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_TRANSIENT_OBJECT, &op,
277 &ret_orig);
278
279 if (res != TEEC_SUCCESS) {
280 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
281 ret_orig);
282 }
283
284 return res;
285}
286
287TEEC_Result ta_crypt_cmd_derive_key(ADBG_Case_t *c, TEEC_Session *s,
288 TEE_OperationHandle oph, TEE_ObjectHandle o,
289 const TEE_Attribute *params,
290 uint32_t paramCount)
291{
292 TEEC_Result res;
293 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
294 uint32_t ret_orig;
295 uint8_t *buf;
296 size_t blen;
297
298 res = pack_attrs(params, paramCount, &buf, &blen);
299
300 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
301 return res;
302
303 assert((uintptr_t)oph <= UINT32_MAX);
304 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
305
306 assert((uintptr_t)o <= UINT32_MAX);
307 op.params[0].value.b = (uint32_t)(uintptr_t)o;
308
309 op.params[1].tmpref.buffer = buf;
310 op.params[1].tmpref.size = blen;
311
312 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
313 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
314 TEEC_NONE);
315
316 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_DERIVE_KEY, &op, &ret_orig);
317
318 if (res != TEEC_SUCCESS) {
319 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
320 ret_orig);
321 }
322
323 free(buf);
324 return res;
325}
326
327TEEC_Result ta_crypt_cmd_get_object_buffer_attribute(ADBG_Case_t *c,
328 TEEC_Session *s,
329 TEE_ObjectHandle o,
330 uint32_t attr_id,
331 void *buf, size_t *blen)
332{
333 TEEC_Result res;
334 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
335 uint32_t ret_orig;
336
337 assert((uintptr_t)o <= UINT32_MAX);
338 op.params[0].value.a = (uint32_t)(uintptr_t)o;
339 op.params[0].value.b = attr_id;
340
341 op.params[1].tmpref.buffer = buf;
342 op.params[1].tmpref.size = *blen;
343
344 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
345 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE,
346 TEEC_NONE);
347
348 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_GET_OBJECT_BUFFER_ATTRIBUTE,
349 &op, &ret_orig);
350
351 if (res != TEEC_SUCCESS) {
352 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
353 ret_orig);
354 }
355
356 if (res == TEEC_SUCCESS)
357 *blen = op.params[1].tmpref.size;
358
359 return res;
360}
361
362TEEC_Result ta_crypt_cmd_free_operation(ADBG_Case_t *c, TEEC_Session *s,
363 TEE_OperationHandle oph)
364{
365 TEEC_Result res;
366 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
367 uint32_t ret_orig;
368
369 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
370
371 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
372 TEEC_NONE);
373
374 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_OPERATION, &op,
375 &ret_orig);
376
377 if (res != TEEC_SUCCESS) {
378 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
379 ret_orig);
380 }
381
382 return res;
383}
Jerome Forissiere3854162016-08-12 12:40:12 +0200384
385#define SWAP_BYTES_16(w16) ((((w16) & 0xFF00) >> 8) | (((w16) & 0xFF) << 8))
386#define SWAP_BYTES_32(w32) ((((w32) & 0xFF000000) >> 24) |\
387 (((w32) & 0xFF0000) >> 8) |\
388 (((w32) & 0xFF00) << 8) |\
389 (((w32) & 0xFF) << 24))
390
391int ree_fs_get_ta_dirname(TEEC_UUID *p_uuid, char *buffer, uint32_t len)
392{
393
394 if (p_uuid == NULL || buffer == NULL)
395 return 0;
396
397 return snprintf(buffer, len,
398 "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
399 SWAP_BYTES_32(p_uuid->timeLow),
400 SWAP_BYTES_16(p_uuid->timeMid),
401 SWAP_BYTES_16(p_uuid->timeHiAndVersion),
402 p_uuid->clockSeqAndNode[0],
403 p_uuid->clockSeqAndNode[1],
404 p_uuid->clockSeqAndNode[2],
405 p_uuid->clockSeqAndNode[3],
406 p_uuid->clockSeqAndNode[4],
407 p_uuid->clockSeqAndNode[5],
408 p_uuid->clockSeqAndNode[6],
409 p_uuid->clockSeqAndNode[7]);
410}