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 struct tee_fs_htree_storage *stor; 120 void *stor_aux; 121 }; 122 123 struct traverse_arg; 124 typedef TEE_Result (*traverse_cb_t)(struct traverse_arg *targ, 125 struct htree_node *node); 126 struct traverse_arg { 127 struct tee_fs_htree *ht; 128 traverse_cb_t cb; 129 void *arg; 130 }; 131 132 static TEE_Result rpc_read(struct tee_fs_htree *ht, enum tee_fs_htree_type type, 133 size_t idx, size_t vers, void *data, size_t dlen) 134 { 135 TEE_Result res; 136 struct tee_fs_rpc_operation op; 137 size_t bytes; 138 void *p; 139 140 res = ht->stor->rpc_read_init(ht->stor_aux, &op, type, idx, vers, &p); 141 if (res != TEE_SUCCESS) 142 return res; 143 144 res = ht->stor->rpc_read_final(&op, &bytes); 145 if (res != TEE_SUCCESS) 146 return res; 147 148 if (bytes != dlen) 149 return TEE_ERROR_CORRUPT_OBJECT; 150 151 memcpy(data, p, dlen); 152 return TEE_SUCCESS; 153 } 154 155 static TEE_Result rpc_read_head(struct tee_fs_htree *ht, size_t vers, 156 struct tee_fs_htree_image *head) 157 { 158 return rpc_read(ht, TEE_FS_HTREE_TYPE_HEAD, 0, vers, 159 head, sizeof(*head)); 160 } 161 162 static TEE_Result rpc_read_node(struct tee_fs_htree *ht, size_t node_id, 163 size_t vers, 164 struct tee_fs_htree_node_image *node) 165 { 166 return rpc_read(ht, TEE_FS_HTREE_TYPE_NODE, node_id - 1, vers, 167 node, sizeof(*node)); 168 } 169 170 static TEE_Result rpc_write(struct tee_fs_htree *ht, 171 enum tee_fs_htree_type type, size_t idx, 172 size_t vers, const void *data, size_t dlen) 173 { 174 TEE_Result res; 175 struct tee_fs_rpc_operation op; 176 void *p; 177 178 res = ht->stor->rpc_write_init(ht->stor_aux, &op, type, idx, vers, &p); 179 if (res != TEE_SUCCESS) 180 return res; 181 182 memcpy(p, data, dlen); 183 return ht->stor->rpc_write_final(&op); 184 } 185 186 static TEE_Result rpc_write_head(struct tee_fs_htree *ht, size_t vers, 187 const struct tee_fs_htree_image *head) 188 { 189 return rpc_write(ht, TEE_FS_HTREE_TYPE_HEAD, 0, vers, 190 head, sizeof(*head)); 191 } 192 193 static TEE_Result rpc_write_node(struct tee_fs_htree *ht, size_t node_id, 194 size_t vers, 195 const struct tee_fs_htree_node_image *node) 196 { 197 return rpc_write(ht, TEE_FS_HTREE_TYPE_NODE, node_id - 1, vers, 198 node, sizeof(*node)); 199 } 200 201 static TEE_Result traverse_post_order(struct traverse_arg *targ, 202 struct htree_node *node) 203 { 204 TEE_Result res; 205 206 /* 207 * This function is recursing but not very deep, only with Log(N) 208 * maximum depth. 209 */ 210 211 if (!node) 212 return TEE_SUCCESS; 213 214 res = traverse_post_order(targ, node->child[0]); 215 if (res != TEE_SUCCESS) 216 return res; 217 218 res = traverse_post_order(targ, node->child[1]); 219 if (res != TEE_SUCCESS) 220 return res; 221 222 return targ->cb(targ, node); 223 } 224 225 static TEE_Result htree_traverse_post_order(struct tee_fs_htree *ht, 226 traverse_cb_t cb, void *arg) 227 { 228 struct traverse_arg targ = { ht, cb, arg }; 229 230 return traverse_post_order(&targ, &ht->root); 231 } 232 233 static size_t node_id_to_level(size_t node_id) 234 { 235 assert(node_id && node_id < UINT_MAX); 236 /* Calculate level of the node, root node (1) has level 1 */ 237 return sizeof(unsigned int) * 8 - __builtin_clz(node_id); 238 } 239 240 static struct htree_node *find_closest_node(struct tee_fs_htree *ht, 241 size_t node_id) 242 { 243 struct htree_node *node = &ht->root; 244 size_t level = node_id_to_level(node_id); 245 size_t n; 246 247 /* n = 1 because root node is level 1 */ 248 for (n = 1; n < level; n++) { 249 struct htree_node *child; 250 size_t bit_idx; 251 252 /* 253 * The difference between levels of the current node and 254 * the node we're looking for tells which bit decides 255 * direction in the tree. 256 * 257 * As the first bit has index 0 we'll subtract 1 258 */ 259 bit_idx = level - n - 1; 260 child = node->child[((node_id >> bit_idx) & 1)]; 261 if (!child) 262 return node; 263 node = child; 264 } 265 266 return node; 267 } 268 269 static struct htree_node *find_node(struct tee_fs_htree *ht, size_t node_id) 270 { 271 struct htree_node *node = find_closest_node(ht, node_id); 272 273 if (node && node->id == node_id) 274 return node; 275 return NULL; 276 } 277 278 static TEE_Result get_node(struct tee_fs_htree *ht, bool create, 279 size_t node_id, struct htree_node **node_ret) 280 { 281 struct htree_node *node; 282 struct htree_node *nc; 283 size_t n; 284 285 node = find_closest_node(ht, node_id); 286 if (!node) 287 return TEE_ERROR_GENERIC; 288 if (node->id == node_id) 289 goto ret_node; 290 291 /* 292 * Trying to read beyond end of file should be caught earlier than 293 * here. 294 */ 295 if (!create) 296 return TEE_ERROR_GENERIC; 297 298 /* 299 * Add missing nodes, some nodes may already be there. When we've 300 * processed the range all nodes up to node_id will be in the tree. 301 */ 302 for (n = node->id + 1; n <= node_id; n++) { 303 node = find_closest_node(ht, n); 304 if (node->id == n) 305 continue; 306 /* Node id n should be a child of node */ 307 assert((n >> 1) == node->id); 308 assert(!node->child[n & 1]); 309 310 nc = calloc(1, sizeof(*nc)); 311 if (!nc) 312 return TEE_ERROR_OUT_OF_MEMORY; 313 nc->id = n; 314 nc->parent = node; 315 node->child[n & 1] = nc; 316 node = nc; 317 } 318 319 if (node->id > ht->imeta.max_node_id) 320 ht->imeta.max_node_id = node->id; 321 322 ret_node: 323 *node_ret = node; 324 return TEE_SUCCESS; 325 } 326 327 static int get_idx_from_counter(uint32_t counter0, uint32_t counter1) 328 { 329 if (!(counter0 & 1)) { 330 if (!(counter1 & 1)) 331 return 0; 332 if (counter0 > counter1) 333 return 0; 334 else 335 return 1; 336 } 337 338 if (counter1 & 1) 339 return 1; 340 else 341 return -1; 342 } 343 344 static TEE_Result init_head_from_data(struct tee_fs_htree *ht) 345 { 346 TEE_Result res; 347 struct tee_fs_htree_image head[2]; 348 int idx; 349 350 for (idx = 0; idx < 2; idx++) { 351 res = rpc_read_head(ht, idx, head + idx); 352 if (res != TEE_SUCCESS) 353 return res; 354 } 355 356 idx = get_idx_from_counter(head[0].counter, head[1].counter); 357 if (idx < 0) 358 return TEE_ERROR_SECURITY; 359 360 res = rpc_read_node(ht, 1, idx, &ht->root.node); 361 if (res != TEE_SUCCESS) 362 return res; 363 364 ht->head = head[idx]; 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_ops.hash.init(ctx, alg); 410 if (res != TEE_SUCCESS) 411 return res; 412 413 res = crypto_ops.hash.update(ctx, alg, ndata, nsize); 414 if (res != TEE_SUCCESS) 415 return res; 416 417 if (node->child[0]) { 418 res = crypto_ops.hash.update(ctx, alg, 419 node->child[0]->node.hash, 420 sizeof(node->child[0]->node.hash)); 421 if (res != TEE_SUCCESS) 422 return res; 423 } 424 425 if (node->child[1]) { 426 res = crypto_ops.hash.update(ctx, alg, 427 node->child[1]->node.hash, 428 sizeof(node->child[1]->node.hash)); 429 if (res != TEE_SUCCESS) 430 return res; 431 } 432 433 return crypto_ops.hash.final(ctx, alg, digest, TEE_FS_HTREE_HASH_SIZE); 434 } 435 436 static TEE_Result authenc_init(void **ctx_ret, TEE_OperationMode mode, 437 struct tee_fs_htree *ht, 438 struct tee_fs_htree_node_image *ni, 439 size_t payload_len) 440 { 441 TEE_Result res = TEE_SUCCESS; 442 const uint32_t alg = TEE_FS_HTREE_AUTH_ENC_ALG; 443 uint8_t *ctx; 444 size_t ctx_size; 445 size_t aad_len = TEE_FS_HTREE_FEK_SIZE + TEE_FS_HTREE_IV_SIZE; 446 uint8_t *iv; 447 448 if (ni) { 449 iv = ni->iv; 450 } else { 451 iv = ht->head.iv; 452 aad_len += TEE_FS_HTREE_HASH_SIZE + sizeof(ht->head.counter); 453 } 454 455 if (mode == TEE_MODE_ENCRYPT) { 456 res = crypto_ops.prng.read(iv, TEE_FS_HTREE_IV_SIZE); 457 if (res != TEE_SUCCESS) 458 return res; 459 } 460 461 res = crypto_ops.authenc.get_ctx_size(alg, &ctx_size); 462 if (res != TEE_SUCCESS) 463 return res; 464 465 ctx = malloc(ctx_size); 466 if (!ctx) { 467 EMSG("request memory size %zu failed", ctx_size); 468 return TEE_ERROR_OUT_OF_MEMORY; 469 } 470 471 res = crypto_ops.authenc.init(ctx, alg, mode, 472 ht->fek, TEE_FS_HTREE_FEK_SIZE, 473 iv, TEE_FS_HTREE_IV_SIZE, 474 TEE_FS_HTREE_TAG_SIZE, aad_len, 475 payload_len); 476 if (res != TEE_SUCCESS) 477 goto exit; 478 479 if (!ni) { 480 res = crypto_ops.authenc.update_aad(ctx, alg, mode, 481 ht->root.node.hash, 482 TEE_FS_HTREE_FEK_SIZE); 483 if (res != TEE_SUCCESS) 484 goto exit; 485 486 res = crypto_ops.authenc.update_aad(ctx, alg, mode, 487 (void *)&ht->head.counter, 488 sizeof(ht->head.counter)); 489 if (res != TEE_SUCCESS) 490 goto exit; 491 } 492 493 res = crypto_ops.authenc.update_aad(ctx, alg, mode, ht->head.enc_fek, 494 TEE_FS_HTREE_FEK_SIZE); 495 if (res != TEE_SUCCESS) 496 goto exit; 497 498 res = crypto_ops.authenc.update_aad(ctx, alg, mode, iv, 499 TEE_FS_HTREE_IV_SIZE); 500 501 exit: 502 if (res == TEE_SUCCESS) 503 *ctx_ret = ctx; 504 else 505 free(ctx); 506 507 return res; 508 } 509 510 static TEE_Result authenc_decrypt_final(void *ctx, const uint8_t *tag, 511 const void *crypt, size_t len, 512 void *plain) 513 { 514 TEE_Result res; 515 size_t out_size = len; 516 517 res = crypto_ops.authenc.dec_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG, 518 crypt, len, plain, &out_size, 519 tag, TEE_FS_HTREE_TAG_SIZE); 520 crypto_ops.authenc.final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG); 521 free(ctx); 522 523 if (res == TEE_SUCCESS && out_size != len) 524 return TEE_ERROR_GENERIC; 525 if (res == TEE_ERROR_MAC_INVALID) 526 return TEE_ERROR_CORRUPT_OBJECT; 527 528 return res; 529 } 530 531 static TEE_Result authenc_encrypt_final(void *ctx, uint8_t *tag, 532 const void *plain, size_t len, 533 void *crypt) 534 { 535 TEE_Result res; 536 size_t out_size = len; 537 size_t out_tag_size = TEE_FS_HTREE_TAG_SIZE; 538 539 res = crypto_ops.authenc.enc_final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG, 540 plain, len, crypt, &out_size, 541 tag, &out_tag_size); 542 crypto_ops.authenc.final(ctx, TEE_FS_HTREE_AUTH_ENC_ALG); 543 free(ctx); 544 545 if (res == TEE_SUCCESS && 546 (out_size != len || out_tag_size != TEE_FS_HTREE_TAG_SIZE)) 547 return TEE_ERROR_GENERIC; 548 549 return res; 550 } 551 552 static TEE_Result verify_root(struct tee_fs_htree *ht) 553 { 554 TEE_Result res; 555 void *ctx; 556 557 res = tee_fs_fek_crypt(TEE_MODE_DECRYPT, ht->head.enc_fek, 558 sizeof(ht->fek), ht->fek); 559 if (res != TEE_SUCCESS) 560 return res; 561 562 res = authenc_init(&ctx, TEE_MODE_DECRYPT, ht, NULL, sizeof(ht->imeta)); 563 if (res != TEE_SUCCESS) 564 return res; 565 566 return authenc_decrypt_final(ctx, ht->head.tag, ht->head.imeta, 567 sizeof(ht->imeta), &ht->imeta); 568 } 569 570 static TEE_Result verify_node(struct traverse_arg *targ, 571 struct htree_node *node) 572 { 573 void *ctx = targ->arg; 574 TEE_Result res; 575 uint8_t digest[TEE_FS_HTREE_HASH_SIZE]; 576 577 res = calc_node_hash(node, ctx, digest); 578 if (res == TEE_SUCCESS && 579 buf_compare_ct(digest, node->node.hash, sizeof(digest))) 580 return TEE_ERROR_CORRUPT_OBJECT; 581 582 return res; 583 } 584 585 static TEE_Result verify_tree(struct tee_fs_htree *ht) 586 { 587 TEE_Result res; 588 size_t size; 589 void *ctx; 590 591 if (!crypto_ops.hash.get_ctx_size || !crypto_ops.hash.init || 592 !crypto_ops.hash.update || !crypto_ops.hash.final) 593 return TEE_ERROR_NOT_SUPPORTED; 594 595 res = crypto_ops.hash.get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); 596 if (res != TEE_SUCCESS) 597 return res; 598 599 ctx = malloc(size); 600 if (!ctx) 601 return TEE_ERROR_OUT_OF_MEMORY; 602 603 res = htree_traverse_post_order(ht, verify_node, ctx); 604 free(ctx); 605 606 return res; 607 } 608 609 static TEE_Result init_root_node(struct tee_fs_htree *ht) 610 { 611 TEE_Result res; 612 size_t size; 613 void *ctx; 614 615 res = crypto_ops.hash.get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); 616 if (res != TEE_SUCCESS) 617 return res; 618 ctx = malloc(size); 619 if (!ctx) 620 return TEE_ERROR_OUT_OF_MEMORY; 621 622 ht->root.id = 1; 623 624 res = calc_node_hash(&ht->root, ctx, ht->root.node.hash); 625 free(ctx); 626 627 return res; 628 } 629 630 TEE_Result tee_fs_htree_open(bool create, 631 const struct tee_fs_htree_storage *stor, 632 void *stor_aux, struct tee_fs_htree **ht_ret) 633 { 634 TEE_Result res; 635 struct tee_fs_htree *ht = calloc(1, sizeof(*ht)); 636 637 if (!ht) 638 return TEE_ERROR_OUT_OF_MEMORY; 639 640 ht->stor = stor; 641 ht->stor_aux = stor_aux; 642 643 if (create) { 644 const struct tee_fs_htree_image dummy_head = { .counter = 0 }; 645 646 res = crypto_ops.prng.read(ht->fek, sizeof(ht->fek)); 647 if (res != TEE_SUCCESS) 648 goto out; 649 650 res = tee_fs_fek_crypt(TEE_MODE_ENCRYPT, ht->fek, 651 sizeof(ht->fek), ht->head.enc_fek); 652 if (res != TEE_SUCCESS) 653 goto out; 654 655 res = init_root_node(ht); 656 if (res != TEE_SUCCESS) 657 goto out; 658 659 ht->dirty = true; 660 res = tee_fs_htree_sync_to_storage(&ht); 661 if (res != TEE_SUCCESS) 662 goto out; 663 res = rpc_write_head(ht, 0, &dummy_head); 664 } else { 665 res = init_head_from_data(ht); 666 if (res != TEE_SUCCESS) 667 goto out; 668 669 res = verify_root(ht); 670 if (res != TEE_SUCCESS) 671 goto out; 672 673 res = init_tree_from_data(ht); 674 if (res != TEE_SUCCESS) 675 goto out; 676 677 res = verify_tree(ht); 678 } 679 out: 680 if (res == TEE_SUCCESS) 681 *ht_ret = ht; 682 else 683 tee_fs_htree_close(&ht); 684 return res; 685 } 686 687 struct tee_fs_htree_meta *tee_fs_htree_get_meta(struct tee_fs_htree *ht) 688 { 689 return &ht->imeta.meta; 690 } 691 692 static TEE_Result free_node(struct traverse_arg *targ __unused, 693 struct htree_node *node) 694 { 695 if (node->parent) 696 free(node); 697 return TEE_SUCCESS; 698 } 699 700 void tee_fs_htree_close(struct tee_fs_htree **ht) 701 { 702 if (!*ht) 703 return; 704 htree_traverse_post_order(*ht, free_node, NULL); 705 free(*ht); 706 *ht = NULL; 707 } 708 709 static TEE_Result htree_sync_node_to_storage(struct traverse_arg *targ, 710 struct htree_node *node) 711 { 712 TEE_Result res; 713 uint8_t vers; 714 715 /* 716 * The node can be dirty while the block isn't updated due to 717 * updated children, but if block is updated the node has to be 718 * dirty. 719 */ 720 assert(node->dirty >= node->block_updated); 721 722 if (!node->dirty) 723 return TEE_SUCCESS; 724 725 if (node->parent) { 726 uint32_t f = HTREE_NODE_COMMITTED_CHILD(node->id & 1); 727 728 node->parent->dirty = true; 729 node->parent->node.flags ^= f; 730 vers = !!(node->parent->node.flags & f); 731 } else { 732 /* 733 * Counter isn't updated yet, it's increased just before 734 * writing the header. 735 */ 736 vers = !(targ->ht->head.counter & 1); 737 } 738 739 res = calc_node_hash(node, targ->arg, node->node.hash); 740 if (res != TEE_SUCCESS) 741 return res; 742 743 node->dirty = false; 744 node->block_updated = false; 745 746 return rpc_write_node(targ->ht, node->id, vers, &node->node); 747 } 748 749 static TEE_Result update_root(struct tee_fs_htree *ht) 750 { 751 TEE_Result res; 752 void *ctx; 753 754 ht->head.counter++; 755 756 res = authenc_init(&ctx, TEE_MODE_ENCRYPT, ht, NULL, sizeof(ht->imeta)); 757 if (res != TEE_SUCCESS) 758 return res; 759 760 return authenc_encrypt_final(ctx, ht->head.tag, &ht->imeta, 761 sizeof(ht->imeta), &ht->head.imeta); 762 } 763 764 TEE_Result tee_fs_htree_sync_to_storage(struct tee_fs_htree **ht_arg) 765 { 766 TEE_Result res; 767 struct tee_fs_htree *ht = *ht_arg; 768 size_t size; 769 void *ctx; 770 771 if (!ht) 772 return TEE_ERROR_CORRUPT_OBJECT; 773 774 if (!ht->dirty) 775 return TEE_SUCCESS; 776 777 res = crypto_ops.hash.get_ctx_size(TEE_FS_HTREE_HASH_ALG, &size); 778 if (res != TEE_SUCCESS) 779 return res; 780 ctx = malloc(size); 781 if (!ctx) 782 return TEE_ERROR_OUT_OF_MEMORY; 783 784 res = htree_traverse_post_order(ht, htree_sync_node_to_storage, ctx); 785 if (res != TEE_SUCCESS) 786 goto out; 787 788 /* All the nodes are written to storage now. Time to update root. */ 789 res = update_root(ht); 790 if (res != TEE_SUCCESS) 791 goto out; 792 793 res = rpc_write_head(ht, ht->head.counter & 1, &ht->head); 794 if (res != TEE_SUCCESS) 795 goto out; 796 797 ht->dirty = false; 798 out: 799 free(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