blob: 2be171e6ec85363c5313ecf4db49557b97d7ac09 [file] [log] [blame]
Pascal Brandc639ac82015-07-02 08:53:34 +02001/*
2 * Copyright (c) 2014, STMicroelectronics International N.V.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "storage.h"
29
30#include <tee_api.h>
Pascal Brand90f23352016-05-19 15:15:47 +020031#include <trace.h>
Pascal Brandc639ac82015-07-02 08:53:34 +020032
33#define ASSERT_PARAM_TYPE(pt) \
34do { \
35 if ((pt) != param_types) \
36 return TEE_ERROR_BAD_PARAMETERS; \
37} while (0)
38
Jens Wiklanderc5231592015-11-11 09:27:27 +010039#define VAL2HANDLE(v) (void *)(uintptr_t)(v)
40
Pascal Brandc639ac82015-07-02 08:53:34 +020041TEE_Result ta_storage_cmd_open(uint32_t param_types, TEE_Param params[4])
42{
Jens Wiklanderc5231592015-11-11 09:27:27 +010043 TEE_Result res;
44 TEE_ObjectHandle o;
45
Pascal Brandc639ac82015-07-02 08:53:34 +020046 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
47 (TEE_PARAM_TYPE_MEMREF_INPUT,
48 TEE_PARAM_TYPE_VALUE_INOUT, TEE_PARAM_TYPE_NONE,
49 TEE_PARAM_TYPE_NONE));
50
Jens Wiklanderc5231592015-11-11 09:27:27 +010051 res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
Pascal Brandc639ac82015-07-02 08:53:34 +020052 params[0].memref.buffer,
53 params[0].memref.size,
Jens Wiklanderc5231592015-11-11 09:27:27 +010054 params[1].value.a, &o);
55
56 params[1].value.b = (uintptr_t)o;
57 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +020058}
59
60TEE_Result ta_storage_cmd_create(uint32_t param_types, TEE_Param params[4])
61{
Jens Wiklanderc5231592015-11-11 09:27:27 +010062 TEE_Result res;
63 TEE_ObjectHandle o;
64
Pascal Brandc639ac82015-07-02 08:53:34 +020065 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
66 (TEE_PARAM_TYPE_MEMREF_INPUT,
67 TEE_PARAM_TYPE_VALUE_INOUT,
68 TEE_PARAM_TYPE_VALUE_INPUT,
69 TEE_PARAM_TYPE_MEMREF_INPUT));
70
Jens Wiklanderc5231592015-11-11 09:27:27 +010071 res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
72 params[0].memref.buffer, params[0].memref.size,
73 params[1].value.a,
74 (TEE_ObjectHandle)(uintptr_t)params[2].value.a,
75 params[3].memref.buffer, params[3].memref.size, &o);
76 params[1].value.b = (uintptr_t)o;
77 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +020078}
79
Pascal Brandeb84c442016-04-19 17:49:49 +020080TEE_Result ta_storage_cmd_create_overwrite(uint32_t param_types,
81 TEE_Param params[4])
82{
83 TEE_Result res;
84
85 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
86 (TEE_PARAM_TYPE_MEMREF_INPUT,
87 TEE_PARAM_TYPE_NONE,
88 TEE_PARAM_TYPE_NONE,
89 TEE_PARAM_TYPE_NONE));
90
91 res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
92 params[0].memref.buffer, params[0].memref.size,
93 TEE_DATA_FLAG_OVERWRITE,
94 NULL, NULL, 0, NULL);
95 return res;
96}
97
Pascal Brandc639ac82015-07-02 08:53:34 +020098TEE_Result ta_storage_cmd_close(uint32_t param_types, TEE_Param params[4])
99{
100 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
101 (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
102 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
103
Jens Wiklanderc5231592015-11-11 09:27:27 +0100104 TEE_CloseObject((TEE_ObjectHandle)(uintptr_t)params[0].value.a);
Pascal Brandc639ac82015-07-02 08:53:34 +0200105
106 return TEE_SUCCESS;
107}
108
109TEE_Result ta_storage_cmd_read(uint32_t param_types, TEE_Param params[4])
110{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100111 TEE_ObjectHandle o = VAL2HANDLE(params[1].value.a);
112
Pascal Brandc639ac82015-07-02 08:53:34 +0200113 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
114 (TEE_PARAM_TYPE_MEMREF_OUTPUT,
115 TEE_PARAM_TYPE_VALUE_INOUT, TEE_PARAM_TYPE_NONE,
116 TEE_PARAM_TYPE_NONE));
117
Jens Wiklanderc5231592015-11-11 09:27:27 +0100118 return TEE_ReadObjectData(o, params[0].memref.buffer,
Pascal Brandc639ac82015-07-02 08:53:34 +0200119 params[0].memref.size, &params[1].value.b);
120}
121
122TEE_Result ta_storage_cmd_write(uint32_t param_types, TEE_Param params[4])
123{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100124 TEE_ObjectHandle o = VAL2HANDLE(params[1].value.a);
125
Pascal Brandc639ac82015-07-02 08:53:34 +0200126 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
127 (TEE_PARAM_TYPE_MEMREF_INPUT,
128 TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
129 TEE_PARAM_TYPE_NONE));
130
Jens Wiklanderc5231592015-11-11 09:27:27 +0100131 return TEE_WriteObjectData(o, params[0].memref.buffer,
Pascal Brandc639ac82015-07-02 08:53:34 +0200132 params[0].memref.size);
133}
134
135TEE_Result ta_storage_cmd_seek(uint32_t param_types, TEE_Param params[4])
136{
137 TEE_Result res;
138 TEE_ObjectInfo info;
Jens Wiklanderc5231592015-11-11 09:27:27 +0100139 TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
Pascal Brandc639ac82015-07-02 08:53:34 +0200140
141 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
142 (TEE_PARAM_TYPE_VALUE_INPUT,
143 TEE_PARAM_TYPE_VALUE_INOUT, TEE_PARAM_TYPE_NONE,
144 TEE_PARAM_TYPE_NONE));
145
Jens Wiklanderc5231592015-11-11 09:27:27 +0100146 res = TEE_SeekObjectData(o, params[0].value.b, params[1].value.a);
147 if (res != TEE_SUCCESS)
148 return res;
149 res = TEE_GetObjectInfo1(o, &info);
Pascal Brandc639ac82015-07-02 08:53:34 +0200150
151 params[1].value.b = info.dataPosition;
152
153 return res;
154}
155
156TEE_Result ta_storage_cmd_unlink(uint32_t param_types, TEE_Param params[4])
157{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100158 TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
159
Pascal Brandc639ac82015-07-02 08:53:34 +0200160 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
161 (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
162 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
163
Jens Wiklanderc5231592015-11-11 09:27:27 +0100164 TEE_CloseAndDeletePersistentObject1(o);
Pascal Brandc639ac82015-07-02 08:53:34 +0200165
166 return TEE_SUCCESS;
167}
168
169TEE_Result ta_storage_cmd_rename(uint32_t param_types, TEE_Param params[4])
170{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100171 TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
172
Pascal Brandc639ac82015-07-02 08:53:34 +0200173 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
174 (TEE_PARAM_TYPE_VALUE_INPUT,
175 TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE,
176 TEE_PARAM_TYPE_NONE));
177
Jens Wiklanderc5231592015-11-11 09:27:27 +0100178 return TEE_RenamePersistentObject(o, params[1].memref.buffer,
Pascal Brandc639ac82015-07-02 08:53:34 +0200179 params[1].memref.size);
180}
181
182TEE_Result ta_storage_cmd_trunc(uint32_t param_types, TEE_Param params[4])
183{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100184 TEE_ObjectHandle o = VAL2HANDLE(params[0].value.a);
185
Pascal Brandc639ac82015-07-02 08:53:34 +0200186 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
187 (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
188 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
189
Jens Wiklanderc5231592015-11-11 09:27:27 +0100190 return TEE_TruncateObjectData(o, params[0].value.b);
Pascal Brandc639ac82015-07-02 08:53:34 +0200191}
192
193TEE_Result ta_storage_cmd_alloc_enum(uint32_t param_types, TEE_Param params[4])
194{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100195 TEE_Result res;
196 TEE_ObjectEnumHandle oe;
197
Pascal Brandc639ac82015-07-02 08:53:34 +0200198 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
199 (TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE,
200 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
201
Jens Wiklanderc5231592015-11-11 09:27:27 +0100202 res = TEE_AllocatePersistentObjectEnumerator(&oe);
203 params[0].value.a = (uintptr_t)oe;
204 return res;
Pascal Brandc639ac82015-07-02 08:53:34 +0200205}
206
207TEE_Result ta_storage_cmd_free_enum(uint32_t param_types, TEE_Param params[4])
208{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100209 TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
210
Pascal Brandc639ac82015-07-02 08:53:34 +0200211 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
212 (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
213 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
214
Jens Wiklanderc5231592015-11-11 09:27:27 +0100215 TEE_FreePersistentObjectEnumerator(oe);
Pascal Brandc639ac82015-07-02 08:53:34 +0200216 return TEE_SUCCESS;
217}
218
219TEE_Result ta_storage_cmd_reset_enum(uint32_t param_types, TEE_Param params[4])
220{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100221 TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
222
Pascal Brandc639ac82015-07-02 08:53:34 +0200223 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
224 (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
225 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
226
Jens Wiklanderc5231592015-11-11 09:27:27 +0100227 TEE_ResetPersistentObjectEnumerator(oe);
Pascal Brandc639ac82015-07-02 08:53:34 +0200228 return TEE_SUCCESS;
229}
230
231TEE_Result ta_storage_cmd_start_enum(uint32_t param_types, TEE_Param params[4])
232{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100233 TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
234
Pascal Brandc639ac82015-07-02 08:53:34 +0200235 ASSERT_PARAM_TYPE(TEE_PARAM_TYPES
236 (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE,
237 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
238
Jens Wiklanderc5231592015-11-11 09:27:27 +0100239 return TEE_StartPersistentObjectEnumerator(oe, TEE_STORAGE_PRIVATE);
Pascal Brandc639ac82015-07-02 08:53:34 +0200240}
241
242TEE_Result ta_storage_cmd_next_enum(uint32_t param_types, TEE_Param params[4])
243{
Jens Wiklanderc5231592015-11-11 09:27:27 +0100244 TEE_ObjectEnumHandle oe = VAL2HANDLE(params[0].value.a);
Pascal Brandc603e0d2016-04-25 12:37:18 +0200245 TEE_ObjectInfo *obj;
Jens Wiklanderc5231592015-11-11 09:27:27 +0100246
Pascal Brandc603e0d2016-04-25 12:37:18 +0200247 if (TEE_PARAM_TYPE_GET(param_types, 0) != TEE_PARAM_TYPE_VALUE_INPUT)
248 return TEE_ERROR_BAD_PARAMETERS;
249 if (TEE_PARAM_TYPE_GET(param_types, 2) != TEE_PARAM_TYPE_MEMREF_OUTPUT)
250 return TEE_ERROR_BAD_PARAMETERS;
251 if (TEE_PARAM_TYPE_GET(param_types, 3) != TEE_PARAM_TYPE_NONE)
252 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200253
Pascal Brandc603e0d2016-04-25 12:37:18 +0200254 if (TEE_PARAM_TYPE_GET(param_types, 1) == TEE_PARAM_TYPE_NONE)
255 obj = NULL;
256 else if (TEE_PARAM_TYPE_GET(param_types, 1) ==
257 TEE_PARAM_TYPE_MEMREF_OUTPUT) {
258 if (params[1].memref.size < sizeof(TEE_ObjectInfo)) {
259 params[1].memref.size = sizeof(TEE_ObjectInfo);
260 return TEE_ERROR_SHORT_BUFFER;
261 }
262 params[1].memref.size = sizeof(TEE_ObjectInfo);
263 obj = (TEE_ObjectInfo *)params[1].memref.buffer;
264 } else
265 return TEE_ERROR_BAD_PARAMETERS;
Pascal Brandc639ac82015-07-02 08:53:34 +0200266
267 if (params[2].memref.size < TEE_OBJECT_ID_MAX_LEN)
268 return TEE_ERROR_SHORT_BUFFER;
269
Pascal Brandc603e0d2016-04-25 12:37:18 +0200270 return TEE_GetNextPersistentObject(oe, obj,
271 params[2].memref.buffer,
272 &params[2].memref.size);
Pascal Brandc639ac82015-07-02 08:53:34 +0200273}
Pascal Brand90f23352016-05-19 15:15:47 +0200274
275static TEE_Result check_obj(TEE_ObjectInfo *o1, TEE_ObjectInfo *o2)
276{
277 if ((o1->objectType != o2->objectType) ||
278 (o1->keySize != o2->keySize) ||
279 (o1->maxKeySize != o2->maxKeySize) ||
280 (o1->objectUsage != o2->objectUsage))
281 return TEE_ERROR_GENERIC;
282 return TEE_SUCCESS;
283}
284
285TEE_Result ta_storage_cmd_key_in_persistent(uint32_t param_types,
286 TEE_Param params[4])
287{
288 TEE_Result result = TEE_SUCCESS;
289 TEE_ObjectHandle transient_key = (TEE_ObjectHandle)NULL;
290 TEE_ObjectHandle persistent_key = (TEE_ObjectHandle)NULL;
291 TEE_ObjectHandle key = (TEE_ObjectHandle)NULL;
292 TEE_OperationHandle encrypt_op = (TEE_OperationHandle)NULL;
293 TEE_ObjectInfo keyInfo;
294 TEE_ObjectInfo keyInfo2;
295 TEE_ObjectInfo keyInfo3;
296 uint32_t alg = TEE_ALG_AES_CBC_NOPAD;
297 void *IV = NULL;
298 size_t IVlen = 16;
299 size_t key_size = 256;
300 uint32_t objectID = 1;
301 uint32_t flags = TEE_DATA_FLAG_ACCESS_READ |
302 TEE_DATA_FLAG_ACCESS_WRITE |
303 TEE_DATA_FLAG_ACCESS_WRITE_META |
304 TEE_DATA_FLAG_SHARE_READ |
305 TEE_DATA_FLAG_SHARE_WRITE;
306
307 (void)param_types;
308 (void)params;
309
310 result = TEE_AllocateTransientObject(TEE_TYPE_AES, key_size,
311 &transient_key);
312 if (result != TEE_SUCCESS) {
313 EMSG("Failed to Allocate transient object handle : 0x%x",
314 result);
315 goto cleanup1;
316 }
317
318 result = TEE_GenerateKey(transient_key, key_size, NULL, 0);
319 if (result != TEE_SUCCESS) {
320 EMSG("Failed to generate a transient key: 0x%x", result);
321 goto cleanup2;
322 }
323
324 TEE_GetObjectInfo1(transient_key, &keyInfo);
325 result = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
326 &objectID, sizeof(objectID),
327 flags, transient_key, NULL, 0,
328 &persistent_key);
329 if (result != TEE_SUCCESS) {
330 EMSG("Failed to create a persistent key: 0x%x", result);
331 goto cleanup2;
332 }
333
334 TEE_GetObjectInfo1(persistent_key, &keyInfo2);
335 result = check_obj(&keyInfo, &keyInfo2);
336 if (result != TEE_SUCCESS) {
337 EMSG("keyInfo and keyInfo2 are different");
338 goto cleanup2;
339 }
340
341 TEE_CloseObject(persistent_key);
342
343 result = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
344 &objectID, sizeof(objectID),
345 flags, &key);
346 if (result != TEE_SUCCESS) {
347 EMSG("Failed to open persistent key: 0x%x", result);
348 goto cleanup2;
349 }
350
351 TEE_GetObjectInfo(key, &keyInfo3);
352 result = check_obj(&keyInfo3, &keyInfo2);
353 if (result != TEE_SUCCESS) {
354 EMSG("keyInfo2 and keyInfo3 are different");
355 goto cleanup2;
356 }
357
358 result = TEE_AllocateOperation(&encrypt_op, alg, TEE_MODE_ENCRYPT,
359 keyInfo3.maxObjectSize);
360 if (result != TEE_SUCCESS) {
361 EMSG("Failed to allocate an operation: 0x%x", result);
362 goto cleanup3;
363 }
364
365 result = TEE_SetOperationKey(encrypt_op, key);
366 if (result != TEE_SUCCESS) {
367 EMSG("Failed to set operation key: 0x%x", result);
368 goto cleanup4;
369 }
370
371 IV = TEE_Malloc(IVlen, 0);
372 if (!IV) {
373 EMSG("Out of memory for IV.");
374 result = TEE_ERROR_OUT_OF_MEMORY;
375 goto cleanup4;
376 }
377
378 TEE_CipherInit(encrypt_op, IV, IVlen);
379 TEE_Free(IV);
380
381cleanup4:
382 TEE_FreeOperation(encrypt_op);
383cleanup3:
384 TEE_CloseAndDeletePersistentObject1(key);
385cleanup2:
386 TEE_FreeTransientObject(transient_key);
387cleanup1:
388 return result;
389}
390