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, uint32_t min_counter) 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_CORRUPT_OBJECT; 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 if (ht->head.counter < min_counter) 364 return TEE_ERROR_SECURITY; 365 366 ht->root.id = 1; 367 368 return TEE_SUCCESS; 369 } 370 371 static TEE_Result init_tree_from_data(struct tee_fs_htree *ht) 372 { 373 TEE_Result res; 374 struct tee_fs_htree_node_image node_image; 375 struct htree_node *node; 376 struct htree_node *nc; 377 size_t committed_version; 378 size_t node_id = 2; 379 380 while (node_id <= ht->imeta.max_node_id) { 381 node = find_node(ht, node_id >> 1); 382 if (!node) 383 return TEE_ERROR_GENERIC; 384 committed_version = !!(node->node.flags & 385 HTREE_NODE_COMMITTED_CHILD(node_id & 1)); 386 387 res = rpc_read_node(ht, node_id, committed_version, 388 &node_image); 389 if (res != TEE_SUCCESS) 390 return res; 391 392 res = get_node(ht, true, node_id, &nc); 393 if (res != TEE_SUCCESS) 394 return res; 395 nc->node = node_image; 396 node_id++; 397 } 398 399 return TEE_SUCCESS; 400 } 401 402 static TEE_Result calc_node_hash(struct htree_node *node, 403 struct tee_fs_htree_meta *meta, void *ctx, 404 uint8_t *digest) 405 { 406 TEE_Result res; 407 uint8_t *ndata = (uint8_t *)&node->node + sizeof(node->node.hash); 408 size_t nsize = sizeof(node->node) - sizeof(node->node.hash); 409 410 res = crypto_hash_init(ctx); 411 if (res != TEE_SUCCESS) 412 return res; 413 414 res = crypto_hash_update(ctx, ndata, nsize); 415 if (res != TEE_SUCCESS) 416 return res; 417 418 if (meta) { 419 res = crypto_hash_update(ctx, (void *)meta, sizeof(*meta)); 420 if (res != TEE_SUCCESS) 421 return res; 422 } 423 424 if (node->child[0]) { 425 res = crypto_hash_update(ctx, node->child[0]->node.hash, 426 sizeof(node->child[0]->node.hash)); 427 if (res != TEE_SUCCESS) 428 return res; 429 } 430 431 if (node->child[1]) { 432 res = crypto_hash_update(ctx, node->child[1]->node.hash, 433 sizeof(node->child[1]->node.hash)); 434 if (res != TEE_SUCCESS) 435 return res; 436 } 437 438 return crypto_hash_final(ctx, digest, TEE_FS_HTREE_HASH_SIZE); 439 } 440 441 static TEE_Result authenc_init(void **ctx_ret, TEE_OperationMode mode, 442 struct tee_fs_htree *ht, 443 struct tee_fs_htree_node_image *ni, 444 size_t payload_len) 445 { 446 TEE_Result res = TEE_SUCCESS; 447 const uint32_t alg = TEE_FS_HTREE_AUTH_ENC_ALG; 448 void *ctx; 449 size_t aad_len = TEE_FS_HTREE_FEK_SIZE + TEE_FS_HTREE_IV_SIZE; 450 uint8_t *iv; 451 452 if (ni) { 453 iv = ni->iv; 454 } else { 455 iv = ht->head.iv; 456 aad_len += TEE_FS_HTREE_HASH_SIZE + sizeof(ht->head.counter); 457 } 458 459 if (mode == TEE_MODE_ENCRYPT) { 460 res = crypto_rng_read(iv, TEE_FS_HTREE_IV_SIZE); 461 if (res != TEE_SUCCESS) 462 return res; 463 } 464 465 res = crypto_authenc_alloc_ctx(&ctx, alg); 466 if (res != TEE_SUCCESS) 467 return res; 468 469 res = crypto_authenc_init(ctx, mode, ht->fek, TEE_FS_HTREE_FEK_SIZE, iv, 470 TEE_FS_HTREE_IV_SIZE, TEE_FS_HTREE_TAG_SIZE, 471 aad_len, payload_len); 472 if (res != TEE_SUCCESS) 473 goto err_free; 474 475 if (!ni) { 476 res = crypto_authenc_update_aad(ctx, mode, ht->root.node.hash, 477 TEE_FS_HTREE_FEK_SIZE); 478 if (res != TEE_SUCCESS) 479 goto err; 480 481 res = crypto_authenc_update_aad(ctx, mode, 482 (void *)&ht->head.counter, 483 sizeof(ht->head.counter)); 484 if (res != TEE_SUCCESS) 485 goto err; 486 } 487 488 res = crypto_authenc_update_aad(ctx, mode, ht->head.enc_fek, 489 TEE_FS_HTREE_FEK_SIZE); 490 if (res != TEE_SUCCESS) 491 goto err; 492 493 res = crypto_authenc_update_aad(ctx, mode, iv, 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); 502 err_free: 503 crypto_authenc_free_ctx(ctx); 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, crypt, len, plain, &out_size, tag, 515 TEE_FS_HTREE_TAG_SIZE); 516 crypto_authenc_final(ctx); 517 crypto_authenc_free_ctx(ctx); 518 519 if (res == TEE_SUCCESS && out_size != len) 520 return TEE_ERROR_GENERIC; 521 if (res == TEE_ERROR_MAC_INVALID) 522 return TEE_ERROR_CORRUPT_OBJECT; 523 524 return res; 525 } 526 527 static TEE_Result authenc_encrypt_final(void *ctx, uint8_t *tag, 528 const void *plain, size_t len, 529 void *crypt) 530 { 531 TEE_Result res; 532 size_t out_size = len; 533 size_t out_tag_size = TEE_FS_HTREE_TAG_SIZE; 534 535 res = crypto_authenc_enc_final(ctx, plain, len, crypt, &out_size, tag, 536 &out_tag_size); 537 crypto_authenc_final(ctx); 538 crypto_authenc_free_ctx(ctx); 539 540 if (res == TEE_SUCCESS && 541 (out_size != len || out_tag_size != TEE_FS_HTREE_TAG_SIZE)) 542 return TEE_ERROR_GENERIC; 543 544 return res; 545 } 546 547 static TEE_Result verify_root(struct tee_fs_htree *ht) 548 { 549 TEE_Result res; 550 void *ctx; 551 552 res = tee_fs_fek_crypt(ht->uuid, TEE_MODE_DECRYPT, ht->head.enc_fek, 553 sizeof(ht->fek), ht->fek); 554 if (res != TEE_SUCCESS) 555 return res; 556 557 res = authenc_init(&ctx, TEE_MODE_DECRYPT, ht, NULL, sizeof(ht->imeta)); 558 if (res != TEE_SUCCESS) 559 return res; 560 561 return authenc_decrypt_final(ctx, ht->head.tag, ht->head.imeta, 562 sizeof(ht->imeta), &ht->imeta); 563 } 564 565 static TEE_Result verify_node(struct traverse_arg *targ, 566 struct htree_node *node) 567 { 568 void *ctx = targ->arg; 569 TEE_Result res; 570 uint8_t digest[TEE_FS_HTREE_HASH_SIZE]; 571 572 if (node->parent) 573 res = calc_node_hash(node, NULL, ctx, digest); 574 else 575 res = calc_node_hash(node, &targ->ht->imeta.meta, ctx, digest); 576 if (res == TEE_SUCCESS && 577 consttime_memcmp(digest, node->node.hash, sizeof(digest))) 578 return TEE_ERROR_CORRUPT_OBJECT; 579 580 return res; 581 } 582 583 static TEE_Result verify_tree(struct tee_fs_htree *ht) 584 { 585 TEE_Result res; 586 void *ctx; 587 588 res = crypto_hash_alloc_ctx(&ctx, TEE_FS_HTREE_HASH_ALG); 589 if (res != TEE_SUCCESS) 590 return res; 591 592 res = htree_traverse_post_order(ht, verify_node, ctx); 593 crypto_hash_free_ctx(ctx); 594 595 return res; 596 } 597 598 static TEE_Result init_root_node(struct tee_fs_htree *ht) 599 { 600 TEE_Result res; 601 void *ctx; 602 603 res = crypto_hash_alloc_ctx(&ctx, TEE_FS_HTREE_HASH_ALG); 604 if (res != TEE_SUCCESS) 605 return res; 606 607 ht->root.id = 1; 608 ht->root.dirty = true; 609 610 res = calc_node_hash(&ht->root, &ht->imeta.meta, ctx, 611 ht->root.node.hash); 612 crypto_hash_free_ctx(ctx); 613 614 return res; 615 } 616 617 TEE_Result tee_fs_htree_open(bool create, uint8_t *hash, uint32_t min_counter, 618 const TEE_UUID *uuid, 619 const struct tee_fs_htree_storage *stor, 620 void *stor_aux, struct tee_fs_htree **ht_ret) 621 { 622 TEE_Result res; 623 struct tee_fs_htree *ht = calloc(1, sizeof(*ht)); 624 625 if (!ht) 626 return TEE_ERROR_OUT_OF_MEMORY; 627 628 ht->uuid = uuid; 629 ht->stor = stor; 630 ht->stor_aux = stor_aux; 631 632 if (create) { 633 const struct tee_fs_htree_image dummy_head = { 634 .counter = min_counter, 635 }; 636 637 res = crypto_rng_read(ht->fek, sizeof(ht->fek)); 638 if (res != TEE_SUCCESS) 639 goto out; 640 641 res = tee_fs_fek_crypt(ht->uuid, TEE_MODE_ENCRYPT, ht->fek, 642 sizeof(ht->fek), ht->head.enc_fek); 643 if (res != TEE_SUCCESS) 644 goto out; 645 646 res = init_root_node(ht); 647 if (res != TEE_SUCCESS) 648 goto out; 649 650 ht->dirty = true; 651 res = tee_fs_htree_sync_to_storage(&ht, hash, NULL); 652 if (res != TEE_SUCCESS) 653 goto out; 654 res = rpc_write_head(ht, 0, &dummy_head); 655 } else { 656 res = init_head_from_data(ht, hash, min_counter); 657 if (res != TEE_SUCCESS) 658 goto out; 659 660 res = verify_root(ht); 661 if (res != TEE_SUCCESS) 662 goto out; 663 664 res = init_tree_from_data(ht); 665 if (res != TEE_SUCCESS) 666 goto out; 667 668 res = verify_tree(ht); 669 } 670 out: 671 if (res == TEE_SUCCESS) 672 *ht_ret = ht; 673 else 674 tee_fs_htree_close(&ht); 675 return res; 676 } 677 678 struct tee_fs_htree_meta *tee_fs_htree_get_meta(struct tee_fs_htree *ht) 679 { 680 return &ht->imeta.meta; 681 } 682 683 void tee_fs_htree_meta_set_dirty(struct tee_fs_htree *ht) 684 { 685 ht->dirty = true; 686 ht->root.dirty = true; 687 } 688 689 static TEE_Result free_node(struct traverse_arg *targ __unused, 690 struct htree_node *node) 691 { 692 if (node->parent) 693 free(node); 694 return TEE_SUCCESS; 695 } 696 697 void tee_fs_htree_close(struct tee_fs_htree **ht) 698 { 699 if (!*ht) 700 return; 701 htree_traverse_post_order(*ht, free_node, NULL); 702 free(*ht); 703 *ht = NULL; 704 } 705 706 static TEE_Result htree_sync_node_to_storage(struct traverse_arg *targ, 707 struct htree_node *node) 708 { 709 TEE_Result res; 710 uint8_t vers; 711 struct tee_fs_htree_meta *meta = NULL; 712 713 /* 714 * The node can be dirty while the block isn't updated due to 715 * updated children, but if block is updated the node has to be 716 * dirty. 717 */ 718 assert(node->dirty >= node->block_updated); 719 720 if (!node->dirty) 721 return TEE_SUCCESS; 722 723 if (node->parent) { 724 uint32_t f = HTREE_NODE_COMMITTED_CHILD(node->id & 1); 725 726 node->parent->dirty = true; 727 node->parent->node.flags ^= f; 728 vers = !!(node->parent->node.flags & f); 729 } else { 730 /* 731 * Counter isn't updated yet, it's increased just before 732 * writing the header. 733 */ 734 vers = !(targ->ht->head.counter & 1); 735 meta = &targ->ht->imeta.meta; 736 } 737 738 res = calc_node_hash(node, meta, targ->arg, node->node.hash); 739 if (res != TEE_SUCCESS) 740 return res; 741 742 node->dirty = false; 743 node->block_updated = false; 744 745 return rpc_write_node(targ->ht, node->id, vers, &node->node); 746 } 747 748 static TEE_Result update_root(struct tee_fs_htree *ht) 749 { 750 TEE_Result res; 751 void *ctx; 752 753 ht->head.counter++; 754 755 res = authenc_init(&ctx, TEE_MODE_ENCRYPT, ht, NULL, sizeof(ht->imeta)); 756 if (res != TEE_SUCCESS) 757 return res; 758 759 return authenc_encrypt_final(ctx, ht->head.tag, &ht->imeta, 760 sizeof(ht->imeta), &ht->head.imeta); 761 } 762 763 TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht_arg, 764 uint8_t *hash, uint32_t *counter) 765 { 766 TEE_Result res; 767 struct tee_fs_htree *ht = *ht_arg; 768 void *ctx; 769 770 if (!ht) 771 return TEE_ERROR_CORRUPT_OBJECT; 772 773 if (!ht->dirty) 774 return TEE_SUCCESS; 775 776 res = crypto_hash_alloc_ctx(&ctx, TEE_FS_HTREE_HASH_ALG); 777 if (res != TEE_SUCCESS) 778 return res; 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 if (counter) 797 *counter = ht->head.counter; 798 out: 799 crypto_hash_free_ctx(ctx); 800 if (res != TEE_SUCCESS) 801 tee_fs_htree_close(ht_arg); 802 return res; 803 } 804 805 static TEE_Result get_block_node(struct tee_fs_htree *ht, bool create, 806 size_t block_num, struct htree_node **node) 807 { 808 TEE_Result res; 809 struct htree_node *nd; 810 811 res = get_node(ht, create, BLOCK_NUM_TO_NODE_ID(block_num), &nd); 812 if (res == TEE_SUCCESS) 813 *node = nd; 814 815 return res; 816 } 817 818 TEE_Result tee_fs_htree_write_block(struct tee_fs_htree **ht_arg, 819 size_t block_num, const void *block) 820 { 821 struct tee_fs_htree *ht = *ht_arg; 822 TEE_Result res; 823 struct tee_fs_rpc_operation op; 824 struct htree_node *node = NULL; 825 uint8_t block_vers; 826 void *ctx; 827 void *enc_block; 828 829 if (!ht) 830 return TEE_ERROR_CORRUPT_OBJECT; 831 832 res = get_block_node(ht, true, block_num, &node); 833 if (res != TEE_SUCCESS) 834 goto out; 835 836 if (!node->block_updated) 837 node->node.flags ^= HTREE_NODE_COMMITTED_BLOCK; 838 839 block_vers = !!(node->node.flags & HTREE_NODE_COMMITTED_BLOCK); 840 res = ht->stor->rpc_write_init(ht->stor_aux, &op, 841 TEE_FS_HTREE_TYPE_BLOCK, block_num, 842 block_vers, &enc_block); 843 if (res != TEE_SUCCESS) 844 goto out; 845 846 res = authenc_init(&ctx, TEE_MODE_ENCRYPT, ht, &node->node, 847 ht->stor->block_size); 848 if (res != TEE_SUCCESS) 849 goto out; 850 res = authenc_encrypt_final(ctx, node->node.tag, block, 851 ht->stor->block_size, enc_block); 852 if (res != TEE_SUCCESS) 853 goto out; 854 855 res = ht->stor->rpc_write_final(&op); 856 if (res != TEE_SUCCESS) 857 goto out; 858 859 node->block_updated = true; 860 node->dirty = true; 861 ht->dirty = true; 862 out: 863 if (res != TEE_SUCCESS) 864 tee_fs_htree_close(ht_arg); 865 return res; 866 } 867 868 TEE_Result tee_fs_htree_read_block(struct tee_fs_htree **ht_arg, 869 size_t block_num, void *block) 870 { 871 struct tee_fs_htree *ht = *ht_arg; 872 TEE_Result res; 873 struct tee_fs_rpc_operation op; 874 struct htree_node *node; 875 uint8_t block_vers; 876 size_t len; 877 void *ctx; 878 void *enc_block; 879 880 if (!ht) 881 return TEE_ERROR_CORRUPT_OBJECT; 882 883 res = get_block_node(ht, false, block_num, &node); 884 if (res != TEE_SUCCESS) 885 goto out; 886 887 block_vers = !!(node->node.flags & HTREE_NODE_COMMITTED_BLOCK); 888 res = ht->stor->rpc_read_init(ht->stor_aux, &op, 889 TEE_FS_HTREE_TYPE_BLOCK, block_num, 890 block_vers, &enc_block); 891 if (res != TEE_SUCCESS) 892 goto out; 893 894 res = ht->stor->rpc_read_final(&op, &len); 895 if (res != TEE_SUCCESS) 896 goto out; 897 if (len != ht->stor->block_size) { 898 res = TEE_ERROR_CORRUPT_OBJECT; 899 goto out; 900 } 901 902 res = authenc_init(&ctx, TEE_MODE_DECRYPT, ht, &node->node, 903 ht->stor->block_size); 904 if (res != TEE_SUCCESS) 905 goto out; 906 907 res = authenc_decrypt_final(ctx, node->node.tag, enc_block, 908 ht->stor->block_size, block); 909 out: 910 if (res != TEE_SUCCESS) 911 tee_fs_htree_close(ht_arg); 912 return res; 913 } 914 915 TEE_Result tee_fs_htree_truncate(struct tee_fs_htree **ht_arg, size_t block_num) 916 { 917 struct tee_fs_htree *ht = *ht_arg; 918 size_t node_id = BLOCK_NUM_TO_NODE_ID(block_num); 919 struct htree_node *node; 920 921 if (!ht) 922 return TEE_ERROR_CORRUPT_OBJECT; 923 924 while (node_id < ht->imeta.max_node_id) { 925 node = find_closest_node(ht, ht->imeta.max_node_id); 926 assert(node && node->id == ht->imeta.max_node_id); 927 assert(!node->child[0] && !node->child[1]); 928 assert(node->parent); 929 assert(node->parent->child[node->id & 1] == node); 930 node->parent->child[node->id & 1] = NULL; 931 free(node); 932 ht->imeta.max_node_id--; 933 ht->dirty = true; 934 } 935 936 return TEE_SUCCESS; 937 } 938