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