blob: 51b1c191d46faab0c333323bb6c854c64f66dd3d [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
118struct tee_attr_packed {
119 uint32_t attr_id;
120 uint32_t a;
121 uint32_t b;
122};
123
124TEE_Result pack_attrs(const TEE_Attribute *attrs, uint32_t attr_count,
125 uint8_t **buf, size_t *blen)
126{
127 struct tee_attr_packed *a;
128 uint8_t *b;
129 size_t bl;
130 size_t n;
131
132 *buf = NULL;
133 *blen = 0;
134 if (attr_count == 0)
135 return TEE_SUCCESS;
136
137 bl = sizeof(uint32_t) + sizeof(struct tee_attr_packed) * attr_count;
138 for (n = 0; n < attr_count; n++) {
139 if ((attrs[n].attributeID & TEE_ATTR_BIT_VALUE) != 0)
140 continue; /* Only memrefs need to be updated */
141
142 if (!attrs[n].content.ref.buffer)
143 continue;
144
145 /* Make room for padding */
146 bl += ROUNDUP(attrs[n].content.ref.length, 4);
147 }
148
149 b = calloc(1, bl);
150 if (!b)
151 return TEE_ERROR_OUT_OF_MEMORY;
152
153 *buf = b;
154 *blen = bl;
155
156 *(uint32_t *)(void *)b = attr_count;
157 b += sizeof(uint32_t);
158 a = (struct tee_attr_packed *)(void *)b;
159 b += sizeof(struct tee_attr_packed) * attr_count;
160
161 for (n = 0; n < attr_count; n++) {
162 a[n].attr_id = attrs[n].attributeID;
163 if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
164 a[n].a = attrs[n].content.value.a;
165 a[n].b = attrs[n].content.value.b;
166 continue;
167 }
168
169 a[n].b = attrs[n].content.ref.length;
170
171 if (!attrs[n].content.ref.buffer) {
172 a[n].a = 0;
173 continue;
174 }
175
176 memcpy(b, attrs[n].content.ref.buffer,
177 attrs[n].content.ref.length);
178
179 /* Make buffer pointer relative to *buf */
180 a[n].a = (uint32_t)(uintptr_t)(b - *buf);
181
182 /* Round up to good alignment */
183 b += ROUNDUP(attrs[n].content.ref.length, 4);
184 }
185
186 return TEE_SUCCESS;
187}
188
189TEEC_Result ta_crypt_cmd_populate_transient_object(ADBG_Case_t *c,
190 TEEC_Session *s,
191 TEE_ObjectHandle o,
192 const TEE_Attribute *attrs,
193 uint32_t attr_count)
194{
195 TEEC_Result res;
196 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
197 uint32_t ret_orig;
198 uint8_t *buf;
199 size_t blen;
200
201 res = pack_attrs(attrs, attr_count, &buf, &blen);
202 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
203 return res;
204
205 assert((uintptr_t)o <= UINT32_MAX);
206 op.params[0].value.a = (uint32_t)(uintptr_t)o;
207
208 op.params[1].tmpref.buffer = buf;
209 op.params[1].tmpref.size = blen;
210
211 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
212 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
213 TEEC_NONE);
214
215 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_POPULATE_TRANSIENT_OBJECT, &op,
216 &ret_orig);
217
218 if (res != TEEC_SUCCESS) {
219 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
220 ret_orig);
221 }
222
223 free(buf);
224 return res;
225}
226
227TEE_Result ta_crypt_cmd_set_operation_key(ADBG_Case_t *c, TEEC_Session *s,
228 TEE_OperationHandle oph,
229 TEE_ObjectHandle key)
230{
231 TEEC_Result res;
232 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
233 uint32_t ret_orig;
234
235 assert((uintptr_t)oph <= UINT32_MAX);
236 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
237
238 assert((uintptr_t)key <= UINT32_MAX);
239 op.params[0].value.b = (uint32_t)(uintptr_t)key;
240
241 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
242 TEEC_NONE);
243
244 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_SET_OPERATION_KEY, &op,
245 &ret_orig);
246
247 if (res != TEEC_SUCCESS) {
248 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
249 ret_orig);
250 }
251
252 return res;
253}
254
255TEEC_Result ta_crypt_cmd_free_transient_object(ADBG_Case_t *c, TEEC_Session *s,
256 TEE_ObjectHandle o)
257{
258 TEEC_Result res;
259 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
260 uint32_t ret_orig;
261
262 assert((uintptr_t)o <= UINT32_MAX);
263 op.params[0].value.a = (uint32_t)(uintptr_t)o;
264 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
265 TEEC_NONE);
266
267 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_TRANSIENT_OBJECT, &op,
268 &ret_orig);
269
270 if (res != TEEC_SUCCESS) {
271 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
272 ret_orig);
273 }
274
275 return res;
276}
277
278TEEC_Result ta_crypt_cmd_derive_key(ADBG_Case_t *c, TEEC_Session *s,
279 TEE_OperationHandle oph, TEE_ObjectHandle o,
280 const TEE_Attribute *params,
281 uint32_t paramCount)
282{
283 TEEC_Result res;
284 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
285 uint32_t ret_orig;
286 uint8_t *buf;
287 size_t blen;
288
289 res = pack_attrs(params, paramCount, &buf, &blen);
290
291 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
292 return res;
293
294 assert((uintptr_t)oph <= UINT32_MAX);
295 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
296
297 assert((uintptr_t)o <= UINT32_MAX);
298 op.params[0].value.b = (uint32_t)(uintptr_t)o;
299
300 op.params[1].tmpref.buffer = buf;
301 op.params[1].tmpref.size = blen;
302
303 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
304 TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
305 TEEC_NONE);
306
307 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_DERIVE_KEY, &op, &ret_orig);
308
309 if (res != TEEC_SUCCESS) {
310 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
311 ret_orig);
312 }
313
314 free(buf);
315 return res;
316}
317
318TEEC_Result ta_crypt_cmd_get_object_buffer_attribute(ADBG_Case_t *c,
319 TEEC_Session *s,
320 TEE_ObjectHandle o,
321 uint32_t attr_id,
322 void *buf, size_t *blen)
323{
324 TEEC_Result res;
325 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
326 uint32_t ret_orig;
327
328 assert((uintptr_t)o <= UINT32_MAX);
329 op.params[0].value.a = (uint32_t)(uintptr_t)o;
330 op.params[0].value.b = attr_id;
331
332 op.params[1].tmpref.buffer = buf;
333 op.params[1].tmpref.size = *blen;
334
335 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
336 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE,
337 TEEC_NONE);
338
339 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_GET_OBJECT_BUFFER_ATTRIBUTE,
340 &op, &ret_orig);
341
342 if (res != TEEC_SUCCESS) {
343 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
344 ret_orig);
345 }
346
347 if (res == TEEC_SUCCESS)
348 *blen = op.params[1].tmpref.size;
349
350 return res;
351}
352
353TEEC_Result ta_crypt_cmd_free_operation(ADBG_Case_t *c, TEEC_Session *s,
354 TEE_OperationHandle oph)
355{
356 TEEC_Result res;
357 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
358 uint32_t ret_orig;
359
360 op.params[0].value.a = (uint32_t)(uintptr_t)oph;
361
362 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE,
363 TEEC_NONE);
364
365 res = TEEC_InvokeCommand(s, TA_CRYPT_CMD_FREE_OPERATION, &op,
366 &ret_orig);
367
368 if (res != TEEC_SUCCESS) {
369 (void)ADBG_EXPECT_TEEC_ERROR_ORIGIN(c, TEEC_ORIGIN_TRUSTED_APP,
370 ret_orig);
371 }
372
373 return res;
374}