xref: /optee_os/core/tee/fs_htree.c (revision 023b04ce9a01a2b211891d5d17e463069e519369)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <config.h>
8 #include <crypto/crypto.h>
9 #include <initcall.h>
10 #include <kernel/tee_common_otp.h>
11 #include <stdlib.h>
12 #include <string_ext.h>
13 #include <string.h>
14 #include <tee/fs_htree.h>
15 #include <tee/tee_fs_key_manager.h>
16 #include <tee/tee_fs_rpc.h>
17 #include <utee_defines.h>
18 #include <util.h>
19 
20 #define TEE_FS_HTREE_CHIP_ID_SIZE	32
21 #define TEE_FS_HTREE_HASH_ALG		TEE_ALG_SHA256
22 #define TEE_FS_HTREE_TSK_SIZE		TEE_FS_HTREE_HASH_SIZE
23 #define TEE_FS_HTREE_ENC_ALG		TEE_ALG_AES_ECB_NOPAD
24 #define TEE_FS_HTREE_ENC_SIZE		TEE_AES_BLOCK_SIZE
25 #define TEE_FS_HTREE_SSK_SIZE		TEE_FS_HTREE_HASH_SIZE
26 
27 #define TEE_FS_HTREE_AUTH_ENC_ALG	TEE_ALG_AES_GCM
28 #define TEE_FS_HTREE_HMAC_ALG		TEE_ALG_HMAC_SHA256
29 
30 #define BLOCK_NUM_TO_NODE_ID(num)	((num) + 1)
31 
32 #define NODE_ID_TO_BLOCK_NUM(id)	((id) - 1)
33 
34 /*
35  * The hash tree is implemented as a binary tree with the purpose to ensure
36  * integrity of the data in the nodes. The data in the nodes their turn
37  * provides both integrity and confidentiality of the data blocks.
38  *
39  * The hash tree is saved in a file as:
40  * +----------------------------+
41  * | htree_image.0		|
42  * | htree_image.1		|
43  * +----------------------------+
44  * | htree_node_image.1.0	|
45  * | htree_node_image.1.1	|
46  * +----------------------------+
47  * | htree_node_image.2.0	|
48  * | htree_node_image.2.1	|
49  * +----------------------------+
50  * | htree_node_image.3.0	|
51  * | htree_node_image.3.1	|
52  * +----------------------------+
53  * | htree_node_image.4.0	|
54  * | htree_node_image.4.1	|
55  * +----------------------------+
56  * ...
57  *
58  * htree_image is the header of the file, there's two instances of it. One
59  * which is committed and the other is used when updating the file. Which
60  * is committed is indicated by the "counter" field, the one with the
61  * largest value is selected.
62  *
63  * htree_node_image is a node in the hash tree, each node has two instances
64  * which is committed is decided by the parent node .flag bit
65  * HTREE_NODE_COMMITTED_CHILD. Which version is the committed version of
66  * node 1 is determined by the by the lowest bit of the counter field in
67  * the header.
68  *
69  * Note that nodes start counting at 1 while blocks at 0, this means that
70  * block 0 is represented by node 1.
71  *
72  * Where different elements are stored in the file is managed by the file
73  * system.
74  */
75 
76 #define HTREE_NODE_COMMITTED_BLOCK	BIT32(0)
77 /* n is 0 or 1 */
78 #define HTREE_NODE_COMMITTED_CHILD(n)	BIT32(1 + (n))
79 
80 struct htree_node {
81 	size_t id;
82 	bool dirty;
83 	bool block_updated;
84 	struct tee_fs_htree_node_image node;
85 	struct htree_node *parent;
86 	struct htree_node *child[2];
87 };
88 
89 struct tee_fs_htree {
90 	struct htree_node root;
91 	struct tee_fs_htree_image head;
92 	uint8_t fek[TEE_FS_HTREE_FEK_SIZE];
93 	struct tee_fs_htree_imeta imeta;
94 	bool dirty;
95 	const TEE_UUID *uuid;
96 	const struct tee_fs_htree_storage *stor;
97 	void *stor_aux;
98 };
99 
100 struct traverse_arg;
101 typedef TEE_Result (*traverse_cb_t)(struct traverse_arg *targ,
102 				    struct htree_node *node);
103 struct traverse_arg {
104 	struct tee_fs_htree *ht;
105 	traverse_cb_t cb;
106 	void *arg;
107 };
108 
109 static TEE_Result rpc_read(struct tee_fs_htree *ht, enum tee_fs_htree_type type,
110 			   size_t idx, size_t vers, void *data, size_t dlen)
111 {
112 	TEE_Result res;
113 	struct tee_fs_rpc_operation op;
114 	size_t bytes;
115 	void *p;
116 
117 	res = ht->stor->rpc_read_init(ht->stor_aux, &op, type, idx, vers, &p);
118 	if (res != TEE_SUCCESS)
119 		return res;
120 
121 	res = ht->stor->rpc_read_final(&op, &bytes);
122 	if (res != TEE_SUCCESS)
123 		return res;
124 
125 	if (bytes != dlen)
126 		return TEE_ERROR_CORRUPT_OBJECT;
127 
128 	memcpy(data, p, dlen);
129 	return TEE_SUCCESS;
130 }
131 
132 static TEE_Result rpc_read_head(struct tee_fs_htree *ht, size_t vers,
133 				struct tee_fs_htree_image *head)
134 {
135 	return rpc_read(ht, TEE_FS_HTREE_TYPE_HEAD, 0, vers,
136 			head, sizeof(*head));
137 }
138 
139 static TEE_Result rpc_read_node(struct tee_fs_htree *ht, size_t node_id,
140 				size_t vers,
141 				struct tee_fs_htree_node_image *node)
142 {
143 	return rpc_read(ht, TEE_FS_HTREE_TYPE_NODE, node_id - 1, vers,
144 			node, sizeof(*node));
145 }
146 
147 static TEE_Result rpc_write(struct tee_fs_htree *ht,
148 			    enum tee_fs_htree_type type, size_t idx,
149 			    size_t vers, const void *data, size_t dlen)
150 {
151 	TEE_Result res;
152 	struct tee_fs_rpc_operation op;
153 	void *p;
154 
155 	res = ht->stor->rpc_write_init(ht->stor_aux, &op, type, idx, vers, &p);
156 	if (res != TEE_SUCCESS)
157 		return res;
158 
159 	memcpy(p, data, dlen);
160 	return ht->stor->rpc_write_final(&op);
161 }
162 
163 static TEE_Result rpc_write_head(struct tee_fs_htree *ht, size_t vers,
164 				 const struct tee_fs_htree_image *head)
165 {
166 	return rpc_write(ht, TEE_FS_HTREE_TYPE_HEAD, 0, vers,
167 			 head, sizeof(*head));
168 }
169 
170 static TEE_Result rpc_write_node(struct tee_fs_htree *ht, size_t node_id,
171 				 size_t vers,
172 				 const struct tee_fs_htree_node_image *node)
173 {
174 	return rpc_write(ht, TEE_FS_HTREE_TYPE_NODE, node_id - 1, vers,
175 			 node, sizeof(*node));
176 }
177 
178 static TEE_Result traverse_post_order(struct traverse_arg *targ,
179 				      struct htree_node *node)
180 {
181 	TEE_Result res;
182 
183 	/*
184 	 * This function is recursing but not very deep, only with Log(N)
185 	 * maximum depth.
186 	 */
187 
188 	if (!node)
189 		return TEE_SUCCESS;
190 
191 	res = traverse_post_order(targ, node->child[0]);
192 	if (res != TEE_SUCCESS)
193 		return res;
194 
195 	res = traverse_post_order(targ, node->child[1]);
196 	if (res != TEE_SUCCESS)
197 		return res;
198 
199 	return targ->cb(targ, node);
200 }
201 
202 static TEE_Result htree_traverse_post_order(struct tee_fs_htree *ht,
203 					    traverse_cb_t cb, void *arg)
204 {
205 	struct traverse_arg targ = { ht, cb, arg };
206 
207 	return traverse_post_order(&targ, &ht->root);
208 }
209 
210 static size_t node_id_to_level(size_t node_id)
211 {
212 	assert(node_id && node_id < UINT_MAX);
213 	/* Calculate level of the node, root node (1) has level 1 */
214 	return sizeof(unsigned int) * 8 - __builtin_clz(node_id);
215 }
216 
217 static struct htree_node *find_closest_node(struct tee_fs_htree *ht,
218 					    size_t node_id)
219 {
220 	struct htree_node *node = &ht->root;
221 	size_t level = node_id_to_level(node_id);
222 	size_t n;
223 
224 	/* n = 1 because root node is level 1 */
225 	for (n = 1; n < level; n++) {
226 		struct htree_node *child;
227 		size_t bit_idx;
228 
229 		/*
230 		 * The difference between levels of the current node and
231 		 * the node we're looking for tells which bit decides
232 		 * direction in the tree.
233 		 *
234 		 * As the first bit has index 0 we'll subtract 1
235 		 */
236 		bit_idx = level - n - 1;
237 		child = node->child[((node_id >> bit_idx) & 1)];
238 		if (!child)
239 			return node;
240 		node = child;
241 	}
242 
243 	return node;
244 }
245 
246 static struct htree_node *find_node(struct tee_fs_htree *ht, size_t node_id)
247 {
248 	struct htree_node *node = find_closest_node(ht, node_id);
249 
250 	if (node && node->id == node_id)
251 		return node;
252 	return NULL;
253 }
254 
255 static TEE_Result get_node(struct tee_fs_htree *ht, bool create,
256 			   size_t node_id, struct htree_node **node_ret)
257 {
258 	struct htree_node *node;
259 	struct htree_node *nc;
260 	size_t n;
261 
262 	node = find_closest_node(ht, node_id);
263 	if (!node)
264 		return TEE_ERROR_GENERIC;
265 	if (node->id == node_id)
266 		goto ret_node;
267 
268 	/*
269 	 * Trying to read beyond end of file should be caught earlier than
270 	 * here.
271 	 */
272 	if (!create)
273 		return TEE_ERROR_GENERIC;
274 
275 	/*
276 	 * Add missing nodes, some nodes may already be there. When we've
277 	 * processed the range all nodes up to node_id will be in the tree.
278 	 */
279 	for (n = node->id + 1; n <= node_id; n++) {
280 		node = find_closest_node(ht, n);
281 		if (node->id == n)
282 			continue;
283 		/* Node id n should be a child of node */
284 		assert((n >> 1) == node->id);
285 		assert(!node->child[n & 1]);
286 
287 		nc = calloc(1, sizeof(*nc));
288 		if (!nc)
289 			return TEE_ERROR_OUT_OF_MEMORY;
290 		nc->id = n;
291 		nc->parent = node;
292 		node->child[n & 1] = nc;
293 		node = nc;
294 	}
295 
296 	if (node->id > ht->imeta.max_node_id)
297 		ht->imeta.max_node_id = node->id;
298 
299 ret_node:
300 	*node_ret = node;
301 	return TEE_SUCCESS;
302 }
303 
304 static int get_idx_from_counter(uint32_t counter0, uint32_t counter1)
305 {
306 	if (!(counter0 & 1)) {
307 		if (!(counter1 & 1))
308 			return 0;
309 		if (counter0 > counter1)
310 			return 0;
311 		else
312 			return 1;
313 	}
314 
315 	if (counter1 & 1)
316 		return 1;
317 	else
318 		return -1;
319 }
320 
321 static TEE_Result init_head_from_data(struct tee_fs_htree *ht,
322 				      const uint8_t *hash, uint32_t min_counter)
323 {
324 	TEE_Result res;
325 	int idx;
326 
327 	if (hash) {
328 		for (idx = 0;; idx++) {
329 			res = rpc_read_node(ht, 1, idx, &ht->root.node);
330 			if (res != TEE_SUCCESS)
331 				return res;
332 
333 			if (!memcmp(ht->root.node.hash, hash,
334 				    sizeof(ht->root.node.hash))) {
335 				res = rpc_read_head(ht, idx, &ht->head);
336 				if (res != TEE_SUCCESS)
337 					return res;
338 				break;
339 			}
340 
341 			if (idx)
342 				return TEE_ERROR_CORRUPT_OBJECT;
343 		}
344 	} else {
345 		struct tee_fs_htree_image head[2];
346 
347 		for (idx = 0; idx < 2; idx++) {
348 			res = rpc_read_head(ht, idx, head + idx);
349 			if (res != TEE_SUCCESS)
350 				return res;
351 		}
352 
353 		idx = get_idx_from_counter(head[0].counter, head[1].counter);
354 		if (idx < 0)
355 			return TEE_ERROR_SECURITY;
356 
357 		res = rpc_read_node(ht, 1, idx, &ht->root.node);
358 		if (res != TEE_SUCCESS)
359 			return res;
360 
361 		ht->head = head[idx];
362 	}
363 
364 	if (ht->head.counter < min_counter)
365 		return TEE_ERROR_SECURITY;
366 
367 	ht->root.id = 1;
368 
369 	return TEE_SUCCESS;
370 }
371 
372 static TEE_Result init_tree_from_data(struct tee_fs_htree *ht)
373 {
374 	TEE_Result res;
375 	struct tee_fs_htree_node_image node_image;
376 	struct htree_node *node;
377 	struct htree_node *nc;
378 	size_t committed_version;
379 	size_t node_id = 2;
380 
381 	while (node_id <= ht->imeta.max_node_id) {
382 		node = find_node(ht, node_id >> 1);
383 		if (!node)
384 			return TEE_ERROR_GENERIC;
385 		committed_version = !!(node->node.flags &
386 				    HTREE_NODE_COMMITTED_CHILD(node_id & 1));
387 
388 		res = rpc_read_node(ht, node_id, committed_version,
389 				    &node_image);
390 		if (res != TEE_SUCCESS)
391 			return res;
392 
393 		res = get_node(ht, true, node_id, &nc);
394 		if (res != TEE_SUCCESS)
395 			return res;
396 		nc->node = node_image;
397 		node_id++;
398 	}
399 
400 	return TEE_SUCCESS;
401 }
402 
403 static TEE_Result calc_node_hash(struct htree_node *node,
404 				 struct tee_fs_htree_meta *meta, void *ctx,
405 				 uint8_t *digest)
406 {
407 	TEE_Result res;
408 	uint8_t *ndata = (uint8_t *)&node->node + sizeof(node->node.hash);
409 	size_t nsize = sizeof(node->node) - sizeof(node->node.hash);
410 
411 	res = crypto_hash_init(ctx);
412 	if (res != TEE_SUCCESS)
413 		return res;
414 
415 	res = crypto_hash_update(ctx, ndata, nsize);
416 	if (res != TEE_SUCCESS)
417 		return res;
418 
419 	if (meta) {
420 		res = crypto_hash_update(ctx, (void *)meta, sizeof(*meta));
421 		if (res != TEE_SUCCESS)
422 			return res;
423 	}
424 
425 	if (node->child[0]) {
426 		res = crypto_hash_update(ctx, node->child[0]->node.hash,
427 					 sizeof(node->child[0]->node.hash));
428 		if (res != TEE_SUCCESS)
429 			return res;
430 	}
431 
432 	if (node->child[1]) {
433 		res = crypto_hash_update(ctx, node->child[1]->node.hash,
434 					 sizeof(node->child[1]->node.hash));
435 		if (res != TEE_SUCCESS)
436 			return res;
437 	}
438 
439 	return crypto_hash_final(ctx, digest, TEE_FS_HTREE_HASH_SIZE);
440 }
441 
442 static TEE_Result authenc_init(void **ctx_ret, TEE_OperationMode mode,
443 			       struct tee_fs_htree *ht,
444 			       struct tee_fs_htree_node_image *ni,
445 			       size_t payload_len)
446 {
447 	TEE_Result res = TEE_SUCCESS;
448 	const uint32_t alg = TEE_FS_HTREE_AUTH_ENC_ALG;
449 	void *ctx;
450 	size_t aad_len = TEE_FS_HTREE_FEK_SIZE + TEE_FS_HTREE_IV_SIZE;
451 	uint8_t *iv;
452 
453 	if (ni) {
454 		iv = ni->iv;
455 	} else {
456 		iv = ht->head.iv;
457 		aad_len += sizeof(ht->head.counter);
458 
459 		/*
460 		 * With CFG_REE_FS_HTREE_HASH_SIZE_COMPAT, hash data passed
461 		 * for AAD is truncated to TEE_FS_HTREE_FEK_SIZE bytes so
462 		 * use the correct size aad_len computation.
463 		 */
464 		if (IS_ENABLED(CFG_REE_FS_HTREE_HASH_SIZE_COMPAT))
465 			aad_len += TEE_FS_HTREE_FEK_SIZE;
466 		else
467 			aad_len += TEE_FS_HTREE_HASH_SIZE;
468 	}
469 
470 	if (mode == TEE_MODE_ENCRYPT) {
471 		res = crypto_rng_read(iv, TEE_FS_HTREE_IV_SIZE);
472 		if (res != TEE_SUCCESS)
473 			return res;
474 	}
475 
476 	res = crypto_authenc_alloc_ctx(&ctx, alg);
477 	if (res != TEE_SUCCESS)
478 		return res;
479 
480 	res = crypto_authenc_init(ctx, mode, ht->fek, TEE_FS_HTREE_FEK_SIZE, iv,
481 				  TEE_FS_HTREE_IV_SIZE, TEE_FS_HTREE_TAG_SIZE,
482 				  aad_len, payload_len);
483 	if (res != TEE_SUCCESS)
484 		goto err_free;
485 
486 	if (!ni) {
487 		size_t hash_size = TEE_FS_HTREE_HASH_SIZE;
488 
489 		if (IS_ENABLED(CFG_REE_FS_HTREE_HASH_SIZE_COMPAT))
490 			hash_size = TEE_FS_HTREE_FEK_SIZE;
491 
492 		res = crypto_authenc_update_aad(ctx, mode, ht->root.node.hash,
493 						hash_size);
494 		if (res != TEE_SUCCESS)
495 			goto err;
496 
497 		res = crypto_authenc_update_aad(ctx, mode,
498 						(void *)&ht->head.counter,
499 						sizeof(ht->head.counter));
500 		if (res != TEE_SUCCESS)
501 			goto err;
502 	}
503 
504 	res = crypto_authenc_update_aad(ctx, mode, ht->head.enc_fek,
505 					TEE_FS_HTREE_FEK_SIZE);
506 	if (res != TEE_SUCCESS)
507 		goto err;
508 
509 	res = crypto_authenc_update_aad(ctx, mode, iv, TEE_FS_HTREE_IV_SIZE);
510 	if (res != TEE_SUCCESS)
511 		goto err;
512 
513 	*ctx_ret = ctx;
514 
515 	return TEE_SUCCESS;
516 err:
517 	crypto_authenc_final(ctx);
518 err_free:
519 	crypto_authenc_free_ctx(ctx);
520 	return res;
521 }
522 
523 static TEE_Result authenc_decrypt_final(void *ctx, const uint8_t *tag,
524 					const void *crypt, size_t len,
525 					void *plain)
526 {
527 	TEE_Result res;
528 	size_t out_size = len;
529 
530 	res = crypto_authenc_dec_final(ctx, crypt, len, plain, &out_size, tag,
531 				       TEE_FS_HTREE_TAG_SIZE);
532 	crypto_authenc_final(ctx);
533 	crypto_authenc_free_ctx(ctx);
534 
535 	if (res == TEE_SUCCESS && out_size != len)
536 		return TEE_ERROR_GENERIC;
537 	if (res == TEE_ERROR_MAC_INVALID)
538 		return TEE_ERROR_CORRUPT_OBJECT;
539 
540 	return res;
541 }
542 
543 static TEE_Result authenc_encrypt_final(void *ctx, uint8_t *tag,
544 					const void *plain, size_t len,
545 					void *crypt)
546 {
547 	TEE_Result res;
548 	size_t out_size = len;
549 	size_t out_tag_size = TEE_FS_HTREE_TAG_SIZE;
550 
551 	res = crypto_authenc_enc_final(ctx, plain, len, crypt, &out_size, tag,
552 				       &out_tag_size);
553 	crypto_authenc_final(ctx);
554 	crypto_authenc_free_ctx(ctx);
555 
556 	if (res == TEE_SUCCESS &&
557 	    (out_size != len || out_tag_size != TEE_FS_HTREE_TAG_SIZE))
558 		return TEE_ERROR_GENERIC;
559 
560 	return res;
561 }
562 
563 static TEE_Result verify_root(struct tee_fs_htree *ht)
564 {
565 	TEE_Result res;
566 	void *ctx;
567 
568 	res = tee_fs_fek_crypt(ht->uuid, TEE_MODE_DECRYPT, ht->head.enc_fek,
569 			       sizeof(ht->fek), ht->fek);
570 	if (res != TEE_SUCCESS)
571 		return res;
572 
573 	res = authenc_init(&ctx, TEE_MODE_DECRYPT, ht, NULL, sizeof(ht->imeta));
574 	if (res != TEE_SUCCESS)
575 		return res;
576 
577 	return authenc_decrypt_final(ctx, ht->head.tag, ht->head.imeta,
578 				     sizeof(ht->imeta), &ht->imeta);
579 }
580 
581 static TEE_Result verify_node(struct traverse_arg *targ,
582 			      struct htree_node *node)
583 {
584 	void *ctx = targ->arg;
585 	TEE_Result res;
586 	uint8_t digest[TEE_FS_HTREE_HASH_SIZE];
587 
588 	if (node->parent)
589 		res = calc_node_hash(node, NULL, ctx, digest);
590 	else
591 		res = calc_node_hash(node, &targ->ht->imeta.meta, ctx, digest);
592 	if (res == TEE_SUCCESS &&
593 	    consttime_memcmp(digest, node->node.hash, sizeof(digest)))
594 		return TEE_ERROR_CORRUPT_OBJECT;
595 
596 	return res;
597 }
598 
599 static TEE_Result verify_tree(struct tee_fs_htree *ht)
600 {
601 	TEE_Result res;
602 	void *ctx;
603 
604 	res = crypto_hash_alloc_ctx(&ctx, TEE_FS_HTREE_HASH_ALG);
605 	if (res != TEE_SUCCESS)
606 		return res;
607 
608 	res = htree_traverse_post_order(ht, verify_node, ctx);
609 	crypto_hash_free_ctx(ctx);
610 
611 	return res;
612 }
613 
614 static TEE_Result init_root_node(struct tee_fs_htree *ht)
615 {
616 	TEE_Result res;
617 	void *ctx;
618 
619 	res = crypto_hash_alloc_ctx(&ctx, TEE_FS_HTREE_HASH_ALG);
620 	if (res != TEE_SUCCESS)
621 		return res;
622 
623 	ht->root.id = 1;
624 	ht->root.dirty = true;
625 
626 	res = calc_node_hash(&ht->root, &ht->imeta.meta, ctx,
627 			     ht->root.node.hash);
628 	crypto_hash_free_ctx(ctx);
629 
630 	return res;
631 }
632 
633 static TEE_Result create_and_sync(struct tee_fs_htree **ht_arg,
634 				  uint8_t *hash,
635 				  uint32_t min_counter)
636 {
637 	TEE_Result res = TEE_ERROR_GENERIC;
638 	struct tee_fs_htree *ht = *ht_arg;
639 	const struct tee_fs_htree_image dummy_head = {
640 		.counter = min_counter,
641 	};
642 
643 	if (!ht)
644 		return TEE_ERROR_GENERIC;
645 
646 	res = crypto_rng_read(ht->fek, sizeof(ht->fek));
647 	if (res != TEE_SUCCESS)
648 		return res;
649 
650 	res = tee_fs_fek_crypt(ht->uuid, TEE_MODE_ENCRYPT, ht->fek,
651 			       sizeof(ht->fek), ht->head.enc_fek);
652 	if (res != TEE_SUCCESS)
653 		return res;
654 
655 	res = init_root_node(ht);
656 	if (res != TEE_SUCCESS)
657 		return res;
658 
659 	ht->dirty = true;
660 	res = tee_fs_htree_sync_to_storage(ht_arg, hash, NULL);
661 	if (res != TEE_SUCCESS)
662 		return res;
663 
664 	return rpc_write_head(*ht_arg, 0, &dummy_head);
665 }
666 
667 static bool ht_head_is_partially_done(const struct tee_fs_htree_image *head)
668 {
669 	uint8_t zero_tag[TEE_FS_HTREE_TAG_SIZE] = {0};
670 
671 	return head->counter == 0 &&
672 	       !memcmp(head->tag, zero_tag, sizeof(head->tag));
673 }
674 
675 TEE_Result tee_fs_htree_open(bool create, uint8_t *hash, uint32_t min_counter,
676 			     const TEE_UUID *uuid,
677 			     const struct tee_fs_htree_storage *stor,
678 			     void *stor_aux, struct tee_fs_htree **ht_ret)
679 {
680 	TEE_Result res;
681 	struct tee_fs_htree *ht = calloc(1, sizeof(*ht));
682 
683 	if (!ht)
684 		return TEE_ERROR_OUT_OF_MEMORY;
685 
686 	ht->uuid = uuid;
687 	ht->stor = stor;
688 	ht->stor_aux = stor_aux;
689 
690 	if (create) {
691 		res = create_and_sync(&ht, hash, min_counter);
692 	} else {
693 		res = init_head_from_data(ht, hash, min_counter);
694 		if (res != TEE_SUCCESS)
695 			goto out;
696 
697 		/*
698 		 * If a power loss occurred during hash tree creation, the
699 		 * head may not have been written and counter is still 0.
700 		 * Re-initialze the hash tree.
701 		 */
702 		if (ht_head_is_partially_done(&ht->head)) {
703 			res = create_and_sync(&ht, hash, min_counter);
704 			if (res != TEE_SUCCESS)
705 				goto out;
706 		}
707 
708 		res = verify_root(ht);
709 		if (res != TEE_SUCCESS)
710 			goto out;
711 
712 		res = init_tree_from_data(ht);
713 		if (res != TEE_SUCCESS)
714 			goto out;
715 
716 		res = verify_tree(ht);
717 	}
718 out:
719 	if (res == TEE_SUCCESS)
720 		*ht_ret = ht;
721 	else
722 		tee_fs_htree_close(&ht);
723 	return res;
724 }
725 
726 struct tee_fs_htree_meta *tee_fs_htree_get_meta(struct tee_fs_htree *ht)
727 {
728 	return &ht->imeta.meta;
729 }
730 
731 void tee_fs_htree_meta_set_dirty(struct tee_fs_htree *ht)
732 {
733 	ht->dirty = true;
734 	ht->root.dirty = true;
735 }
736 
737 static TEE_Result free_node(struct traverse_arg *targ __unused,
738 			    struct htree_node *node)
739 {
740 	if (node->parent)
741 		free(node);
742 	return TEE_SUCCESS;
743 }
744 
745 void tee_fs_htree_close(struct tee_fs_htree **ht)
746 {
747 	if (!*ht)
748 		return;
749 	htree_traverse_post_order(*ht, free_node, NULL);
750 	free(*ht);
751 	*ht = NULL;
752 }
753 
754 static TEE_Result htree_sync_node_to_storage(struct traverse_arg *targ,
755 					     struct htree_node *node)
756 {
757 	TEE_Result res;
758 	uint8_t vers;
759 	struct tee_fs_htree_meta *meta = NULL;
760 
761 	/*
762 	 * The node can be dirty while the block isn't updated due to
763 	 * updated children, but if block is updated the node has to be
764 	 * dirty.
765 	 */
766 	assert(node->dirty >= node->block_updated);
767 
768 	if (!node->dirty)
769 		return TEE_SUCCESS;
770 
771 	if (node->parent) {
772 		uint32_t f = HTREE_NODE_COMMITTED_CHILD(node->id & 1);
773 
774 		node->parent->dirty = true;
775 		node->parent->node.flags ^= f;
776 		vers = !!(node->parent->node.flags & f);
777 	} else {
778 		/*
779 		 * Counter isn't updated yet, it's increased just before
780 		 * writing the header.
781 		 */
782 		vers = !(targ->ht->head.counter & 1);
783 		meta = &targ->ht->imeta.meta;
784 	}
785 
786 	res = calc_node_hash(node, meta, targ->arg, node->node.hash);
787 	if (res != TEE_SUCCESS)
788 		return res;
789 
790 	node->dirty = false;
791 	node->block_updated = false;
792 
793 	return rpc_write_node(targ->ht, node->id, vers, &node->node);
794 }
795 
796 static TEE_Result update_root(struct tee_fs_htree *ht)
797 {
798 	TEE_Result res;
799 	void *ctx;
800 
801 	ht->head.counter++;
802 
803 	res = authenc_init(&ctx, TEE_MODE_ENCRYPT, ht, NULL, sizeof(ht->imeta));
804 	if (res != TEE_SUCCESS)
805 		return res;
806 
807 	return authenc_encrypt_final(ctx, ht->head.tag, &ht->imeta,
808 				     sizeof(ht->imeta), &ht->head.imeta);
809 }
810 
811 TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht_arg,
812 					uint8_t *hash, uint32_t *counter)
813 {
814 	TEE_Result res;
815 	struct tee_fs_htree *ht = *ht_arg;
816 	void *ctx;
817 
818 	if (!ht)
819 		return TEE_ERROR_CORRUPT_OBJECT;
820 
821 	if (!ht->dirty)
822 		return TEE_SUCCESS;
823 
824 	res = crypto_hash_alloc_ctx(&ctx, TEE_FS_HTREE_HASH_ALG);
825 	if (res != TEE_SUCCESS)
826 		return res;
827 
828 	res = htree_traverse_post_order(ht, htree_sync_node_to_storage, ctx);
829 	if (res != TEE_SUCCESS)
830 		goto out;
831 
832 	/* All the nodes are written to storage now. Time to update root. */
833 	res = update_root(ht);
834 	if (res != TEE_SUCCESS)
835 		goto out;
836 
837 	res = rpc_write_head(ht, ht->head.counter & 1, &ht->head);
838 	if (res != TEE_SUCCESS)
839 		goto out;
840 
841 	ht->dirty = false;
842 	if (hash)
843 		memcpy(hash, ht->root.node.hash, sizeof(ht->root.node.hash));
844 	if (counter)
845 		*counter = ht->head.counter;
846 out:
847 	crypto_hash_free_ctx(ctx);
848 	if (res != TEE_SUCCESS)
849 		tee_fs_htree_close(ht_arg);
850 	return res;
851 }
852 
853 static TEE_Result get_block_node(struct tee_fs_htree *ht, bool create,
854 				 size_t block_num, struct htree_node **node)
855 {
856 	TEE_Result res;
857 	struct htree_node *nd;
858 
859 	res = get_node(ht, create, BLOCK_NUM_TO_NODE_ID(block_num), &nd);
860 	if (res == TEE_SUCCESS)
861 		*node = nd;
862 
863 	return res;
864 }
865 
866 TEE_Result tee_fs_htree_write_block(struct tee_fs_htree **ht_arg,
867 				    size_t block_num, const void *block)
868 {
869 	struct tee_fs_htree *ht = *ht_arg;
870 	TEE_Result res;
871 	struct tee_fs_rpc_operation op;
872 	struct htree_node *node = NULL;
873 	uint8_t block_vers;
874 	void *ctx;
875 	void *enc_block;
876 
877 	if (!ht)
878 		return TEE_ERROR_CORRUPT_OBJECT;
879 
880 	res = get_block_node(ht, true, block_num, &node);
881 	if (res != TEE_SUCCESS)
882 		goto out;
883 
884 	if (!node->block_updated)
885 		node->node.flags ^= HTREE_NODE_COMMITTED_BLOCK;
886 
887 	block_vers = !!(node->node.flags & HTREE_NODE_COMMITTED_BLOCK);
888 	res = ht->stor->rpc_write_init(ht->stor_aux, &op,
889 				       TEE_FS_HTREE_TYPE_BLOCK, block_num,
890 				       block_vers, &enc_block);
891 	if (res != TEE_SUCCESS)
892 		goto out;
893 
894 	res = authenc_init(&ctx, TEE_MODE_ENCRYPT, ht, &node->node,
895 			   ht->stor->block_size);
896 	if (res != TEE_SUCCESS)
897 		goto out;
898 	res = authenc_encrypt_final(ctx, node->node.tag, block,
899 				    ht->stor->block_size, enc_block);
900 	if (res != TEE_SUCCESS)
901 		goto out;
902 
903 	res = ht->stor->rpc_write_final(&op);
904 	if (res != TEE_SUCCESS)
905 		goto out;
906 
907 	node->block_updated = true;
908 	node->dirty = true;
909 	ht->dirty = true;
910 out:
911 	if (res != TEE_SUCCESS)
912 		tee_fs_htree_close(ht_arg);
913 	return res;
914 }
915 
916 TEE_Result tee_fs_htree_read_block(struct tee_fs_htree **ht_arg,
917 				   size_t block_num, void *block)
918 {
919 	struct tee_fs_htree *ht = *ht_arg;
920 	TEE_Result res;
921 	struct tee_fs_rpc_operation op;
922 	struct htree_node *node;
923 	uint8_t block_vers;
924 	size_t len;
925 	void *ctx;
926 	void *enc_block;
927 
928 	if (!ht)
929 		return TEE_ERROR_CORRUPT_OBJECT;
930 
931 	res = get_block_node(ht, false, block_num, &node);
932 	if (res != TEE_SUCCESS)
933 		goto out;
934 
935 	block_vers = !!(node->node.flags & HTREE_NODE_COMMITTED_BLOCK);
936 	res = ht->stor->rpc_read_init(ht->stor_aux, &op,
937 				      TEE_FS_HTREE_TYPE_BLOCK, block_num,
938 				      block_vers, &enc_block);
939 	if (res != TEE_SUCCESS)
940 		goto out;
941 
942 	res = ht->stor->rpc_read_final(&op, &len);
943 	if (res != TEE_SUCCESS)
944 		goto out;
945 	if (len != ht->stor->block_size) {
946 		res = TEE_ERROR_CORRUPT_OBJECT;
947 		goto out;
948 	}
949 
950 	res = authenc_init(&ctx, TEE_MODE_DECRYPT, ht, &node->node,
951 			   ht->stor->block_size);
952 	if (res != TEE_SUCCESS)
953 		goto out;
954 
955 	res = authenc_decrypt_final(ctx, node->node.tag, enc_block,
956 				    ht->stor->block_size, block);
957 out:
958 	if (res != TEE_SUCCESS)
959 		tee_fs_htree_close(ht_arg);
960 	return res;
961 }
962 
963 TEE_Result tee_fs_htree_truncate(struct tee_fs_htree **ht_arg, size_t block_num)
964 {
965 	struct tee_fs_htree *ht = *ht_arg;
966 	size_t node_id = BLOCK_NUM_TO_NODE_ID(block_num);
967 	struct htree_node *node;
968 
969 	if (!ht)
970 		return TEE_ERROR_CORRUPT_OBJECT;
971 
972 	while (node_id < ht->imeta.max_node_id) {
973 		node = find_closest_node(ht, ht->imeta.max_node_id);
974 		assert(node && node->id == ht->imeta.max_node_id);
975 		assert(!node->child[0] && !node->child[1]);
976 		assert(node->parent);
977 		assert(node->parent->child[node->id & 1] == node);
978 		node->parent->child[node->id & 1] = NULL;
979 		free(node);
980 		ht->imeta.max_node_id--;
981 		ht->dirty = true;
982 	}
983 
984 	return TEE_SUCCESS;
985 }
986