11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2d7767217SJens Wiklander /*
3d7767217SJens Wiklander * Copyright (c) 2017, Linaro Limited
4d7767217SJens Wiklander */
5d7767217SJens Wiklander
6d7767217SJens Wiklander #include <assert.h>
7d7767217SJens Wiklander #include <bitstring.h>
8d7767217SJens Wiklander #include <stdio.h>
9d7767217SJens Wiklander #include <stdlib.h>
10d7767217SJens Wiklander #include <string.h>
11d7767217SJens Wiklander #include <tee/fs_dirfile.h>
12d7767217SJens Wiklander #include <types_ext.h>
13d7767217SJens Wiklander
14d7767217SJens Wiklander struct tee_fs_dirfile_dirh {
15d7767217SJens Wiklander const struct tee_fs_dirfile_operations *fops;
16d7767217SJens Wiklander struct tee_file_handle *fh;
17d7767217SJens Wiklander int nbits;
18d7767217SJens Wiklander bitstr_t *files;
19d7767217SJens Wiklander size_t ndents;
20d7767217SJens Wiklander };
21d7767217SJens Wiklander
22d7767217SJens Wiklander struct dirfile_entry {
23d7767217SJens Wiklander TEE_UUID uuid;
24d7767217SJens Wiklander uint8_t oid[TEE_OBJECT_ID_MAX_LEN];
25d7767217SJens Wiklander uint32_t oidlen;
26d7767217SJens Wiklander uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
27d7767217SJens Wiklander uint32_t file_number;
28d7767217SJens Wiklander };
29d7767217SJens Wiklander
3063740eacSJerome Forissier #define OID_EMPTY_NAME 1
3163740eacSJerome Forissier
3263740eacSJerome Forissier /*
3363740eacSJerome Forissier * An object can have an ID of size zero. This object is represented by
3463740eacSJerome Forissier * oidlen == 0 and oid[0] == OID_EMPTY_NAME. When both are zero, the entry is
3563740eacSJerome Forissier * not a valid object.
3663740eacSJerome Forissier */
is_free(struct dirfile_entry * dent)3763740eacSJerome Forissier static bool is_free(struct dirfile_entry *dent)
3863740eacSJerome Forissier {
3963740eacSJerome Forissier assert(dent->oidlen || !dent->oid[0] || dent->oid[0] == OID_EMPTY_NAME);
4063740eacSJerome Forissier
4163740eacSJerome Forissier return !dent->oidlen && !dent->oid[0];
4263740eacSJerome Forissier }
4363740eacSJerome Forissier
44d7767217SJens Wiklander /*
45d7767217SJens Wiklander * File layout
46d7767217SJens Wiklander *
47d7767217SJens Wiklander * dirfile_entry.0
48d7767217SJens Wiklander * ...
49d7767217SJens Wiklander * dirfile_entry.n
50d7767217SJens Wiklander *
51d7767217SJens Wiklander * where n the index is disconnected from file_number in struct dirfile_entry
52d7767217SJens Wiklander */
53d7767217SJens Wiklander
maybe_grow_files(struct tee_fs_dirfile_dirh * dirh,int idx)54d7767217SJens Wiklander static TEE_Result maybe_grow_files(struct tee_fs_dirfile_dirh *dirh, int idx)
55d7767217SJens Wiklander {
56d7767217SJens Wiklander void *p;
57d7767217SJens Wiklander
58d7767217SJens Wiklander if (idx < dirh->nbits)
59d7767217SJens Wiklander return TEE_SUCCESS;
60d7767217SJens Wiklander
61d7767217SJens Wiklander p = realloc(dirh->files, bitstr_size(idx + 1));
62d7767217SJens Wiklander if (!p)
63d7767217SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
64d7767217SJens Wiklander dirh->files = p;
65d7767217SJens Wiklander
66d7767217SJens Wiklander bit_nclear(dirh->files, dirh->nbits, idx);
67d7767217SJens Wiklander dirh->nbits = idx + 1;
68d7767217SJens Wiklander
69d7767217SJens Wiklander return TEE_SUCCESS;
70d7767217SJens Wiklander }
71d7767217SJens Wiklander
set_file(struct tee_fs_dirfile_dirh * dirh,int idx)72d7767217SJens Wiklander static TEE_Result set_file(struct tee_fs_dirfile_dirh *dirh, int idx)
73d7767217SJens Wiklander {
74d7767217SJens Wiklander TEE_Result res = maybe_grow_files(dirh, idx);
75d7767217SJens Wiklander
76d7767217SJens Wiklander if (!res)
77d7767217SJens Wiklander bit_set(dirh->files, idx);
78d7767217SJens Wiklander
79d7767217SJens Wiklander return res;
80d7767217SJens Wiklander }
81d7767217SJens Wiklander
clear_file(struct tee_fs_dirfile_dirh * dirh,int idx)82d7767217SJens Wiklander static void clear_file(struct tee_fs_dirfile_dirh *dirh, int idx)
83d7767217SJens Wiklander {
84d7767217SJens Wiklander if (idx < dirh->nbits)
85d7767217SJens Wiklander bit_clear(dirh->files, idx);
86d7767217SJens Wiklander }
87d7767217SJens Wiklander
test_file(struct tee_fs_dirfile_dirh * dirh,int idx)88d7767217SJens Wiklander static bool test_file(struct tee_fs_dirfile_dirh *dirh, int idx)
89d7767217SJens Wiklander {
90d7767217SJens Wiklander if (idx < dirh->nbits)
91d7767217SJens Wiklander return bit_test(dirh->files, idx);
92d7767217SJens Wiklander
93d7767217SJens Wiklander return false;
94d7767217SJens Wiklander }
95d7767217SJens Wiklander
read_dent(struct tee_fs_dirfile_dirh * dirh,int idx,struct dirfile_entry * dent)96d7767217SJens Wiklander static TEE_Result read_dent(struct tee_fs_dirfile_dirh *dirh, int idx,
97d7767217SJens Wiklander struct dirfile_entry *dent)
98d7767217SJens Wiklander {
99d7767217SJens Wiklander TEE_Result res;
100d7767217SJens Wiklander size_t l;
101d7767217SJens Wiklander
102d7767217SJens Wiklander l = sizeof(*dent);
103d7767217SJens Wiklander res = dirh->fops->read(dirh->fh, sizeof(struct dirfile_entry) * idx,
104d7767217SJens Wiklander dent, &l);
105d7767217SJens Wiklander if (!res && l != sizeof(*dent))
106d7767217SJens Wiklander res = TEE_ERROR_ITEM_NOT_FOUND;
107d7767217SJens Wiklander
108d7767217SJens Wiklander return res;
109d7767217SJens Wiklander }
110d7767217SJens Wiklander
write_dent(struct tee_fs_dirfile_dirh * dirh,size_t n,struct dirfile_entry * dent)111d7767217SJens Wiklander static TEE_Result write_dent(struct tee_fs_dirfile_dirh *dirh, size_t n,
112d7767217SJens Wiklander struct dirfile_entry *dent)
113d7767217SJens Wiklander {
114d7767217SJens Wiklander TEE_Result res;
115d7767217SJens Wiklander
116b2284b11SJens Wiklander res = dirh->fops->write(dirh->fh, sizeof(*dent) * n, dent,
117b2284b11SJens Wiklander sizeof(*dent));
118d7767217SJens Wiklander if (!res && n >= dirh->ndents)
119d7767217SJens Wiklander dirh->ndents = n + 1;
120d7767217SJens Wiklander
121d7767217SJens Wiklander return res;
122d7767217SJens Wiklander }
123d7767217SJens Wiklander
tee_fs_dirfile_open(bool create,uint8_t * hash,uint32_t min_counter,const struct tee_fs_dirfile_operations * fops,struct tee_fs_dirfile_dirh ** dirh_ret)124623b9bd4SJens Wiklander TEE_Result tee_fs_dirfile_open(bool create, uint8_t *hash, uint32_t min_counter,
125a4ed7bafSJens Wiklander const struct tee_fs_dirfile_operations *fops,
126d7767217SJens Wiklander struct tee_fs_dirfile_dirh **dirh_ret)
127d7767217SJens Wiklander {
128d7767217SJens Wiklander TEE_Result res;
129d7767217SJens Wiklander struct tee_fs_dirfile_dirh *dirh = calloc(1, sizeof(*dirh));
130d7767217SJens Wiklander size_t n;
131d7767217SJens Wiklander
132d7767217SJens Wiklander if (!dirh)
133d7767217SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
134d7767217SJens Wiklander
135d7767217SJens Wiklander dirh->fops = fops;
136623b9bd4SJens Wiklander res = fops->open(create, hash, min_counter, NULL, NULL, &dirh->fh);
137d7767217SJens Wiklander if (res)
138d7767217SJens Wiklander goto out;
139d7767217SJens Wiklander
140d7767217SJens Wiklander for (n = 0;; n++) {
141a4ba53ebSClement Faure struct dirfile_entry dent = { };
142d7767217SJens Wiklander
143d7767217SJens Wiklander res = read_dent(dirh, n, &dent);
144d7767217SJens Wiklander if (res) {
145d7767217SJens Wiklander if (res == TEE_ERROR_ITEM_NOT_FOUND)
146d7767217SJens Wiklander res = TEE_SUCCESS;
147d7767217SJens Wiklander goto out;
148d7767217SJens Wiklander }
149d7767217SJens Wiklander
15063740eacSJerome Forissier if (is_free(&dent))
151d7767217SJens Wiklander continue;
152d7767217SJens Wiklander
153d7767217SJens Wiklander if (test_file(dirh, dent.file_number)) {
154d7767217SJens Wiklander DMSG("clearing duplicate file number %" PRIu32,
155d7767217SJens Wiklander dent.file_number);
156d7767217SJens Wiklander memset(&dent, 0, sizeof(dent));
157d7767217SJens Wiklander res = write_dent(dirh, n, &dent);
158d7767217SJens Wiklander if (res)
159d7767217SJens Wiklander goto out;
160d7767217SJens Wiklander continue;
161d7767217SJens Wiklander }
162d7767217SJens Wiklander
163d7767217SJens Wiklander res = set_file(dirh, dent.file_number);
164d7767217SJens Wiklander if (res != TEE_SUCCESS)
165d7767217SJens Wiklander goto out;
166d7767217SJens Wiklander }
167d7767217SJens Wiklander out:
168d7767217SJens Wiklander if (!res) {
169d7767217SJens Wiklander dirh->ndents = n;
170d7767217SJens Wiklander *dirh_ret = dirh;
171d7767217SJens Wiklander } else {
172d7767217SJens Wiklander tee_fs_dirfile_close(dirh);
173d7767217SJens Wiklander }
174d7767217SJens Wiklander return res;
175d7767217SJens Wiklander }
176d7767217SJens Wiklander
tee_fs_dirfile_close(struct tee_fs_dirfile_dirh * dirh)177d7767217SJens Wiklander void tee_fs_dirfile_close(struct tee_fs_dirfile_dirh *dirh)
178d7767217SJens Wiklander {
179d7767217SJens Wiklander if (dirh) {
180d7767217SJens Wiklander dirh->fops->close(dirh->fh);
181d7767217SJens Wiklander free(dirh->files);
182d7767217SJens Wiklander free(dirh);
183d7767217SJens Wiklander }
184d7767217SJens Wiklander }
185d7767217SJens Wiklander
tee_fs_dirfile_commit_writes(struct tee_fs_dirfile_dirh * dirh,uint8_t * hash,uint32_t * counter)186a4ed7bafSJens Wiklander TEE_Result tee_fs_dirfile_commit_writes(struct tee_fs_dirfile_dirh *dirh,
187623b9bd4SJens Wiklander uint8_t *hash, uint32_t *counter)
188d7767217SJens Wiklander {
189623b9bd4SJens Wiklander return dirh->fops->commit_writes(dirh->fh, hash, counter);
190d7767217SJens Wiklander }
191d7767217SJens Wiklander
tee_fs_dirfile_get_tmp(struct tee_fs_dirfile_dirh * dirh,struct tee_fs_dirfile_fileh * dfh)192d7767217SJens Wiklander TEE_Result tee_fs_dirfile_get_tmp(struct tee_fs_dirfile_dirh *dirh,
193d7767217SJens Wiklander struct tee_fs_dirfile_fileh *dfh)
194d7767217SJens Wiklander {
195d7767217SJens Wiklander TEE_Result res;
196d7767217SJens Wiklander int i = 0;
197d7767217SJens Wiklander
19868697bf5SJens Wiklander if (dirh->nbits) {
199d7767217SJens Wiklander bit_ffc(dirh->files, dirh->nbits, &i);
200d7767217SJens Wiklander if (i == -1)
201d7767217SJens Wiklander i = dirh->nbits;
202d7767217SJens Wiklander }
203d7767217SJens Wiklander
204d7767217SJens Wiklander res = set_file(dirh, i);
205d7767217SJens Wiklander if (!res)
206d7767217SJens Wiklander dfh->file_number = i;
207d7767217SJens Wiklander
208d7767217SJens Wiklander return res;
209d7767217SJens Wiklander }
210d7767217SJens Wiklander
tee_fs_dirfile_find(struct tee_fs_dirfile_dirh * dirh,const TEE_UUID * uuid,const void * oid,size_t oidlen,struct tee_fs_dirfile_fileh * dfh)211d7767217SJens Wiklander TEE_Result tee_fs_dirfile_find(struct tee_fs_dirfile_dirh *dirh,
212fd108c3eSJens Wiklander const TEE_UUID *uuid, const void *oid,
213fd108c3eSJens Wiklander size_t oidlen, struct tee_fs_dirfile_fileh *dfh)
214d7767217SJens Wiklander {
21563740eacSJerome Forissier TEE_Result res = TEE_SUCCESS;
21663740eacSJerome Forissier struct dirfile_entry dent = { };
21763740eacSJerome Forissier int n = 0;
218d7767217SJens Wiklander
219d7767217SJens Wiklander for (n = 0;; n++) {
220d7767217SJens Wiklander res = read_dent(dirh, n, &dent);
221d7767217SJens Wiklander if (res)
222d7767217SJens Wiklander return res;
223d7767217SJens Wiklander
22463740eacSJerome Forissier if (is_free(&dent))
22563740eacSJerome Forissier continue;
226d7767217SJens Wiklander if (dent.oidlen != oidlen)
227d7767217SJens Wiklander continue;
228d7767217SJens Wiklander
22963740eacSJerome Forissier assert(test_file(dirh, dent.file_number));
230d7767217SJens Wiklander
231fd108c3eSJens Wiklander if (!memcmp(&dent.uuid, uuid, sizeof(dent.uuid)) &&
232d7767217SJens Wiklander !memcmp(&dent.oid, oid, oidlen))
233d7767217SJens Wiklander break;
234d7767217SJens Wiklander }
235d7767217SJens Wiklander
236d7767217SJens Wiklander if (dfh) {
237d7767217SJens Wiklander dfh->idx = n;
238d7767217SJens Wiklander dfh->file_number = dent.file_number;
239d7767217SJens Wiklander memcpy(dfh->hash, dent.hash, sizeof(dent.hash));
240d7767217SJens Wiklander }
241d7767217SJens Wiklander
242d7767217SJens Wiklander return TEE_SUCCESS;
243d7767217SJens Wiklander }
244d7767217SJens Wiklander
find_empty_idx(struct tee_fs_dirfile_dirh * dh,int * idx)24563740eacSJerome Forissier static TEE_Result find_empty_idx(struct tee_fs_dirfile_dirh *dh, int *idx)
24663740eacSJerome Forissier {
24763740eacSJerome Forissier struct dirfile_entry dent = { };
24863740eacSJerome Forissier TEE_Result res = TEE_SUCCESS;
24963740eacSJerome Forissier int n = 0;
25063740eacSJerome Forissier
25163740eacSJerome Forissier for (n = 0;; n++) {
25263740eacSJerome Forissier res = read_dent(dh, n, &dent);
25363740eacSJerome Forissier if (res == TEE_ERROR_ITEM_NOT_FOUND)
25463740eacSJerome Forissier break;
25563740eacSJerome Forissier if (res)
25663740eacSJerome Forissier return res;
25763740eacSJerome Forissier if (is_free(&dent))
25863740eacSJerome Forissier break;
25963740eacSJerome Forissier }
26063740eacSJerome Forissier
26163740eacSJerome Forissier *idx = n;
26263740eacSJerome Forissier return TEE_SUCCESS;
26363740eacSJerome Forissier }
26463740eacSJerome Forissier
tee_fs_dirfile_fileh_to_fname(const struct tee_fs_dirfile_fileh * dfh,char * fname,size_t * fnlen)265d7767217SJens Wiklander TEE_Result tee_fs_dirfile_fileh_to_fname(const struct tee_fs_dirfile_fileh *dfh,
266d7767217SJens Wiklander char *fname, size_t *fnlen)
267d7767217SJens Wiklander {
268d7767217SJens Wiklander int r;
269d7767217SJens Wiklander size_t l = *fnlen;
270d7767217SJens Wiklander
271d7767217SJens Wiklander if (dfh)
272d7767217SJens Wiklander r = snprintf(fname, l, "%" PRIx32, dfh->file_number);
273d7767217SJens Wiklander else
274d7767217SJens Wiklander r = snprintf(fname, l, "dirf.db");
275d7767217SJens Wiklander
276d7767217SJens Wiklander if (r < 0)
277d7767217SJens Wiklander return TEE_ERROR_GENERIC;
278d7767217SJens Wiklander
279d7767217SJens Wiklander *fnlen = r + 1;
280d7767217SJens Wiklander if ((size_t)r >= l)
281d7767217SJens Wiklander return TEE_ERROR_SHORT_BUFFER;
282d7767217SJens Wiklander
283d7767217SJens Wiklander return TEE_SUCCESS;
284d7767217SJens Wiklander }
285d7767217SJens Wiklander
tee_fs_dirfile_rename(struct tee_fs_dirfile_dirh * dirh,const TEE_UUID * uuid,struct tee_fs_dirfile_fileh * dfh,const void * oid,size_t oidlen)286d7767217SJens Wiklander TEE_Result tee_fs_dirfile_rename(struct tee_fs_dirfile_dirh *dirh,
287fd108c3eSJens Wiklander const TEE_UUID *uuid,
288d7767217SJens Wiklander struct tee_fs_dirfile_fileh *dfh,
289d7767217SJens Wiklander const void *oid, size_t oidlen)
290d7767217SJens Wiklander {
291d7767217SJens Wiklander TEE_Result res;
292a4ba53ebSClement Faure struct dirfile_entry dent = { };
293d7767217SJens Wiklander
29463740eacSJerome Forissier if (oidlen > sizeof(dent.oid))
295d7767217SJens Wiklander return TEE_ERROR_BAD_PARAMETERS;
296d7767217SJens Wiklander memset(&dent, 0, sizeof(dent));
297fd108c3eSJens Wiklander dent.uuid = *uuid;
29863740eacSJerome Forissier if (oidlen)
299d7767217SJens Wiklander memcpy(dent.oid, oid, oidlen);
30063740eacSJerome Forissier else
30163740eacSJerome Forissier dent.oid[0] = OID_EMPTY_NAME;
30263740eacSJerome Forissier
303d7767217SJens Wiklander dent.oidlen = oidlen;
304d7767217SJens Wiklander memcpy(dent.hash, dfh->hash, sizeof(dent.hash));
305d7767217SJens Wiklander dent.file_number = dfh->file_number;
306d7767217SJens Wiklander
307d7767217SJens Wiklander if (dfh->idx < 0) {
308d7767217SJens Wiklander struct tee_fs_dirfile_fileh dfh2;
309d7767217SJens Wiklander
310fd108c3eSJens Wiklander res = tee_fs_dirfile_find(dirh, uuid, oid, oidlen, &dfh2);
311d7767217SJens Wiklander if (res) {
312d7767217SJens Wiklander if (res == TEE_ERROR_ITEM_NOT_FOUND)
31363740eacSJerome Forissier res = find_empty_idx(dirh, &dfh2.idx);
314d7767217SJens Wiklander if (res)
315d7767217SJens Wiklander return res;
316d7767217SJens Wiklander }
317d7767217SJens Wiklander dfh->idx = dfh2.idx;
318d7767217SJens Wiklander }
319d7767217SJens Wiklander
320d7767217SJens Wiklander return write_dent(dirh, dfh->idx, &dent);
321d7767217SJens Wiklander }
322d7767217SJens Wiklander
tee_fs_dirfile_remove(struct tee_fs_dirfile_dirh * dirh,const struct tee_fs_dirfile_fileh * dfh)323d7767217SJens Wiklander TEE_Result tee_fs_dirfile_remove(struct tee_fs_dirfile_dirh *dirh,
324d7767217SJens Wiklander const struct tee_fs_dirfile_fileh *dfh)
325d7767217SJens Wiklander {
326d7767217SJens Wiklander TEE_Result res;
327a4ba53ebSClement Faure struct dirfile_entry dent = { };
328d7767217SJens Wiklander uint32_t file_number;
329d7767217SJens Wiklander
330d7767217SJens Wiklander res = read_dent(dirh, dfh->idx, &dent);
331d7767217SJens Wiklander if (res)
332d7767217SJens Wiklander return res;
333d7767217SJens Wiklander
33463740eacSJerome Forissier if (is_free(&dent))
335d7767217SJens Wiklander return TEE_SUCCESS;
336d7767217SJens Wiklander
337d7767217SJens Wiklander file_number = dent.file_number;
338d7767217SJens Wiklander assert(dfh->file_number == file_number);
339d7767217SJens Wiklander assert(test_file(dirh, file_number));
340d7767217SJens Wiklander
341d7767217SJens Wiklander memset(&dent, 0, sizeof(dent));
342d7767217SJens Wiklander res = write_dent(dirh, dfh->idx, &dent);
343d7767217SJens Wiklander if (!res)
344d7767217SJens Wiklander clear_file(dirh, file_number);
345d7767217SJens Wiklander
346d7767217SJens Wiklander return res;
347d7767217SJens Wiklander }
348d7767217SJens Wiklander
tee_fs_dirfile_update_hash(struct tee_fs_dirfile_dirh * dirh,const struct tee_fs_dirfile_fileh * dfh)349d7767217SJens Wiklander TEE_Result tee_fs_dirfile_update_hash(struct tee_fs_dirfile_dirh *dirh,
350d7767217SJens Wiklander const struct tee_fs_dirfile_fileh *dfh)
351d7767217SJens Wiklander {
352d7767217SJens Wiklander TEE_Result res;
353a4ba53ebSClement Faure struct dirfile_entry dent = { };
354d7767217SJens Wiklander
355d7767217SJens Wiklander res = read_dent(dirh, dfh->idx, &dent);
356d7767217SJens Wiklander if (res)
357d7767217SJens Wiklander return res;
358d7767217SJens Wiklander assert(dent.file_number == dfh->file_number);
359d7767217SJens Wiklander assert(test_file(dirh, dent.file_number));
360d7767217SJens Wiklander
361d7767217SJens Wiklander memcpy(&dent.hash, dfh->hash, sizeof(dent.hash));
362d7767217SJens Wiklander
363d7767217SJens Wiklander return write_dent(dirh, dfh->idx, &dent);
364d7767217SJens Wiklander }
365d7767217SJens Wiklander
tee_fs_dirfile_get_next(struct tee_fs_dirfile_dirh * dirh,const TEE_UUID * uuid,int * idx,void * oid,size_t * oidlen)366d7767217SJens Wiklander TEE_Result tee_fs_dirfile_get_next(struct tee_fs_dirfile_dirh *dirh,
367fd108c3eSJens Wiklander const TEE_UUID *uuid, int *idx, void *oid,
368fd108c3eSJens Wiklander size_t *oidlen)
369d7767217SJens Wiklander {
370d7767217SJens Wiklander TEE_Result res;
371d7767217SJens Wiklander int i = *idx + 1;
372*239fae35SClement Faure struct dirfile_entry dent = { };
373d7767217SJens Wiklander
374d7767217SJens Wiklander if (i < 0)
375d7767217SJens Wiklander i = 0;
376d7767217SJens Wiklander
377d7767217SJens Wiklander for (;; i++) {
378d7767217SJens Wiklander res = read_dent(dirh, i, &dent);
379d7767217SJens Wiklander if (res)
380d7767217SJens Wiklander return res;
381fd108c3eSJens Wiklander if (!memcmp(&dent.uuid, uuid, sizeof(dent.uuid)) &&
38263740eacSJerome Forissier !is_free(&dent))
383d7767217SJens Wiklander break;
384d7767217SJens Wiklander }
385d7767217SJens Wiklander
386d7767217SJens Wiklander if (*oidlen < dent.oidlen)
387d7767217SJens Wiklander return TEE_ERROR_SHORT_BUFFER;
388d7767217SJens Wiklander
389d7767217SJens Wiklander memcpy(oid, dent.oid, dent.oidlen);
390d7767217SJens Wiklander *oidlen = dent.oidlen;
391d7767217SJens Wiklander *idx = i;
392d7767217SJens Wiklander
393d7767217SJens Wiklander return TEE_SUCCESS;
394d7767217SJens Wiklander }
395