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