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