xref: /optee_os/core/tee/fs_dirfile.c (revision fd108c3e6609cc545dd1d53ea40042bcb28d500e)
1d7767217SJens Wiklander /*
2d7767217SJens Wiklander  * Copyright (c) 2017, Linaro Limited
3d7767217SJens Wiklander  * All rights reserved.
4d7767217SJens Wiklander  *
5d7767217SJens Wiklander  * Redistribution and use in source and binary forms, with or without
6d7767217SJens Wiklander  * modification, are permitted provided that the following conditions are met:
7d7767217SJens Wiklander  *
8d7767217SJens Wiklander  * 1. Redistributions of source code must retain the above copyright notice,
9d7767217SJens Wiklander  * this list of conditions and the following disclaimer.
10d7767217SJens Wiklander  *
11d7767217SJens Wiklander  * 2. Redistributions in binary form must reproduce the above copyright notice,
12d7767217SJens Wiklander  * this list of conditions and the following disclaimer in the documentation
13d7767217SJens Wiklander  * and/or other materials provided with the distribution.
14d7767217SJens Wiklander  *
15d7767217SJens Wiklander  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16d7767217SJens Wiklander  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17d7767217SJens Wiklander  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18d7767217SJens Wiklander  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19d7767217SJens Wiklander  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20d7767217SJens Wiklander  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21d7767217SJens Wiklander  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22d7767217SJens Wiklander  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23d7767217SJens Wiklander  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24d7767217SJens Wiklander  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25d7767217SJens Wiklander  * POSSIBILITY OF SUCH DAMAGE.
26d7767217SJens Wiklander  */
27d7767217SJens Wiklander 
28d7767217SJens Wiklander #include <assert.h>
29d7767217SJens Wiklander #include <bitstring.h>
30d7767217SJens Wiklander #include <stdio.h>
31d7767217SJens Wiklander #include <stdlib.h>
32d7767217SJens Wiklander #include <string.h>
33d7767217SJens Wiklander #include <tee/fs_dirfile.h>
34d7767217SJens Wiklander #include <types_ext.h>
35d7767217SJens Wiklander 
36d7767217SJens Wiklander struct tee_fs_dirfile_dirh {
37d7767217SJens Wiklander 	const struct tee_fs_dirfile_operations *fops;
38d7767217SJens Wiklander 	struct tee_file_handle *fh;
39d7767217SJens Wiklander 	int nbits;
40d7767217SJens Wiklander 	bitstr_t *files;
41d7767217SJens Wiklander 	size_t ndents;
42d7767217SJens Wiklander };
43d7767217SJens Wiklander 
44d7767217SJens Wiklander struct dirfile_entry {
45d7767217SJens Wiklander 	TEE_UUID uuid;
46d7767217SJens Wiklander 	uint8_t oid[TEE_OBJECT_ID_MAX_LEN];
47d7767217SJens Wiklander 	uint32_t oidlen;
48d7767217SJens Wiklander 	uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
49d7767217SJens Wiklander 	uint32_t file_number;
50d7767217SJens Wiklander };
51d7767217SJens Wiklander 
52d7767217SJens Wiklander /*
53d7767217SJens Wiklander  * File layout
54d7767217SJens Wiklander  *
55d7767217SJens Wiklander  * dirfile_entry.0
56d7767217SJens Wiklander  * ...
57d7767217SJens Wiklander  * dirfile_entry.n
58d7767217SJens Wiklander  *
59d7767217SJens Wiklander  * where n the index is disconnected from file_number in struct dirfile_entry
60d7767217SJens Wiklander  */
61d7767217SJens Wiklander 
62d7767217SJens Wiklander static TEE_Result maybe_grow_files(struct tee_fs_dirfile_dirh *dirh, int idx)
63d7767217SJens Wiklander {
64d7767217SJens Wiklander 	void *p;
65d7767217SJens Wiklander 
66d7767217SJens Wiklander 	if (idx < dirh->nbits)
67d7767217SJens Wiklander 		return TEE_SUCCESS;
68d7767217SJens Wiklander 
69d7767217SJens Wiklander 	p = realloc(dirh->files, bitstr_size(idx + 1));
70d7767217SJens Wiklander 	if (!p)
71d7767217SJens Wiklander 		return TEE_ERROR_OUT_OF_MEMORY;
72d7767217SJens Wiklander 	dirh->files = p;
73d7767217SJens Wiklander 
74d7767217SJens Wiklander 	bit_nclear(dirh->files, dirh->nbits, idx);
75d7767217SJens Wiklander 	dirh->nbits = idx + 1;
76d7767217SJens Wiklander 
77d7767217SJens Wiklander 	return TEE_SUCCESS;
78d7767217SJens Wiklander }
79d7767217SJens Wiklander 
80d7767217SJens Wiklander static TEE_Result set_file(struct tee_fs_dirfile_dirh *dirh, int idx)
81d7767217SJens Wiklander {
82d7767217SJens Wiklander 	TEE_Result res = maybe_grow_files(dirh, idx);
83d7767217SJens Wiklander 
84d7767217SJens Wiklander 	if (!res)
85d7767217SJens Wiklander 		bit_set(dirh->files, idx);
86d7767217SJens Wiklander 
87d7767217SJens Wiklander 	return res;
88d7767217SJens Wiklander }
89d7767217SJens Wiklander 
90d7767217SJens Wiklander static void clear_file(struct tee_fs_dirfile_dirh *dirh, int idx)
91d7767217SJens Wiklander {
92d7767217SJens Wiklander 	if (idx < dirh->nbits)
93d7767217SJens Wiklander 		bit_clear(dirh->files, idx);
94d7767217SJens Wiklander }
95d7767217SJens Wiklander 
96d7767217SJens Wiklander static bool test_file(struct tee_fs_dirfile_dirh *dirh, int idx)
97d7767217SJens Wiklander {
98d7767217SJens Wiklander 	if (idx < dirh->nbits)
99d7767217SJens Wiklander 		return bit_test(dirh->files, idx);
100d7767217SJens Wiklander 
101d7767217SJens Wiklander 	return false;
102d7767217SJens Wiklander }
103d7767217SJens Wiklander 
104d7767217SJens Wiklander static TEE_Result read_dent(struct tee_fs_dirfile_dirh *dirh, int idx,
105d7767217SJens Wiklander 			    struct dirfile_entry *dent)
106d7767217SJens Wiklander {
107d7767217SJens Wiklander 	TEE_Result res;
108d7767217SJens Wiklander 	size_t l;
109d7767217SJens Wiklander 
110d7767217SJens Wiklander 	l = sizeof(*dent);
111d7767217SJens Wiklander 	res = dirh->fops->read(dirh->fh, sizeof(struct dirfile_entry) * idx,
112d7767217SJens Wiklander 			       dent, &l);
113d7767217SJens Wiklander 	if (!res && l != sizeof(*dent))
114d7767217SJens Wiklander 		res = TEE_ERROR_ITEM_NOT_FOUND;
115d7767217SJens Wiklander 
116d7767217SJens Wiklander 	return res;
117d7767217SJens Wiklander }
118d7767217SJens Wiklander 
119d7767217SJens Wiklander static TEE_Result write_dent(struct tee_fs_dirfile_dirh *dirh, size_t n,
120d7767217SJens Wiklander 			     struct dirfile_entry *dent)
121d7767217SJens Wiklander {
122d7767217SJens Wiklander 	TEE_Result res;
123d7767217SJens Wiklander 
124d7767217SJens Wiklander 	res = dirh->fops->write(dirh->fh, sizeof(*dent) * n,
125d7767217SJens Wiklander 				dent, sizeof(*dent));
126d7767217SJens Wiklander 	if (!res && n >= dirh->ndents)
127d7767217SJens Wiklander 		dirh->ndents = n + 1;
128d7767217SJens Wiklander 
129d7767217SJens Wiklander 	return res;
130d7767217SJens Wiklander }
131d7767217SJens Wiklander 
132*fd108c3eSJens Wiklander TEE_Result tee_fs_dirfile_open(const struct tee_fs_dirfile_operations *fops,
133d7767217SJens Wiklander 			       struct tee_fs_dirfile_dirh **dirh_ret)
134d7767217SJens Wiklander {
135d7767217SJens Wiklander 	TEE_Result res;
136d7767217SJens Wiklander 	struct tee_fs_dirfile_dirh *dirh = calloc(1, sizeof(*dirh));
137d7767217SJens Wiklander 	size_t n;
138d7767217SJens Wiklander 
139d7767217SJens Wiklander 	if (!dirh)
140d7767217SJens Wiklander 		return TEE_ERROR_OUT_OF_MEMORY;
141d7767217SJens Wiklander 
142d7767217SJens Wiklander 	dirh->fops = fops;
143d7767217SJens Wiklander 	res = fops->open(false, NULL, NULL, &dirh->fh);
144d7767217SJens Wiklander 	if (res) {
145d7767217SJens Wiklander 		res = fops->open(true, NULL, NULL, &dirh->fh);
146d7767217SJens Wiklander 		if (res)
147d7767217SJens Wiklander 			goto out;
148d7767217SJens Wiklander 	}
149d7767217SJens Wiklander 
150d7767217SJens Wiklander 	for (n = 0;; n++) {
151d7767217SJens Wiklander 		struct dirfile_entry dent;
152d7767217SJens Wiklander 
153d7767217SJens Wiklander 		res = read_dent(dirh, n, &dent);
154d7767217SJens Wiklander 		if (res) {
155d7767217SJens Wiklander 			if (res == TEE_ERROR_ITEM_NOT_FOUND)
156d7767217SJens Wiklander 				res = TEE_SUCCESS;
157d7767217SJens Wiklander 			goto out;
158d7767217SJens Wiklander 		}
159d7767217SJens Wiklander 
160d7767217SJens Wiklander 		if (!dent.oidlen)
161d7767217SJens Wiklander 			continue;
162d7767217SJens Wiklander 
163d7767217SJens Wiklander 		if (test_file(dirh, dent.file_number)) {
164d7767217SJens Wiklander 			DMSG("clearing duplicate file number %" PRIu32,
165d7767217SJens Wiklander 			     dent.file_number);
166d7767217SJens Wiklander 			memset(&dent, 0, sizeof(dent));
167d7767217SJens Wiklander 			res = write_dent(dirh, n, &dent);
168d7767217SJens Wiklander 			if (res)
169d7767217SJens Wiklander 				goto out;
170d7767217SJens Wiklander 			continue;
171d7767217SJens Wiklander 		}
172d7767217SJens Wiklander 
173d7767217SJens Wiklander 		res = set_file(dirh, dent.file_number);
174d7767217SJens Wiklander 		if (res != TEE_SUCCESS)
175d7767217SJens Wiklander 			goto out;
176d7767217SJens Wiklander 	}
177d7767217SJens Wiklander out:
178d7767217SJens Wiklander 	if (!res) {
179d7767217SJens Wiklander 		dirh->ndents = n;
180d7767217SJens Wiklander 		*dirh_ret = dirh;
181d7767217SJens Wiklander 	} else {
182d7767217SJens Wiklander 		tee_fs_dirfile_close(dirh);
183d7767217SJens Wiklander 	}
184d7767217SJens Wiklander 	return res;
185d7767217SJens Wiklander }
186d7767217SJens Wiklander 
187d7767217SJens Wiklander void tee_fs_dirfile_close(struct tee_fs_dirfile_dirh *dirh)
188d7767217SJens Wiklander {
189d7767217SJens Wiklander 	if (dirh) {
190d7767217SJens Wiklander 		dirh->fops->close(dirh->fh);
191d7767217SJens Wiklander 		free(dirh->files);
192d7767217SJens Wiklander 		free(dirh);
193d7767217SJens Wiklander 	}
194d7767217SJens Wiklander }
195d7767217SJens Wiklander 
196d7767217SJens Wiklander TEE_Result tee_fs_dirfile_commit_writes(struct tee_fs_dirfile_dirh *dirh)
197d7767217SJens Wiklander {
198d7767217SJens Wiklander 	return dirh->fops->commit_writes(dirh->fh, NULL);
199d7767217SJens Wiklander }
200d7767217SJens Wiklander 
201d7767217SJens Wiklander TEE_Result tee_fs_dirfile_get_tmp(struct tee_fs_dirfile_dirh *dirh,
202d7767217SJens Wiklander 				  struct tee_fs_dirfile_fileh *dfh)
203d7767217SJens Wiklander {
204d7767217SJens Wiklander 	TEE_Result res;
205d7767217SJens Wiklander 	int i = 0;
206d7767217SJens Wiklander 
207d7767217SJens Wiklander 	if (dirh->files) {
208d7767217SJens Wiklander 		bit_ffc(dirh->files, dirh->nbits, &i);
209d7767217SJens Wiklander 		if (i == -1)
210d7767217SJens Wiklander 			i = dirh->nbits;
211d7767217SJens Wiklander 	}
212d7767217SJens Wiklander 
213d7767217SJens Wiklander 	res = set_file(dirh, i);
214d7767217SJens Wiklander 	if (!res)
215d7767217SJens Wiklander 		dfh->file_number = i;
216d7767217SJens Wiklander 
217d7767217SJens Wiklander 	return res;
218d7767217SJens Wiklander }
219d7767217SJens Wiklander 
220d7767217SJens Wiklander TEE_Result tee_fs_dirfile_find(struct tee_fs_dirfile_dirh *dirh,
221*fd108c3eSJens Wiklander 			       const TEE_UUID *uuid, const void *oid,
222*fd108c3eSJens Wiklander 			       size_t oidlen, struct tee_fs_dirfile_fileh *dfh)
223d7767217SJens Wiklander {
224d7767217SJens Wiklander 	TEE_Result res;
225d7767217SJens Wiklander 	struct dirfile_entry dent;
226d7767217SJens Wiklander 	int n;
227d7767217SJens Wiklander 	int first_free = -1;
228d7767217SJens Wiklander 
229d7767217SJens Wiklander 	for (n = 0;; n++) {
230d7767217SJens Wiklander 		res = read_dent(dirh, n, &dent);
231d7767217SJens Wiklander 		if (res == TEE_ERROR_ITEM_NOT_FOUND && !oidlen) {
232d7767217SJens Wiklander 			memset(&dent, 0, sizeof(dent));
233d7767217SJens Wiklander 			if (first_free != -1)
234d7767217SJens Wiklander 				n = first_free;
235d7767217SJens Wiklander 			break;
236d7767217SJens Wiklander 		}
237d7767217SJens Wiklander 		if (res)
238d7767217SJens Wiklander 			return res;
239d7767217SJens Wiklander 
240*fd108c3eSJens Wiklander 		/* TODO check this loop when oidlen == 0 */
241*fd108c3eSJens Wiklander 
242d7767217SJens Wiklander 		if (!dent.oidlen && first_free == -1)
243d7767217SJens Wiklander 			first_free = n;
244d7767217SJens Wiklander 		if (dent.oidlen != oidlen)
245d7767217SJens Wiklander 			continue;
246d7767217SJens Wiklander 
247d7767217SJens Wiklander 		assert(!oidlen || !dent.oidlen ||
248d7767217SJens Wiklander 		       test_file(dirh, dent.file_number));
249d7767217SJens Wiklander 
250*fd108c3eSJens Wiklander 		if (!memcmp(&dent.uuid, uuid, sizeof(dent.uuid)) &&
251d7767217SJens Wiklander 		    !memcmp(&dent.oid, oid, oidlen))
252d7767217SJens Wiklander 			break;
253d7767217SJens Wiklander 	}
254d7767217SJens Wiklander 
255d7767217SJens Wiklander 	if (dfh) {
256d7767217SJens Wiklander 		dfh->idx = n;
257d7767217SJens Wiklander 		dfh->file_number = dent.file_number;
258d7767217SJens Wiklander 		memcpy(dfh->hash, dent.hash, sizeof(dent.hash));
259d7767217SJens Wiklander 	}
260d7767217SJens Wiklander 
261d7767217SJens Wiklander 	return TEE_SUCCESS;
262d7767217SJens Wiklander }
263d7767217SJens Wiklander 
264d7767217SJens Wiklander TEE_Result tee_fs_dirfile_fileh_to_fname(const struct tee_fs_dirfile_fileh *dfh,
265d7767217SJens Wiklander 					 char *fname, size_t *fnlen)
266d7767217SJens Wiklander {
267d7767217SJens Wiklander 	int r;
268d7767217SJens Wiklander 	size_t l = *fnlen;
269d7767217SJens Wiklander 
270d7767217SJens Wiklander 	if (dfh)
271d7767217SJens Wiklander 		r = snprintf(fname, l, "%" PRIx32, dfh->file_number);
272d7767217SJens Wiklander 	else
273d7767217SJens Wiklander 		r = snprintf(fname, l, "dirf.db");
274d7767217SJens Wiklander 
275d7767217SJens Wiklander 	if (r < 0)
276d7767217SJens Wiklander 		return TEE_ERROR_GENERIC;
277d7767217SJens Wiklander 
278d7767217SJens Wiklander 	*fnlen = r + 1;
279d7767217SJens Wiklander 	if ((size_t)r >= l)
280d7767217SJens Wiklander 		return TEE_ERROR_SHORT_BUFFER;
281d7767217SJens Wiklander 
282d7767217SJens Wiklander 	return TEE_SUCCESS;
283d7767217SJens Wiklander }
284d7767217SJens Wiklander 
285d7767217SJens Wiklander TEE_Result tee_fs_dirfile_rename(struct tee_fs_dirfile_dirh *dirh,
286*fd108c3eSJens Wiklander 				 const TEE_UUID *uuid,
287d7767217SJens Wiklander 				 struct tee_fs_dirfile_fileh *dfh,
288d7767217SJens Wiklander 				 const void *oid, size_t oidlen)
289d7767217SJens Wiklander {
290d7767217SJens Wiklander 	TEE_Result res;
291d7767217SJens Wiklander 	struct dirfile_entry dent;
292d7767217SJens Wiklander 
293d7767217SJens Wiklander 	if (!oidlen || oidlen > sizeof(dent.oid))
294d7767217SJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
295d7767217SJens Wiklander 	memset(&dent, 0, sizeof(dent));
296*fd108c3eSJens Wiklander 	dent.uuid = *uuid;
297d7767217SJens Wiklander 	memcpy(dent.oid, oid, oidlen);
298d7767217SJens Wiklander 	dent.oidlen = oidlen;
299d7767217SJens Wiklander 	memcpy(dent.hash, dfh->hash, sizeof(dent.hash));
300d7767217SJens Wiklander 	dent.file_number = dfh->file_number;
301d7767217SJens Wiklander 
302d7767217SJens Wiklander 	if (dfh->idx < 0) {
303d7767217SJens Wiklander 		struct tee_fs_dirfile_fileh dfh2;
304d7767217SJens Wiklander 
305*fd108c3eSJens Wiklander 		res = tee_fs_dirfile_find(dirh, uuid, oid, oidlen, &dfh2);
306d7767217SJens Wiklander 		if (res) {
307d7767217SJens Wiklander 			if (res == TEE_ERROR_ITEM_NOT_FOUND)
308*fd108c3eSJens Wiklander 				res = tee_fs_dirfile_find(dirh, uuid, NULL, 0,
309*fd108c3eSJens Wiklander 							  &dfh2);
310d7767217SJens Wiklander 			if (res)
311d7767217SJens Wiklander 				return res;
312d7767217SJens Wiklander 		}
313d7767217SJens Wiklander 		dfh->idx = dfh2.idx;
314d7767217SJens Wiklander 	}
315d7767217SJens Wiklander 
316d7767217SJens Wiklander 	return write_dent(dirh, dfh->idx, &dent);
317d7767217SJens Wiklander }
318d7767217SJens Wiklander 
319d7767217SJens Wiklander TEE_Result tee_fs_dirfile_remove(struct tee_fs_dirfile_dirh *dirh,
320d7767217SJens Wiklander 				 const struct tee_fs_dirfile_fileh *dfh)
321d7767217SJens Wiklander {
322d7767217SJens Wiklander 	TEE_Result res;
323d7767217SJens Wiklander 	struct dirfile_entry dent;
324d7767217SJens Wiklander 	uint32_t file_number;
325d7767217SJens Wiklander 
326d7767217SJens Wiklander 	res = read_dent(dirh, dfh->idx, &dent);
327d7767217SJens Wiklander 	if (res)
328d7767217SJens Wiklander 		return res;
329d7767217SJens Wiklander 
330d7767217SJens Wiklander 	if (!dent.oidlen)
331d7767217SJens Wiklander 		return TEE_SUCCESS;
332d7767217SJens Wiklander 
333d7767217SJens Wiklander 	file_number = dent.file_number;
334d7767217SJens Wiklander 	assert(dfh->file_number == file_number);
335d7767217SJens Wiklander 	assert(test_file(dirh, file_number));
336d7767217SJens Wiklander 
337d7767217SJens Wiklander 	memset(&dent, 0, sizeof(dent));
338d7767217SJens Wiklander 	res = write_dent(dirh, dfh->idx, &dent);
339d7767217SJens Wiklander 	if (!res)
340d7767217SJens Wiklander 		clear_file(dirh, file_number);
341d7767217SJens Wiklander 
342d7767217SJens Wiklander 	return res;
343d7767217SJens Wiklander }
344d7767217SJens Wiklander 
345d7767217SJens Wiklander TEE_Result tee_fs_dirfile_update_hash(struct tee_fs_dirfile_dirh *dirh,
346d7767217SJens Wiklander 				      const struct tee_fs_dirfile_fileh *dfh)
347d7767217SJens Wiklander {
348d7767217SJens Wiklander 	TEE_Result res;
349d7767217SJens Wiklander 	struct dirfile_entry dent;
350d7767217SJens Wiklander 
351d7767217SJens Wiklander 	res = read_dent(dirh, dfh->idx, &dent);
352d7767217SJens Wiklander 	if (res)
353d7767217SJens Wiklander 		return res;
354d7767217SJens Wiklander 	assert(dent.file_number == dfh->file_number);
355d7767217SJens Wiklander 	assert(test_file(dirh, dent.file_number));
356d7767217SJens Wiklander 
357d7767217SJens Wiklander 	memcpy(&dent.hash, dfh->hash, sizeof(dent.hash));
358d7767217SJens Wiklander 
359d7767217SJens Wiklander 	return write_dent(dirh, dfh->idx, &dent);
360d7767217SJens Wiklander }
361d7767217SJens Wiklander 
362d7767217SJens Wiklander TEE_Result tee_fs_dirfile_get_next(struct tee_fs_dirfile_dirh *dirh,
363*fd108c3eSJens Wiklander 				   const TEE_UUID *uuid, int *idx, void *oid,
364*fd108c3eSJens Wiklander 				   size_t *oidlen)
365d7767217SJens Wiklander {
366d7767217SJens Wiklander 	TEE_Result res;
367d7767217SJens Wiklander 	int i = *idx + 1;
368d7767217SJens Wiklander 	struct dirfile_entry dent;
369d7767217SJens Wiklander 
370d7767217SJens Wiklander 	if (i < 0)
371d7767217SJens Wiklander 		i = 0;
372d7767217SJens Wiklander 
373d7767217SJens Wiklander 	for (;; i++) {
374d7767217SJens Wiklander 		res = read_dent(dirh, i, &dent);
375d7767217SJens Wiklander 		if (res)
376d7767217SJens Wiklander 			return res;
377*fd108c3eSJens Wiklander 		if (!memcmp(&dent.uuid, uuid, sizeof(dent.uuid)) &&
378d7767217SJens Wiklander 		    dent.oidlen)
379d7767217SJens Wiklander 			break;
380d7767217SJens Wiklander 	}
381d7767217SJens Wiklander 
382d7767217SJens Wiklander 	if (*oidlen < dent.oidlen)
383d7767217SJens Wiklander 		return TEE_ERROR_SHORT_BUFFER;
384d7767217SJens Wiklander 
385d7767217SJens Wiklander 	memcpy(oid, dent.oid, dent.oidlen);
386d7767217SJens Wiklander 	*oidlen = dent.oidlen;
387d7767217SJens Wiklander 	*idx = i;
388d7767217SJens Wiklander 
389d7767217SJens Wiklander 	return TEE_SUCCESS;
390d7767217SJens Wiklander }
391