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