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