1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <bitstring.h> 8 #include <crypto/crypto.h> 9 #include <kernel/mutex.h> 10 #include <kernel/thread.h> 11 #include <kernel/user_access.h> 12 #include <mm/mobj.h> 13 #include <optee_rpc_cmd.h> 14 #include <stdio.h> 15 #include <string.h> 16 #include <tee_api_defines_extensions.h> 17 #include <tee/tadb.h> 18 #include <tee/tee_fs.h> 19 #include <tee/tee_fs_rpc.h> 20 #include <tee/tee_pobj.h> 21 #include <tee/tee_svc_storage.h> 22 #include <utee_defines.h> 23 24 #define TADB_MAX_BUFFER_SIZE (64U * 1024) 25 26 #define TADB_AUTH_ENC_ALG TEE_ALG_AES_GCM 27 #define TADB_IV_SIZE TEE_AES_BLOCK_SIZE 28 #define TADB_TAG_SIZE TEE_AES_BLOCK_SIZE 29 #define TADB_KEY_SIZE TEE_AES_MAX_KEY_SIZE 30 31 struct tee_tadb_dir { 32 const struct tee_file_operations *ops; 33 struct tee_file_handle *fh; 34 int nbits; 35 bitstr_t *files; 36 }; 37 38 /* 39 * struct tadb_entry - TA database entry 40 * @prop: properties of TA 41 * @file_number: encrypted TA is stored in <file_number>.ta 42 * @iv: Initialization vector of the authentication crypto 43 * @tag: Tag used to validate the authentication encrypted TA 44 * @key: Key used to decrypt the TA 45 */ 46 struct tadb_entry { 47 struct tee_tadb_property prop; 48 uint32_t file_number; 49 uint8_t iv[TADB_IV_SIZE]; 50 uint8_t tag[TADB_TAG_SIZE]; 51 uint8_t key[TADB_KEY_SIZE]; 52 }; 53 54 struct tadb_header { 55 uint32_t opaque_len; 56 uint8_t opaque[]; 57 }; 58 59 struct tee_tadb_ta_write { 60 struct tee_tadb_dir *db; 61 int fd; 62 struct tadb_entry entry; 63 size_t pos; 64 void *ctx; 65 }; 66 67 struct tee_tadb_ta_read { 68 struct tee_tadb_dir *db; 69 int fd; 70 struct tadb_entry entry; 71 size_t pos; 72 void *ctx; 73 struct mobj *ta_mobj; 74 uint8_t *ta_buf; 75 }; 76 77 static const char tadb_obj_id[] = "ta.db"; 78 static struct tee_tadb_dir *tadb_db; 79 static unsigned int tadb_db_refc; 80 static struct mutex tadb_mutex = MUTEX_INITIALIZER; 81 82 static void file_num_to_str(char *buf, size_t blen, uint32_t file_number) 83 { 84 int rc __maybe_unused = 0; 85 86 rc = snprintf(buf, blen, "%" PRIu32 ".ta", file_number); 87 assert(rc >= 0); 88 } 89 90 static bool is_null_uuid(const TEE_UUID *uuid) 91 { 92 const TEE_UUID null_uuid = { 0 }; 93 94 return !memcmp(uuid, &null_uuid, sizeof(*uuid)); 95 } 96 97 static TEE_Result ta_operation_open(unsigned int cmd, uint32_t file_number, 98 int *fd) 99 { 100 struct thread_param params[3] = { }; 101 struct mobj *mobj = NULL; 102 TEE_Result res = TEE_SUCCESS; 103 void *va = NULL; 104 105 va = thread_rpc_shm_cache_alloc(THREAD_SHM_CACHE_USER_FS, 106 THREAD_SHM_TYPE_APPLICATION, 107 TEE_FS_NAME_MAX, &mobj); 108 if (!va) 109 return TEE_ERROR_OUT_OF_MEMORY; 110 111 file_num_to_str(va, TEE_FS_NAME_MAX, file_number); 112 113 params[0] = THREAD_PARAM_VALUE(IN, cmd, 0, 0); 114 params[1] = THREAD_PARAM_MEMREF(IN, mobj, 0, TEE_FS_NAME_MAX); 115 params[2] = THREAD_PARAM_VALUE(OUT, 0, 0, 0); 116 117 res = thread_rpc_cmd(OPTEE_RPC_CMD_FS, ARRAY_SIZE(params), params); 118 if (!res) 119 *fd = params[2].u.value.a; 120 121 return res; 122 } 123 124 static TEE_Result ta_operation_remove(uint32_t file_number) 125 { 126 struct thread_param params[2] = { }; 127 struct mobj *mobj = NULL; 128 void *va = NULL; 129 130 va = thread_rpc_shm_cache_alloc(THREAD_SHM_CACHE_USER_FS, 131 THREAD_SHM_TYPE_APPLICATION, 132 TEE_FS_NAME_MAX, &mobj); 133 if (!va) 134 return TEE_ERROR_OUT_OF_MEMORY; 135 136 file_num_to_str(va, TEE_FS_NAME_MAX, file_number); 137 138 params[0] = THREAD_PARAM_VALUE(IN, OPTEE_RPC_FS_REMOVE, 0, 0); 139 params[1] = THREAD_PARAM_MEMREF(IN, mobj, 0, TEE_FS_NAME_MAX); 140 141 return thread_rpc_cmd(OPTEE_RPC_CMD_FS, ARRAY_SIZE(params), params); 142 } 143 144 static TEE_Result maybe_grow_files(struct tee_tadb_dir *db, int idx) 145 { 146 void *p; 147 148 if (idx < db->nbits) 149 return TEE_SUCCESS; 150 151 p = realloc(db->files, bitstr_size(idx + 1)); 152 if (!p) 153 return TEE_ERROR_OUT_OF_MEMORY; 154 db->files = p; 155 156 bit_nclear(db->files, db->nbits, idx); 157 db->nbits = idx + 1; 158 159 return TEE_SUCCESS; 160 } 161 162 static TEE_Result set_file(struct tee_tadb_dir *db, int idx) 163 { 164 TEE_Result res = maybe_grow_files(db, idx); 165 166 if (!res) 167 bit_set(db->files, idx); 168 169 return res; 170 } 171 172 static void clear_file(struct tee_tadb_dir *db, int idx) 173 { 174 /* 175 * This is safe because db->nbits > 0 implies that 176 * db->files is non-NULL (see maybe_grow_files()). 177 */ 178 if (idx < db->nbits) 179 bit_clear(db->files, idx); 180 } 181 182 static bool test_file(struct tee_tadb_dir *db, int idx) 183 { 184 /* 185 * This is safe because db->nbits > 0 implies that 186 * db->files is non-NULL (see maybe_grow_files()). 187 */ 188 if (idx < db->nbits) 189 return bit_test(db->files, idx); 190 191 return false; 192 } 193 194 static TEE_Result read_ent(struct tee_tadb_dir *db, size_t idx, 195 struct tadb_entry *entry) 196 { 197 size_t l = sizeof(*entry); 198 TEE_Result res = db->ops->read(db->fh, idx * l, entry, NULL, &l); 199 200 if (!res && l != sizeof(*entry)) 201 return TEE_ERROR_ITEM_NOT_FOUND; 202 203 return res; 204 } 205 206 static TEE_Result write_ent(struct tee_tadb_dir *db, size_t idx, 207 const struct tadb_entry *entry) 208 { 209 const size_t l = sizeof(*entry); 210 211 return db->ops->write(db->fh, idx * l, entry, NULL, l); 212 } 213 214 static TEE_Result tadb_open(struct tee_tadb_dir **db_ret) 215 { 216 TEE_Result res; 217 struct tee_tadb_dir *db = calloc(1, sizeof(*db)); 218 struct tee_pobj po = { 219 .obj_id = (void *)tadb_obj_id, 220 .obj_id_len = sizeof(tadb_obj_id) 221 }; 222 223 if (!db) 224 return TEE_ERROR_OUT_OF_MEMORY; 225 226 db->ops = tee_svc_storage_file_ops(TEE_STORAGE_PRIVATE); 227 228 res = db->ops->open(&po, NULL, &db->fh); 229 if (res == TEE_ERROR_ITEM_NOT_FOUND) 230 res = db->ops->create(&po, false, NULL, 0, NULL, 0, 231 NULL, NULL, 0, &db->fh); 232 233 if (res) 234 free(db); 235 else 236 *db_ret = db; 237 238 return res; 239 } 240 241 static TEE_Result tee_tadb_open(struct tee_tadb_dir **db) 242 { 243 TEE_Result res = TEE_SUCCESS; 244 245 mutex_lock(&tadb_mutex); 246 if (!tadb_db_refc) { 247 assert(!tadb_db); 248 res = tadb_open(&tadb_db); 249 if (res) 250 goto err; 251 } 252 tadb_db_refc++; 253 *db = tadb_db; 254 err: 255 mutex_unlock(&tadb_mutex); 256 return res; 257 } 258 259 static void tadb_put(struct tee_tadb_dir *db) 260 { 261 assert(db == tadb_db); 262 mutex_lock(&tadb_mutex); 263 assert(tadb_db_refc); 264 tadb_db_refc--; 265 if (!tadb_db_refc) { 266 db->ops->close(&db->fh); 267 free(db->files); 268 free(db); 269 tadb_db = NULL; 270 } 271 mutex_unlock(&tadb_mutex); 272 } 273 274 static void tee_tadb_close(struct tee_tadb_dir *db) 275 { 276 tadb_put(db); 277 } 278 279 static TEE_Result tadb_authenc_init(TEE_OperationMode mode, 280 const struct tadb_entry *entry, 281 void **ctx_ret) 282 { 283 TEE_Result res; 284 void *ctx; 285 const size_t enc_size = entry->prop.custom_size + entry->prop.bin_size; 286 287 res = crypto_authenc_alloc_ctx(&ctx, TADB_AUTH_ENC_ALG); 288 if (res) 289 return res; 290 291 res = crypto_authenc_init(ctx, mode, entry->key, sizeof(entry->key), 292 entry->iv, sizeof(entry->iv), 293 sizeof(entry->tag), 0, enc_size); 294 if (res) 295 crypto_authenc_free_ctx(ctx); 296 else 297 *ctx_ret = ctx; 298 299 return res; 300 } 301 302 static TEE_Result tadb_update_payload(void *ctx, TEE_OperationMode mode, 303 const void *src, size_t len, void *dst) 304 { 305 TEE_Result res; 306 size_t sz = len; 307 308 res = crypto_authenc_update_payload(ctx, mode, (const uint8_t *)src, 309 len, dst, &sz); 310 assert(res || sz == len); 311 return res; 312 } 313 314 static TEE_Result populate_files(struct tee_tadb_dir *db) 315 { 316 TEE_Result res; 317 size_t idx; 318 319 /* 320 * If db->files isn't NULL the bitfield is already populated and 321 * there's nothing left to do here for now. 322 */ 323 if (db->nbits) 324 return TEE_SUCCESS; 325 326 /* 327 * Iterate over the TA database and set the bits in the bit field 328 * for used file numbers. Note that set_file() will allocate and 329 * grow the bitfield as needed. 330 * 331 * At the same time clean out duplicate file numbers, the first 332 * entry with the file number has precedence. Duplicate entries is 333 * not supposed to be able to happen, but if it still does better 334 * to clean it out here instead of letting the error spread with 335 * unexpected side effects. 336 */ 337 for (idx = 0;; idx++) { 338 struct tadb_entry entry; 339 340 res = read_ent(db, idx, &entry); 341 if (res) { 342 if (res == TEE_ERROR_ITEM_NOT_FOUND) 343 return TEE_SUCCESS; 344 goto err; 345 } 346 347 if (is_null_uuid(&entry.prop.uuid)) 348 continue; 349 350 if (test_file(db, entry.file_number)) { 351 IMSG("Clearing duplicate file number %" PRIu32, 352 entry.file_number); 353 memset(&entry, 0, sizeof(entry)); 354 res = write_ent(db, idx, &entry); 355 if (res) 356 goto err; 357 continue; 358 } 359 360 res = set_file(db, entry.file_number); 361 if (res) 362 goto err; 363 } 364 365 err: 366 free(db->files); 367 db->files = NULL; 368 db->nbits = 0; 369 370 return res; 371 } 372 373 TEE_Result tee_tadb_ta_create(const struct tee_tadb_property *property, 374 struct tee_tadb_ta_write **ta_ret) 375 { 376 TEE_Result res; 377 struct tee_tadb_ta_write *ta; 378 int i = 0; 379 380 if (is_null_uuid(&property->uuid)) 381 return TEE_ERROR_GENERIC; 382 383 ta = calloc(1, sizeof(*ta)); 384 if (!ta) 385 return TEE_ERROR_OUT_OF_MEMORY; 386 387 res = tee_tadb_open(&ta->db); 388 if (res) 389 goto err_free; 390 391 mutex_lock(&tadb_mutex); 392 393 /* 394 * Since we're going to search for next free file number below we 395 * need to populate the bitfield holding used file numbers. 396 */ 397 res = populate_files(ta->db); 398 if (res) 399 goto err_mutex; 400 401 if (ta->db->files) { 402 bit_ffc(ta->db->files, ta->db->nbits, &i); 403 if (i == -1) 404 i = ta->db->nbits; 405 } 406 407 res = set_file(ta->db, i); 408 if (res) 409 goto err_mutex; 410 411 mutex_unlock(&tadb_mutex); 412 413 ta->entry.file_number = i; 414 ta->entry.prop = *property; 415 416 res = crypto_rng_read(ta->entry.iv, sizeof(ta->entry.iv)); 417 if (res) 418 goto err_put; 419 420 res = crypto_rng_read(ta->entry.key, sizeof(ta->entry.key)); 421 if (res) 422 goto err_put; 423 424 res = ta_operation_open(OPTEE_RPC_FS_CREATE, ta->entry.file_number, 425 &ta->fd); 426 if (res) 427 goto err_put; 428 429 res = tadb_authenc_init(TEE_MODE_ENCRYPT, &ta->entry, &ta->ctx); 430 if (res) 431 goto err_put; 432 433 *ta_ret = ta; 434 435 return TEE_SUCCESS; 436 437 err_mutex: 438 mutex_unlock(&tadb_mutex); 439 err_put: 440 tadb_put(ta->db); 441 err_free: 442 free(ta); 443 444 return res; 445 } 446 447 TEE_Result tee_tadb_ta_write(struct tee_tadb_ta_write *ta, const void *buf, 448 size_t len) 449 { 450 TEE_Result res; 451 const uint8_t *rb = buf; 452 size_t rl = len; 453 struct tee_fs_rpc_operation op; 454 455 while (rl) { 456 size_t wl = MIN(rl, TADB_MAX_BUFFER_SIZE); 457 void *wb; 458 459 res = tee_fs_rpc_write_init(&op, OPTEE_RPC_CMD_FS, ta->fd, 460 ta->pos, wl, &wb); 461 if (res) 462 return res; 463 464 res = tadb_update_payload(ta->ctx, TEE_MODE_ENCRYPT, 465 rb, wl, wb); 466 if (res) 467 return res; 468 469 res = tee_fs_rpc_write_final(&op); 470 if (res) 471 return res; 472 473 rl -= wl; 474 rb += wl; 475 ta->pos += wl; 476 } 477 478 return TEE_SUCCESS; 479 } 480 481 void tee_tadb_ta_close_and_delete(struct tee_tadb_ta_write *ta) 482 { 483 crypto_authenc_final(ta->ctx); 484 crypto_authenc_free_ctx(ta->ctx); 485 tee_fs_rpc_close(OPTEE_RPC_CMD_FS, ta->fd); 486 ta_operation_remove(ta->entry.file_number); 487 488 mutex_lock(&tadb_mutex); 489 clear_file(ta->db, ta->entry.file_number); 490 mutex_unlock(&tadb_mutex); 491 492 tadb_put(ta->db); 493 free(ta); 494 } 495 496 static TEE_Result find_ent(struct tee_tadb_dir *db, const TEE_UUID *uuid, 497 size_t *idx_ret, struct tadb_entry *entry_ret) 498 { 499 TEE_Result res; 500 size_t idx; 501 502 /* 503 * Search for the provided uuid, if it's found return the index it 504 * has together with TEE_SUCCESS. 505 * 506 * If the uuid can't be found return the number indexes together 507 * with TEE_ERROR_ITEM_NOT_FOUND. 508 */ 509 for (idx = 0;; idx++) { 510 struct tadb_entry entry = { }; 511 512 res = read_ent(db, idx, &entry); 513 if (res) { 514 if (res == TEE_ERROR_ITEM_NOT_FOUND) 515 break; 516 return res; 517 } 518 519 if (!memcmp(&entry.prop.uuid, uuid, sizeof(*uuid))) { 520 if (entry_ret) 521 *entry_ret = entry; 522 break; 523 } 524 } 525 526 *idx_ret = idx; 527 return res; 528 } 529 530 static TEE_Result find_free_ent_idx(struct tee_tadb_dir *db, size_t *idx) 531 { 532 const TEE_UUID null_uuid = { 0 }; 533 TEE_Result res = find_ent(db, &null_uuid, idx, NULL); 534 535 /* 536 * Note that *idx is set to the number of entries on 537 * TEE_ERROR_ITEM_NOT_FOUND. 538 */ 539 if (res == TEE_ERROR_ITEM_NOT_FOUND) 540 return TEE_SUCCESS; 541 return res; 542 } 543 544 TEE_Result tee_tadb_ta_close_and_commit(struct tee_tadb_ta_write *ta) 545 { 546 TEE_Result res; 547 size_t dsz = 0; 548 size_t sz = sizeof(ta->entry.tag); 549 size_t idx; 550 struct tadb_entry old_ent; 551 bool have_old_ent = false; 552 553 res = crypto_authenc_enc_final(ta->ctx, NULL, 0, NULL, &dsz, 554 ta->entry.tag, &sz); 555 if (res) 556 goto err; 557 558 tee_fs_rpc_close(OPTEE_RPC_CMD_FS, ta->fd); 559 560 mutex_lock(&tadb_mutex); 561 /* 562 * First try to find an existing TA to replace. If there's one 563 * we'll use the entry, but we should also remove the old encrypted 564 * file. 565 * 566 * If there isn't an existing TA to replace, grab a new entry. 567 */ 568 res = find_ent(ta->db, &ta->entry.prop.uuid, &idx, &old_ent); 569 if (!res) { 570 have_old_ent = true; 571 } else { 572 res = find_free_ent_idx(ta->db, &idx); 573 if (res) 574 goto err_mutex; 575 } 576 res = write_ent(ta->db, idx, &ta->entry); 577 if (res) 578 goto err_mutex; 579 if (have_old_ent) 580 clear_file(ta->db, old_ent.file_number); 581 mutex_unlock(&tadb_mutex); 582 583 crypto_authenc_final(ta->ctx); 584 crypto_authenc_free_ctx(ta->ctx); 585 tadb_put(ta->db); 586 free(ta); 587 if (have_old_ent) 588 ta_operation_remove(old_ent.file_number); 589 return TEE_SUCCESS; 590 591 err_mutex: 592 mutex_unlock(&tadb_mutex); 593 err: 594 tee_tadb_ta_close_and_delete(ta); 595 return res; 596 } 597 598 TEE_Result tee_tadb_ta_delete(const TEE_UUID *uuid) 599 { 600 const struct tadb_entry null_entry = { { { 0 } } }; 601 struct tee_tadb_dir *db; 602 struct tadb_entry entry; 603 size_t idx; 604 TEE_Result res; 605 606 if (is_null_uuid(uuid)) 607 return TEE_ERROR_GENERIC; 608 609 res = tee_tadb_open(&db); 610 if (res) 611 return res; 612 613 mutex_lock(&tadb_mutex); 614 res = find_ent(db, uuid, &idx, &entry); 615 if (res) { 616 mutex_unlock(&tadb_mutex); 617 tee_tadb_close(db); 618 return res; 619 } 620 621 clear_file(db, entry.file_number); 622 res = write_ent(db, idx, &null_entry); 623 mutex_unlock(&tadb_mutex); 624 625 tee_tadb_close(db); 626 if (res) 627 return res; 628 629 ta_operation_remove(entry.file_number); 630 return TEE_SUCCESS; 631 } 632 633 TEE_Result tee_tadb_ta_open(const TEE_UUID *uuid, 634 struct tee_tadb_ta_read **ta_ret) 635 { 636 TEE_Result res = TEE_SUCCESS; 637 size_t idx = 0; 638 struct tee_tadb_ta_read *ta = NULL; 639 640 if (is_null_uuid(uuid)) 641 return TEE_ERROR_GENERIC; 642 643 ta = calloc(1, sizeof(*ta)); 644 if (!ta) 645 return TEE_ERROR_OUT_OF_MEMORY; 646 647 res = tee_tadb_open(&ta->db); 648 if (res) 649 goto err_free; /* Mustn't call tadb_put() */ 650 651 mutex_read_lock(&tadb_mutex); 652 res = find_ent(ta->db, uuid, &idx, &ta->entry); 653 mutex_read_unlock(&tadb_mutex); 654 if (res) 655 goto err; 656 657 res = ta_operation_open(OPTEE_RPC_FS_OPEN, ta->entry.file_number, 658 &ta->fd); 659 if (res) 660 goto err; 661 662 res = tadb_authenc_init(TEE_MODE_DECRYPT, &ta->entry, &ta->ctx); 663 if (res) 664 goto err; 665 666 *ta_ret = ta; 667 668 return TEE_SUCCESS; 669 err: 670 tadb_put(ta->db); 671 err_free: 672 free(ta); 673 return res; 674 } 675 676 const struct tee_tadb_property * 677 tee_tadb_ta_get_property(struct tee_tadb_ta_read *ta) 678 { 679 return &ta->entry.prop; 680 } 681 682 TEE_Result tee_tadb_get_tag(struct tee_tadb_ta_read *ta, uint8_t *tag, 683 unsigned int *tag_len) 684 { 685 if (!tag || *tag_len < sizeof(ta->entry.tag)) { 686 *tag_len = sizeof(ta->entry.tag); 687 return TEE_ERROR_SHORT_BUFFER; 688 } 689 *tag_len = sizeof(ta->entry.tag); 690 691 memcpy(tag, ta->entry.tag, sizeof(ta->entry.tag)); 692 693 return TEE_SUCCESS; 694 } 695 696 static TEE_Result ta_load(struct tee_tadb_ta_read *ta) 697 { 698 struct thread_param params[2] = { }; 699 TEE_Result res; 700 const size_t sz = ta->entry.prop.custom_size + ta->entry.prop.bin_size; 701 702 if (ta->ta_mobj) 703 return TEE_SUCCESS; 704 705 ta->ta_mobj = thread_rpc_alloc_payload(sz); 706 if (!ta->ta_mobj) 707 return TEE_ERROR_OUT_OF_MEMORY; 708 709 ta->ta_buf = mobj_get_va(ta->ta_mobj, 0, sz); 710 assert(ta->ta_buf); 711 712 params[0] = THREAD_PARAM_VALUE(IN, OPTEE_RPC_FS_READ, ta->fd, 0); 713 params[1] = THREAD_PARAM_MEMREF(OUT, ta->ta_mobj, 0, sz); 714 715 res = thread_rpc_cmd(OPTEE_RPC_CMD_FS, ARRAY_SIZE(params), params); 716 if (res) { 717 thread_rpc_free_payload(ta->ta_mobj); 718 ta->ta_mobj = NULL; 719 } 720 return res; 721 } 722 723 TEE_Result tee_tadb_ta_read(struct tee_tadb_ta_read *ta, void *buf_core, 724 void *buf_user, size_t *len) 725 { 726 TEE_Result res = TEE_SUCCESS; 727 const size_t sz = ta->entry.prop.custom_size + ta->entry.prop.bin_size; 728 size_t l = MIN(*len, sz - ta->pos); 729 size_t bb_len = MIN(1024U, l); 730 size_t num_bytes = 0; 731 size_t dst_len = 0; 732 void *dst = NULL; 733 void *bb = NULL; 734 735 res = ta_load(ta); 736 if (res) 737 return res; 738 739 if (buf_core) { 740 dst = buf_core; 741 dst_len = l; 742 } else { 743 bb = bb_alloc(bb_len); 744 if (!bb) 745 return TEE_ERROR_OUT_OF_MEMORY; 746 dst = bb; 747 dst_len = bb_len; 748 } 749 750 /* 751 * This loop will only run once if buf_core is non-NULL, but as 752 * many times as needed if the bounce buffer bb is used. That's why 753 * dst doesn't need to be updated in the loop. 754 */ 755 while (num_bytes < l) { 756 size_t n = MIN(dst_len, l - num_bytes); 757 758 res = tadb_update_payload(ta->ctx, TEE_MODE_DECRYPT, 759 ta->ta_buf + ta->pos + num_bytes, 760 n, dst); 761 if (res) 762 goto out; 763 764 if (buf_user) { 765 res = copy_to_user((uint8_t *)buf_user + num_bytes, 766 dst, n); 767 if (res) 768 goto out; 769 } 770 num_bytes += n; 771 } 772 773 ta->pos += l; 774 if (ta->pos == sz) { 775 size_t dl = 0; 776 777 res = crypto_authenc_dec_final(ta->ctx, NULL, 0, NULL, &dl, 778 ta->entry.tag, TADB_TAG_SIZE); 779 if (res) 780 return res; 781 } 782 *len = l; 783 out: 784 bb_free(bb, bb_len); 785 return res; 786 } 787 788 void tee_tadb_ta_close(struct tee_tadb_ta_read *ta) 789 { 790 crypto_authenc_final(ta->ctx); 791 crypto_authenc_free_ctx(ta->ctx); 792 if (ta->ta_mobj) 793 thread_rpc_free_payload(ta->ta_mobj); 794 tee_fs_rpc_close(OPTEE_RPC_CMD_FS, ta->fd); 795 tadb_put(ta->db); 796 free(ta); 797 } 798