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