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