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