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