xref: /optee_os/core/tee/tadb.c (revision 5b25c76ac40f830867e3d60800120ffd7874e8dc)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <bitstring.h>
8 #include <crypto/crypto.h>
9 #include <kernel/mutex.h>
10 #include <kernel/thread.h>
11 #include <mm/mobj.h>
12 #include <optee_rpc_cmd.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <tee_api_defines_extensions.h>
16 #include <tee/tadb.h>
17 #include <tee/tee_fs.h>
18 #include <tee/tee_fs_rpc.h>
19 #include <tee/tee_pobj.h>
20 #include <tee/tee_svc_storage.h>
21 #include <utee_defines.h>
22 
23 #define TADB_MAX_BUFFER_SIZE	(64U * 1024)
24 
25 #define TADB_AUTH_ENC_ALG	TEE_ALG_AES_GCM
26 #define TADB_IV_SIZE		TEE_AES_BLOCK_SIZE
27 #define TADB_TAG_SIZE		TEE_AES_BLOCK_SIZE
28 #define TADB_KEY_SIZE		TEE_AES_MAX_KEY_SIZE
29 
30 struct tee_tadb_dir {
31 	const struct tee_file_operations *ops;
32 	struct tee_file_handle *fh;
33 	int nbits;
34 	bitstr_t *files;
35 };
36 
37 /*
38  * struct tadb_entry - TA database entry
39  * @prop:	 properties of TA
40  * @file_number: encrypted TA is stored in <file_number>.ta
41  * @iv:		 Initialization vector of the authentication crypto
42  * @tag:	 Tag used to validate the authentication encrypted TA
43  * @key:	 Key used to decrypt the TA
44  */
45 struct tadb_entry {
46 	struct tee_tadb_property prop;
47 	uint32_t file_number;
48 	uint8_t iv[TADB_IV_SIZE];
49 	uint8_t tag[TADB_TAG_SIZE];
50 	uint8_t key[TADB_KEY_SIZE];
51 };
52 
53 struct tadb_header {
54 	uint32_t opaque_len;
55 	uint8_t opaque[];
56 };
57 
58 struct tee_tadb_ta_write {
59 	struct tee_tadb_dir *db;
60 	int fd;
61 	struct tadb_entry entry;
62 	size_t pos;
63 	void *ctx;
64 };
65 
66 struct tee_tadb_ta_read {
67 	struct tee_tadb_dir *db;
68 	int fd;
69 	struct tadb_entry entry;
70 	size_t pos;
71 	void *ctx;
72 	struct mobj *ta_mobj;
73 	uint8_t *ta_buf;
74 };
75 
76 static const char tadb_obj_id[] = "ta.db";
77 static struct tee_tadb_dir *tadb_db;
78 static unsigned int tadb_db_refc;
79 static struct mutex tadb_mutex = MUTEX_INITIALIZER;
80 
81 static void file_num_to_str(char *buf, size_t blen, uint32_t file_number)
82 {
83 	snprintf(buf, blen, "%" PRIu32 ".ta", file_number);
84 }
85 
86 static bool is_null_uuid(const TEE_UUID *uuid)
87 {
88 	const TEE_UUID null_uuid = { 0 };
89 
90 	return !memcmp(uuid, &null_uuid, sizeof(*uuid));
91 }
92 
93 static TEE_Result ta_operation_open(unsigned int cmd, uint32_t file_number,
94 				    int *fd)
95 {
96 	struct mobj *mobj;
97 	TEE_Result res;
98 	void *va;
99 
100 	va = tee_fs_rpc_cache_alloc(TEE_FS_NAME_MAX, &mobj);
101 	if (!va)
102 		return TEE_ERROR_OUT_OF_MEMORY;
103 
104 	file_num_to_str(va, TEE_FS_NAME_MAX, file_number);
105 
106 	struct thread_param params[] = {
107 		[0] = THREAD_PARAM_VALUE(IN, cmd, 0, 0),
108 		[1] = THREAD_PARAM_MEMREF(IN, mobj, 0, TEE_FS_NAME_MAX),
109 		[2] = THREAD_PARAM_VALUE(OUT, 0, 0, 0),
110 	};
111 
112 	res = thread_rpc_cmd(OPTEE_RPC_CMD_FS, ARRAY_SIZE(params), params);
113 	if (!res)
114 		*fd = params[2].u.value.a;
115 
116 	return res;
117 }
118 
119 static TEE_Result ta_operation_remove(uint32_t file_number)
120 {
121 	struct mobj *mobj;
122 	void *va;
123 
124 	va = tee_fs_rpc_cache_alloc(TEE_FS_NAME_MAX, &mobj);
125 	if (!va)
126 		return TEE_ERROR_OUT_OF_MEMORY;
127 
128 	file_num_to_str(va, TEE_FS_NAME_MAX, file_number);
129 
130 	struct thread_param params[] = {
131 		[0] = THREAD_PARAM_VALUE(IN, OPTEE_RPC_FS_REMOVE, 0, 0),
132 		[1] = THREAD_PARAM_MEMREF(IN, mobj, 0, TEE_FS_NAME_MAX),
133 	};
134 
135 	return thread_rpc_cmd(OPTEE_RPC_CMD_FS, ARRAY_SIZE(params), params);
136 }
137 
138 static TEE_Result maybe_grow_files(struct tee_tadb_dir *db, int idx)
139 {
140 	void *p;
141 
142 	if (idx < db->nbits)
143 		return TEE_SUCCESS;
144 
145 	p = realloc(db->files, bitstr_size(idx + 1));
146 	if (!p)
147 		return TEE_ERROR_OUT_OF_MEMORY;
148 	db->files = p;
149 
150 	bit_nclear(db->files, db->nbits, idx);
151 	db->nbits = idx + 1;
152 
153 	return TEE_SUCCESS;
154 }
155 
156 static TEE_Result set_file(struct tee_tadb_dir *db, int idx)
157 {
158 	TEE_Result res = maybe_grow_files(db, idx);
159 
160 	if (!res)
161 		bit_set(db->files, idx);
162 
163 	return res;
164 }
165 
166 static void clear_file(struct tee_tadb_dir *db, int idx)
167 {
168 	if (idx < db->nbits)
169 		bit_clear(db->files, idx);
170 }
171 
172 static bool test_file(struct tee_tadb_dir *db, int idx)
173 {
174 	if (idx < db->nbits)
175 		return bit_test(db->files, idx);
176 
177 	return false;
178 }
179 
180 static TEE_Result read_ent(struct tee_tadb_dir *db, size_t idx,
181 			   struct tadb_entry *entry)
182 {
183 	size_t l = sizeof(*entry);
184 	TEE_Result res = db->ops->read(db->fh, idx * l, entry, &l);
185 
186 	if (!res && l != sizeof(*entry))
187 		return TEE_ERROR_ITEM_NOT_FOUND;
188 
189 	return res;
190 }
191 
192 static TEE_Result write_ent(struct tee_tadb_dir *db, size_t idx,
193 			    const struct tadb_entry *entry)
194 {
195 	const size_t l = sizeof(*entry);
196 
197 	return db->ops->write(db->fh, idx * l, entry, l);
198 }
199 
200 static TEE_Result tadb_open(struct tee_tadb_dir **db_ret)
201 {
202 	TEE_Result res;
203 	struct tee_tadb_dir *db = calloc(1, sizeof(*db));
204 	struct tee_pobj po = {
205 		.obj_id = (void *)tadb_obj_id,
206 		.obj_id_len = sizeof(tadb_obj_id)
207 	};
208 
209 	if (!db)
210 		return TEE_ERROR_OUT_OF_MEMORY;
211 
212 	db->ops = tee_svc_storage_file_ops(TEE_STORAGE_PRIVATE);
213 
214 	res = db->ops->open(&po, NULL, &db->fh);
215 	if (res == TEE_ERROR_ITEM_NOT_FOUND)
216 		res = db->ops->create(&po, false, NULL, 0, NULL, 0, NULL, 0,
217 				      &db->fh);
218 
219 	if (res)
220 		free(db);
221 	else
222 		*db_ret = db;
223 
224 	return res;
225 }
226 
227 static TEE_Result tee_tadb_open(struct tee_tadb_dir **db)
228 {
229 	TEE_Result res = TEE_SUCCESS;
230 
231 	mutex_lock(&tadb_mutex);
232 	if (!tadb_db_refc) {
233 		assert(!tadb_db);
234 		res = tadb_open(&tadb_db);
235 		if (res)
236 			goto err;
237 	}
238 	tadb_db_refc++;
239 	*db = tadb_db;
240 err:
241 	mutex_unlock(&tadb_mutex);
242 	return res;
243 }
244 
245 static void tadb_put(struct tee_tadb_dir *db)
246 {
247 	assert(db == tadb_db);
248 	mutex_lock(&tadb_mutex);
249 	assert(tadb_db_refc);
250 	tadb_db_refc--;
251 	if (!tadb_db_refc) {
252 		db->ops->close(&db->fh);
253 		free(db->files);
254 		free(db);
255 		tadb_db = NULL;
256 	}
257 	mutex_unlock(&tadb_mutex);
258 }
259 
260 static void tee_tadb_close(struct tee_tadb_dir *db)
261 {
262 	tadb_put(db);
263 }
264 
265 static TEE_Result tadb_authenc_init(TEE_OperationMode mode,
266 				    const struct tadb_entry *entry,
267 				    void **ctx_ret)
268 {
269 	TEE_Result res;
270 	void *ctx;
271 	const size_t enc_size = entry->prop.custom_size + entry->prop.bin_size;
272 
273 	res = crypto_authenc_alloc_ctx(&ctx, TADB_AUTH_ENC_ALG);
274 	if (res)
275 		return res;
276 
277 	res = crypto_authenc_init(ctx, mode, entry->key, sizeof(entry->key),
278 				  entry->iv, sizeof(entry->iv),
279 				  sizeof(entry->tag), 0, enc_size);
280 	if (res)
281 		crypto_authenc_free_ctx(ctx);
282 	else
283 		*ctx_ret = ctx;
284 
285 	return res;
286 }
287 
288 static TEE_Result tadb_update_payload(void *ctx, TEE_OperationMode mode,
289 				      const void *src, size_t len, void *dst)
290 {
291 	TEE_Result res;
292 	size_t sz = len;
293 
294 	res = crypto_authenc_update_payload(ctx, mode, (const uint8_t *)src,
295 					    len, dst, &sz);
296 	assert(res || sz == len);
297 	return res;
298 }
299 
300 static TEE_Result populate_files(struct tee_tadb_dir *db)
301 {
302 	TEE_Result res;
303 	size_t idx;
304 
305 	/*
306 	 * If db->files isn't NULL the bitfield is already populated and
307 	 * there's nothing left to do here for now.
308 	 */
309 	if (db->files)
310 		return TEE_SUCCESS;
311 
312 	/*
313 	 * Iterate over the TA database and set the bits in the bit field
314 	 * for used file numbers. Note that set_file() will allocate and
315 	 * grow the bitfield as needed.
316 	 *
317 	 * At the same time clean out duplicate file numbers, the first
318 	 * entry with the file number has precedence. Duplicate entries is
319 	 * not supposed to be able to happen, but if it still does better
320 	 * to clean it out here instead of letting the error spread with
321 	 * unexpected side effects.
322 	 */
323 	for (idx = 0;; idx++) {
324 		struct tadb_entry entry;
325 
326 		res = read_ent(db, idx, &entry);
327 		if (res) {
328 			if (res == TEE_ERROR_ITEM_NOT_FOUND)
329 				return TEE_SUCCESS;
330 			goto err;
331 		}
332 
333 		if (is_null_uuid(&entry.prop.uuid))
334 			continue;
335 
336 		if (test_file(db, entry.file_number)) {
337 			IMSG("Clearing duplicate file number %" PRIu32,
338 			     entry.file_number);
339 			memset(&entry, 0, sizeof(entry));
340 			res = write_ent(db, idx, &entry);
341 			if (res)
342 				goto err;
343 			continue;
344 		}
345 
346 		res = set_file(db, entry.file_number);
347 		if (res)
348 			goto err;
349 	}
350 
351 err:
352 	free(db->files);
353 	db->files = NULL;
354 	db->nbits = 0;
355 
356 	return res;
357 }
358 
359 TEE_Result tee_tadb_ta_create(const struct tee_tadb_property *property,
360 			      struct tee_tadb_ta_write **ta_ret)
361 {
362 	TEE_Result res;
363 	struct tee_tadb_ta_write *ta;
364 	int i = 0;
365 
366 	if (is_null_uuid(&property->uuid))
367 		return TEE_ERROR_GENERIC;
368 
369 	ta = calloc(1, sizeof(*ta));
370 	if (!ta)
371 		return TEE_ERROR_OUT_OF_MEMORY;
372 
373 	res = tee_tadb_open(&ta->db);
374 	if (res)
375 		goto err_free;
376 
377 	mutex_lock(&tadb_mutex);
378 
379 	/*
380 	 * Since we're going to search for next free file number below we
381 	 * need to populate the bitfield holding used file numbers.
382 	 */
383 	res = populate_files(ta->db);
384 	if (res)
385 		goto err_mutex;
386 
387 	if (ta->db->files) {
388 		bit_ffc(ta->db->files, ta->db->nbits, &i);
389 		if (i == -1)
390 			i = ta->db->nbits;
391 	}
392 
393 	res = set_file(ta->db, i);
394 	if (res)
395 		goto err_mutex;
396 
397 	mutex_unlock(&tadb_mutex);
398 
399 	ta->entry.file_number = i;
400 	ta->entry.prop = *property;
401 
402 	res = crypto_rng_read(ta->entry.iv, sizeof(ta->entry.iv));
403 	if (res)
404 		goto err_put;
405 
406 	res = crypto_rng_read(ta->entry.key, sizeof(ta->entry.key));
407 	if (res)
408 		goto err_put;
409 
410 	res = ta_operation_open(OPTEE_RPC_FS_CREATE, ta->entry.file_number,
411 				&ta->fd);
412 	if (res)
413 		goto err_put;
414 
415 	res = tadb_authenc_init(TEE_MODE_ENCRYPT, &ta->entry, &ta->ctx);
416 	if (res)
417 		goto err_put;
418 
419 	*ta_ret = ta;
420 
421 	return TEE_SUCCESS;
422 
423 err_mutex:
424 	mutex_unlock(&tadb_mutex);
425 err_put:
426 	tadb_put(ta->db);
427 err_free:
428 	free(ta);
429 
430 	return res;
431 }
432 
433 TEE_Result tee_tadb_ta_write(struct tee_tadb_ta_write *ta, const void *buf,
434 			     size_t len)
435 {
436 	TEE_Result res;
437 	const uint8_t *rb = buf;
438 	size_t rl = len;
439 	struct tee_fs_rpc_operation op;
440 
441 	while (rl) {
442 		size_t wl = MIN(rl, TADB_MAX_BUFFER_SIZE);
443 		void *wb;
444 
445 		res = tee_fs_rpc_write_init(&op, OPTEE_RPC_CMD_FS, ta->fd,
446 					    ta->pos, wl, &wb);
447 		if (res)
448 			return res;
449 
450 		res = tadb_update_payload(ta->ctx, TEE_MODE_ENCRYPT,
451 					  rb, wl, wb);
452 		if (res)
453 			return res;
454 
455 		res = tee_fs_rpc_write_final(&op);
456 		if (res)
457 			return res;
458 
459 		rl -= wl;
460 		rb += wl;
461 		ta->pos += wl;
462 	}
463 
464 	return TEE_SUCCESS;
465 }
466 
467 void tee_tadb_ta_close_and_delete(struct tee_tadb_ta_write *ta)
468 {
469 	crypto_authenc_final(ta->ctx);
470 	crypto_authenc_free_ctx(ta->ctx);
471 	tee_fs_rpc_close(OPTEE_RPC_CMD_FS, ta->fd);
472 	ta_operation_remove(ta->entry.file_number);
473 
474 	mutex_lock(&tadb_mutex);
475 	clear_file(ta->db, ta->entry.file_number);
476 	mutex_unlock(&tadb_mutex);
477 
478 	tadb_put(ta->db);
479 	free(ta);
480 }
481 
482 static TEE_Result find_ent(struct tee_tadb_dir *db, const TEE_UUID *uuid,
483 			   size_t *idx_ret, struct tadb_entry *entry_ret)
484 {
485 	TEE_Result res;
486 	size_t idx;
487 
488 	/*
489 	 * Search for the provided uuid, if it's found return the index it
490 	 * has together with TEE_SUCCESS.
491 	 *
492 	 * If the uuid can't be found return the number indexes together
493 	 * with TEE_ERROR_ITEM_NOT_FOUND.
494 	 */
495 	for (idx = 0;; idx++) {
496 		struct tadb_entry entry;
497 
498 		res = read_ent(db, idx, &entry);
499 		if (res) {
500 			if (res == TEE_ERROR_ITEM_NOT_FOUND)
501 				break;
502 			return res;
503 		}
504 
505 		if (!memcmp(&entry.prop.uuid, uuid, sizeof(*uuid))) {
506 			if (entry_ret)
507 				*entry_ret = entry;
508 			break;
509 		}
510 	}
511 
512 	*idx_ret = idx;
513 	return res;
514 }
515 
516 static TEE_Result find_free_ent_idx(struct tee_tadb_dir *db, size_t *idx)
517 {
518 	const TEE_UUID null_uuid = { 0 };
519 	TEE_Result res = find_ent(db, &null_uuid, idx, NULL);
520 
521 	/*
522 	 * Note that *idx is set to the number of entries on
523 	 * TEE_ERROR_ITEM_NOT_FOUND.
524 	 */
525 	if (res == TEE_ERROR_ITEM_NOT_FOUND)
526 		return TEE_SUCCESS;
527 	return res;
528 }
529 
530 TEE_Result tee_tadb_ta_close_and_commit(struct tee_tadb_ta_write *ta)
531 {
532 	TEE_Result res;
533 	size_t dsz = 0;
534 	size_t sz = sizeof(ta->entry.tag);
535 	size_t idx;
536 	struct tadb_entry old_ent;
537 	bool have_old_ent = false;
538 
539 	res = crypto_authenc_enc_final(ta->ctx, NULL, 0, NULL, &dsz,
540 				       ta->entry.tag, &sz);
541 	if (res)
542 		goto err;
543 
544 	tee_fs_rpc_close(OPTEE_RPC_CMD_FS, ta->fd);
545 
546 	mutex_lock(&tadb_mutex);
547 	/*
548 	 * First try to find an existing TA to replace. If there's one
549 	 * we'll use the entry, but we should also remove the old encrypted
550 	 * file.
551 	 *
552 	 * If there isn't an existing TA to replace, grab a new entry.
553 	 */
554 	res = find_ent(ta->db, &ta->entry.prop.uuid, &idx, &old_ent);
555 	if (!res) {
556 		have_old_ent = true;
557 	} else {
558 		res = find_free_ent_idx(ta->db, &idx);
559 		if (res)
560 			goto err_mutex;
561 	}
562 	res = write_ent(ta->db, idx, &ta->entry);
563 	if (res)
564 		goto err_mutex;
565 	if (have_old_ent)
566 		clear_file(ta->db, old_ent.file_number);
567 	mutex_unlock(&tadb_mutex);
568 
569 	crypto_authenc_final(ta->ctx);
570 	crypto_authenc_free_ctx(ta->ctx);
571 	tadb_put(ta->db);
572 	free(ta);
573 	if (have_old_ent)
574 		ta_operation_remove(old_ent.file_number);
575 	return TEE_SUCCESS;
576 
577 err_mutex:
578 	mutex_unlock(&tadb_mutex);
579 err:
580 	tee_tadb_ta_close_and_delete(ta);
581 	return res;
582 }
583 
584 TEE_Result tee_tadb_ta_delete(const TEE_UUID *uuid)
585 {
586 	const struct tadb_entry null_entry = { { { 0 } } };
587 	struct tee_tadb_dir *db;
588 	struct tadb_entry entry;
589 	size_t idx;
590 	TEE_Result res;
591 
592 	if (is_null_uuid(uuid))
593 		return TEE_ERROR_GENERIC;
594 
595 	res = tee_tadb_open(&db);
596 	if (res)
597 		return res;
598 
599 	mutex_lock(&tadb_mutex);
600 	res = find_ent(db, uuid, &idx, &entry);
601 	if (res) {
602 		mutex_unlock(&tadb_mutex);
603 		tee_tadb_close(db);
604 		return res;
605 	}
606 
607 	clear_file(db, entry.file_number);
608 	res = write_ent(db, idx, &null_entry);
609 	mutex_unlock(&tadb_mutex);
610 
611 	tee_tadb_close(db);
612 	if (res)
613 		return res;
614 
615 	ta_operation_remove(entry.file_number);
616 	return TEE_SUCCESS;
617 }
618 
619 TEE_Result tee_tadb_ta_open(const TEE_UUID *uuid,
620 			    struct tee_tadb_ta_read **ta_ret)
621 {
622 	TEE_Result res = TEE_SUCCESS;
623 	size_t idx = 0;
624 	struct tee_tadb_ta_read *ta = NULL;
625 
626 	if (is_null_uuid(uuid))
627 		return TEE_ERROR_GENERIC;
628 
629 	ta = calloc(1, sizeof(*ta));
630 	if (!ta)
631 		return TEE_ERROR_OUT_OF_MEMORY;
632 
633 	res = tee_tadb_open(&ta->db);
634 	if (res)
635 		goto err_free; /* Mustn't call tadb_put() */
636 
637 	mutex_read_lock(&tadb_mutex);
638 	res = find_ent(ta->db, uuid, &idx, &ta->entry);
639 	mutex_read_unlock(&tadb_mutex);
640 	if (res)
641 		goto err;
642 
643 	res = ta_operation_open(OPTEE_RPC_FS_OPEN, ta->entry.file_number,
644 				&ta->fd);
645 	if (res)
646 		goto err;
647 
648 	res = tadb_authenc_init(TEE_MODE_DECRYPT, &ta->entry, &ta->ctx);
649 	if (res)
650 		goto err;
651 
652 	*ta_ret = ta;
653 
654 	return TEE_SUCCESS;
655 err:
656 	tadb_put(ta->db);
657 err_free:
658 	free(ta);
659 	return res;
660 }
661 
662 const struct tee_tadb_property *
663 tee_tadb_ta_get_property(struct tee_tadb_ta_read *ta)
664 {
665 	return &ta->entry.prop;
666 }
667 
668 TEE_Result tee_tadb_get_tag(struct tee_tadb_ta_read *ta, uint8_t *tag,
669 			    unsigned int *tag_len)
670 {
671 	if (!tag || *tag_len < sizeof(ta->entry.tag)) {
672 		*tag_len = sizeof(ta->entry.tag);
673 		return TEE_ERROR_SHORT_BUFFER;
674 	}
675 	*tag_len = sizeof(ta->entry.tag);
676 
677 	memcpy(tag, ta->entry.tag, sizeof(ta->entry.tag));
678 
679 	return TEE_SUCCESS;
680 }
681 
682 static TEE_Result ta_load(struct tee_tadb_ta_read *ta)
683 {
684 	TEE_Result res;
685 	const size_t sz = ta->entry.prop.custom_size + ta->entry.prop.bin_size;
686 
687 	if (ta->ta_mobj)
688 		return TEE_SUCCESS;
689 
690 	ta->ta_mobj = thread_rpc_alloc_payload(sz);
691 	if (!ta->ta_mobj)
692 		return TEE_ERROR_OUT_OF_MEMORY;
693 
694 	ta->ta_buf = mobj_get_va(ta->ta_mobj, 0);
695 	assert(ta->ta_buf);
696 
697 	struct thread_param params[] = {
698 		[0] = THREAD_PARAM_VALUE(IN, OPTEE_RPC_FS_READ, ta->fd, 0),
699 		[1] = THREAD_PARAM_MEMREF(OUT, ta->ta_mobj, 0, sz),
700 	};
701 
702 	res = thread_rpc_cmd(OPTEE_RPC_CMD_FS, ARRAY_SIZE(params), params);
703 	if (res) {
704 		thread_rpc_free_payload(ta->ta_mobj);
705 		ta->ta_mobj = NULL;
706 	}
707 	return res;
708 }
709 
710 TEE_Result tee_tadb_ta_read(struct tee_tadb_ta_read *ta, void *buf, size_t *len)
711 {
712 	TEE_Result res;
713 	const size_t sz = ta->entry.prop.custom_size + ta->entry.prop.bin_size;
714 	size_t l = MIN(*len, sz - ta->pos);
715 
716 	res = ta_load(ta);
717 	if (res)
718 		return res;
719 
720 	if (buf) {
721 		res = tadb_update_payload(ta->ctx, TEE_MODE_DECRYPT,
722 					  ta->ta_buf + ta->pos, l, buf);
723 		if (res)
724 			return res;
725 	} else {
726 		size_t num_bytes = 0;
727 		size_t b_size = MIN(256U, l);
728 		uint8_t *b = malloc(b_size);
729 
730 		if (!b)
731 			return TEE_ERROR_OUT_OF_MEMORY;
732 
733 		while (num_bytes < l) {
734 			size_t n = MIN(b_size, l - num_bytes);
735 
736 			res = tadb_update_payload(ta->ctx, TEE_MODE_DECRYPT,
737 						  ta->ta_buf + ta->pos +
738 							num_bytes, n, b);
739 			if (res)
740 				break;
741 			num_bytes += n;
742 		}
743 
744 		free(b);
745 		if (res)
746 			return res;
747 	}
748 
749 	ta->pos += l;
750 	if (ta->pos == sz) {
751 		size_t dl = 0;
752 
753 		res = crypto_authenc_dec_final(ta->ctx, NULL, 0, NULL, &dl,
754 					       ta->entry.tag, TADB_TAG_SIZE);
755 		if (res)
756 			return res;
757 	}
758 	*len = l;
759 	return TEE_SUCCESS;
760 }
761 
762 void tee_tadb_ta_close(struct tee_tadb_ta_read *ta)
763 {
764 	crypto_authenc_final(ta->ctx);
765 	crypto_authenc_free_ctx(ta->ctx);
766 	if (ta->ta_mobj)
767 		thread_rpc_free_payload(ta->ta_mobj);
768 	tee_fs_rpc_close(OPTEE_RPC_CMD_FS, ta->fd);
769 	tadb_put(ta->db);
770 	free(ta);
771 }
772