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