1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017, 2019, Linaro Limited 4 * Copyright (c) 2020, Arm Limited. 5 */ 6 7 /* 8 * Security properties of REE-FS TAs 9 * ================================= 10 * 11 * Authentication only 12 * ------------------- 13 * 14 * Required security properties: 15 * 1. Authentication and non-repudiation of a TA to Service Provider (SP). 16 * 2. Integrity of a TA. 17 * 18 * To satisfy (1) and (2), SP needs to sign TA and OP-TEE core needs to verify 19 * the signature using SP public key with computed hash of the TA. 20 * 21 * Authentication along with Confidentiality 22 * ----------------------------------------- 23 * 24 * Required security properties: 25 * 1. Authentication and non-repudiation of a TA to Service Provider (SP). 26 * 2. Confidentiality of a TA. 27 * 3. Integrity of an encrypted TA blob. 28 * 29 * To satisfy (1), SP needs to sign plain TA and OP-TEE core needs to verify the 30 * signature using SP public key with computed hash of the TA. 31 * 32 * To satisfy (2) and (3), SP needs to do authenticated encryption of TA and 33 * OP-TEE core needs to do authenticated decryption of TA to retrieve its 34 * contents. Here encryption provides the confidentiality of TA and MAC tag 35 * provides the integrity of encrypted TA blob. 36 */ 37 38 #include <assert.h> 39 #include <crypto/crypto.h> 40 #include <fault_mitigation.h> 41 #include <initcall.h> 42 #include <kernel/thread.h> 43 #include <kernel/ts_store.h> 44 #include <mm/core_memprot.h> 45 #include <mm/mobj.h> 46 #include <mm/tee_mm.h> 47 #include <optee_rpc_cmd.h> 48 #include <signed_hdr.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <tee_api_defines_extensions.h> 52 #include <tee_api_types.h> 53 #include <tee/tee_pobj.h> 54 #include <tee/tee_svc_storage.h> 55 #include <tee/tee_ta_enc_manager.h> 56 #include <tee/uuid.h> 57 #include <utee_defines.h> 58 59 struct ree_fs_ta_handle { 60 struct shdr *nw_ta; /* Non-secure (shared memory) */ 61 size_t nw_ta_size; 62 struct mobj *mobj; 63 size_t offs; 64 struct shdr *shdr; /* Verified secure copy of @nw_ta's signed header */ 65 void *hash_ctx; 66 void *enc_ctx; 67 struct shdr_bootstrap_ta *bs_hdr; 68 struct shdr_encrypted_ta *ehdr; 69 }; 70 71 struct ver_db_entry { 72 uint8_t uuid[sizeof(TEE_UUID)]; 73 uint32_t version; 74 }; 75 76 struct ver_db_hdr { 77 uint32_t db_version; 78 uint32_t nb_entries; 79 }; 80 81 static const char ta_ver_db[] = "ta_ver.db"; 82 static const char subkey_ver_db[] = "subkey_ver.db"; 83 static struct mutex ver_db_mutex = MUTEX_INITIALIZER; 84 85 static TEE_Result check_update_version(const char *db_name, 86 const uint8_t uuid[sizeof(TEE_UUID)], 87 uint32_t version) 88 { 89 struct ver_db_entry db_entry = { }; 90 const struct tee_file_operations *ops = NULL; 91 struct tee_file_handle *fh = NULL; 92 TEE_Result res = TEE_SUCCESS; 93 bool entry_found = false; 94 size_t len = 0; 95 unsigned int i = 0; 96 struct ver_db_hdr db_hdr = { }; 97 struct tee_pobj pobj = { 98 .obj_id = (void *)db_name, 99 .obj_id_len = strlen(db_name) + 1, 100 }; 101 102 ops = tee_svc_storage_file_ops(TEE_STORAGE_PRIVATE); 103 if (!ops) 104 return TEE_SUCCESS; /* Compiled with no secure storage */ 105 106 mutex_lock(&ver_db_mutex); 107 108 res = ops->open(&pobj, NULL, &fh); 109 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND) 110 goto out; 111 112 if (res == TEE_ERROR_ITEM_NOT_FOUND) { 113 res = ops->create(&pobj, false, NULL, 0, NULL, 0, NULL, 0, &fh); 114 if (res != TEE_SUCCESS) 115 goto out; 116 117 res = ops->write(fh, 0, &db_hdr, sizeof(db_hdr)); 118 if (res != TEE_SUCCESS) 119 goto out; 120 } else { 121 len = sizeof(db_hdr); 122 123 res = ops->read(fh, 0, &db_hdr, &len); 124 if (res != TEE_SUCCESS) { 125 goto out; 126 } else if (len != sizeof(db_hdr)) { 127 res = TEE_ERROR_BAD_STATE; 128 goto out; 129 } 130 } 131 132 for (i = 0; i < db_hdr.nb_entries; i++) { 133 len = sizeof(db_entry); 134 135 res = ops->read(fh, sizeof(db_hdr) + (i * len), &db_entry, 136 &len); 137 if (res != TEE_SUCCESS) { 138 goto out; 139 } else if (len != sizeof(db_entry)) { 140 res = TEE_ERROR_BAD_STATE; 141 goto out; 142 } 143 144 if (!memcmp(uuid, db_entry.uuid, sizeof(TEE_UUID))) { 145 entry_found = true; 146 break; 147 } 148 } 149 150 if (entry_found) { 151 if (db_entry.version > version) { 152 res = TEE_ERROR_ACCESS_CONFLICT; 153 goto out; 154 } else if (db_entry.version < version) { 155 memcpy(db_entry.uuid, uuid, sizeof(TEE_UUID)); 156 db_entry.version = version; 157 len = sizeof(db_entry); 158 res = ops->write(fh, sizeof(db_hdr) + (i * len), 159 &db_entry, len); 160 if (res != TEE_SUCCESS) 161 goto out; 162 } 163 } else { 164 memcpy(db_entry.uuid, uuid, sizeof(TEE_UUID)); 165 db_entry.version = version; 166 len = sizeof(db_entry); 167 res = ops->write(fh, sizeof(db_hdr) + (db_hdr.nb_entries * len), 168 &db_entry, len); 169 if (res != TEE_SUCCESS) 170 goto out; 171 172 db_hdr.nb_entries++; 173 res = ops->write(fh, 0, &db_hdr, sizeof(db_hdr)); 174 if (res != TEE_SUCCESS) 175 goto out; 176 } 177 178 out: 179 ops->close(&fh); 180 mutex_unlock(&ver_db_mutex); 181 return res; 182 } 183 184 /* 185 * Load a TA via RPC with UUID defined by input param @uuid. The virtual 186 * address of the raw TA binary is received in out parameter @ta. 187 */ 188 static TEE_Result rpc_load(const TEE_UUID *uuid, struct shdr **ta, 189 size_t *ta_size, struct mobj **mobj) 190 { 191 TEE_Result res; 192 struct thread_param params[2]; 193 194 if (!uuid || !ta || !mobj || !ta_size) 195 return TEE_ERROR_BAD_PARAMETERS; 196 197 memset(params, 0, sizeof(params)); 198 params[0].attr = THREAD_PARAM_ATTR_VALUE_IN; 199 tee_uuid_to_octets((void *)¶ms[0].u.value, uuid); 200 params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT; 201 202 res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params); 203 if (res != TEE_SUCCESS) 204 return res; 205 206 *mobj = thread_rpc_alloc_payload(params[1].u.memref.size); 207 if (!*mobj) 208 return TEE_ERROR_OUT_OF_MEMORY; 209 210 *ta = mobj_get_va(*mobj, 0, params[1].u.memref.size); 211 if (!*ta) { 212 res = TEE_ERROR_SHORT_BUFFER; 213 goto exit; 214 } 215 /* We don't expect NULL as thread_rpc_alloc_payload() was successful */ 216 assert(*ta); 217 *ta_size = params[1].u.memref.size; 218 219 params[0].attr = THREAD_PARAM_ATTR_VALUE_IN; 220 tee_uuid_to_octets((void *)¶ms[0].u.value, uuid); 221 params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT; 222 params[1].u.memref.offs = 0; 223 params[1].u.memref.mobj = *mobj; 224 225 res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params); 226 exit: 227 if (res != TEE_SUCCESS) 228 thread_rpc_free_payload(*mobj); 229 230 return res; 231 } 232 233 static TEE_Result ree_fs_ta_open(const TEE_UUID *uuid, 234 struct ts_store_handle **h) 235 { 236 uint8_t next_uuid[sizeof(TEE_UUID)] = { }; 237 struct ree_fs_ta_handle *handle; 238 uint8_t *next_uuid_ptr = NULL; 239 struct shdr *shdr = NULL; 240 struct mobj *mobj = NULL; 241 void *hash_ctx = NULL; 242 struct shdr *ta = NULL; 243 size_t ta_size = 0; 244 TEE_Result res = TEE_SUCCESS; 245 size_t offs = 0; 246 struct shdr_bootstrap_ta *bs_hdr = NULL; 247 struct shdr_encrypted_ta *ehdr = NULL; 248 size_t shdr_sz = 0; 249 uint32_t max_depth = UINT32_MAX; 250 251 handle = calloc(1, sizeof(*handle)); 252 if (!handle) 253 return TEE_ERROR_OUT_OF_MEMORY; 254 255 /* Request TA from tee-supplicant */ 256 res = rpc_load(uuid, &ta, &ta_size, &mobj); 257 if (res != TEE_SUCCESS) 258 goto error; 259 260 /* Make secure copy of signed header */ 261 shdr = shdr_alloc_and_copy(0, ta, ta_size); 262 if (!shdr) { 263 res = TEE_ERROR_SECURITY; 264 goto error_free_payload; 265 } 266 267 /* Validate header signature */ 268 res = shdr_verify_signature(shdr); 269 if (res != TEE_SUCCESS) 270 goto error_free_payload; 271 272 shdr_sz = SHDR_GET_SIZE(shdr); 273 if (!shdr_sz) { 274 res = TEE_ERROR_SECURITY; 275 goto error_free_payload; 276 } 277 offs = shdr_sz; 278 279 while (shdr->img_type == SHDR_SUBKEY) { 280 struct shdr_pub_key pub_key = { }; 281 282 if (offs > ta_size) { 283 res = TEE_ERROR_SECURITY; 284 goto error_free_payload; 285 } 286 287 res = shdr_load_pub_key(shdr, offs, (const void *)ta, 288 ta_size, next_uuid_ptr, max_depth, 289 &pub_key); 290 if (res) 291 goto error_free_payload; 292 293 if (ADD_OVERFLOW(offs, shdr->img_size, &offs) || 294 ADD_OVERFLOW(offs, pub_key.name_size, &offs) || 295 offs > ta_size) { 296 res = TEE_ERROR_SECURITY; 297 goto error_free_payload; 298 } 299 max_depth = pub_key.max_depth; 300 memcpy(next_uuid, pub_key.next_uuid, sizeof(TEE_UUID)); 301 next_uuid_ptr = next_uuid; 302 303 res = check_update_version(subkey_ver_db, pub_key.uuid, 304 pub_key.version); 305 if (res) { 306 res = TEE_ERROR_SECURITY; 307 shdr_free_pub_key(&pub_key); 308 goto error_free_payload; 309 } 310 311 shdr_free(shdr); 312 shdr = shdr_alloc_and_copy(offs, ta, ta_size); 313 res = TEE_ERROR_SECURITY; 314 if (shdr) 315 res = shdr_verify_signature2(&pub_key, shdr); 316 shdr_free_pub_key(&pub_key); 317 if (res) 318 goto error_free_payload; 319 320 shdr_sz = SHDR_GET_SIZE(shdr); 321 if (!shdr_sz) { 322 res = TEE_ERROR_SECURITY; 323 goto error_free_payload; 324 } 325 offs += shdr_sz; 326 if (offs > ta_size) { 327 res = TEE_ERROR_SECURITY; 328 goto error_free_payload; 329 } 330 } 331 332 if (shdr->img_type != SHDR_TA && shdr->img_type != SHDR_BOOTSTRAP_TA && 333 shdr->img_type != SHDR_ENCRYPTED_TA) { 334 res = TEE_ERROR_SECURITY; 335 goto error_free_payload; 336 } 337 338 /* 339 * If we're verifying this TA using a subkey, make sure that 340 * the UUID of the TA belongs to the namespace defined by the subkey. 341 * The namespace is defined as in RFC4122, that is, valid UUID 342 * is calculated as a V5 UUID SHA-512(subkey UUID, "name string"). 343 */ 344 if (next_uuid_ptr) { 345 TEE_UUID check_uuid = { }; 346 347 tee_uuid_from_octets(&check_uuid, next_uuid_ptr); 348 if (memcmp(&check_uuid, uuid, sizeof(*uuid))) { 349 res = TEE_ERROR_SECURITY; 350 goto error_free_payload; 351 } 352 } 353 354 /* 355 * Initialize a hash context and run the algorithm over the signed 356 * header (less the final file hash and its signature of course) 357 */ 358 res = crypto_hash_alloc_ctx(&hash_ctx, 359 TEE_DIGEST_HASH_TO_ALGO(shdr->algo)); 360 if (res != TEE_SUCCESS) 361 goto error_free_payload; 362 res = crypto_hash_init(hash_ctx); 363 if (res != TEE_SUCCESS) 364 goto error_free_hash; 365 res = crypto_hash_update(hash_ctx, (uint8_t *)shdr, sizeof(*shdr)); 366 if (res != TEE_SUCCESS) 367 goto error_free_hash; 368 369 if (shdr->img_type == SHDR_BOOTSTRAP_TA || 370 shdr->img_type == SHDR_ENCRYPTED_TA) { 371 TEE_UUID bs_uuid = { }; 372 size_t sz = shdr_sz; 373 374 if (ADD_OVERFLOW(sz, sizeof(*bs_hdr), &sz) || ta_size < sz) { 375 res = TEE_ERROR_SECURITY; 376 goto error_free_hash; 377 } 378 379 bs_hdr = malloc(sizeof(*bs_hdr)); 380 if (!bs_hdr) { 381 res = TEE_ERROR_OUT_OF_MEMORY; 382 goto error_free_hash; 383 } 384 385 memcpy(bs_hdr, (uint8_t *)ta + offs, sizeof(*bs_hdr)); 386 387 /* 388 * There's a check later that the UUID embedded inside the 389 * ELF is matching, but since we now have easy access to 390 * the expected uuid of the TA we check it a bit earlier 391 * here. 392 */ 393 tee_uuid_from_octets(&bs_uuid, bs_hdr->uuid); 394 if (memcmp(&bs_uuid, uuid, sizeof(TEE_UUID))) { 395 res = TEE_ERROR_SECURITY; 396 goto error_free_hash; 397 } 398 399 res = crypto_hash_update(hash_ctx, (uint8_t *)bs_hdr, 400 sizeof(*bs_hdr)); 401 if (res != TEE_SUCCESS) 402 goto error_free_hash; 403 offs += sizeof(*bs_hdr); 404 handle->bs_hdr = bs_hdr; 405 } 406 407 if (shdr->img_type == SHDR_ENCRYPTED_TA) { 408 struct shdr_encrypted_ta img_ehdr = { }; 409 size_t sz = shdr_sz; 410 size_t ehdr_sz = 0; 411 412 if (ADD_OVERFLOW(sz, sizeof(struct shdr_bootstrap_ta), &sz) || 413 ADD_OVERFLOW(sz, sizeof(img_ehdr), &sz) || 414 ta_size < sz) { 415 res = TEE_ERROR_SECURITY; 416 goto error_free_hash; 417 } 418 419 memcpy(&img_ehdr, ((uint8_t *)ta + offs), sizeof(img_ehdr)); 420 ehdr_sz = SHDR_ENC_GET_SIZE(&img_ehdr); 421 sz -= sizeof(img_ehdr); 422 if (!ehdr_sz || ADD_OVERFLOW(sz, ehdr_sz, &sz) || 423 ta_size < sz) { 424 res = TEE_ERROR_SECURITY; 425 goto error_free_hash; 426 } 427 428 /* 429 * This is checked further down too, but we must sanity 430 * check shdr->img_size before it's used below. 431 */ 432 if (ta_size != sz + shdr->img_size) { 433 res = TEE_ERROR_SECURITY; 434 goto error_free_hash; 435 } 436 437 ehdr = malloc(ehdr_sz); 438 if (!ehdr) { 439 res = TEE_ERROR_OUT_OF_MEMORY; 440 goto error_free_hash; 441 } 442 443 *ehdr = img_ehdr; 444 memcpy((uint8_t *)ehdr + sizeof(img_ehdr), 445 (uint8_t *)ta + offs + sizeof(img_ehdr), 446 ehdr_sz - sizeof(img_ehdr)); 447 448 res = crypto_hash_update(hash_ctx, (uint8_t *)ehdr, ehdr_sz); 449 if (res != TEE_SUCCESS) 450 goto error_free_hash; 451 452 res = tee_ta_decrypt_init(&handle->enc_ctx, ehdr, 453 shdr->img_size); 454 if (res != TEE_SUCCESS) 455 goto error_free_hash; 456 457 offs += ehdr_sz; 458 handle->ehdr = ehdr; 459 } 460 461 if (ta_size != offs + shdr->img_size) { 462 res = TEE_ERROR_SECURITY; 463 goto error_free_hash; 464 } 465 466 handle->nw_ta = ta; 467 handle->nw_ta_size = ta_size; 468 handle->offs = offs; 469 handle->hash_ctx = hash_ctx; 470 handle->shdr = shdr; 471 handle->mobj = mobj; 472 *h = (struct ts_store_handle *)handle; 473 return TEE_SUCCESS; 474 475 error_free_hash: 476 crypto_hash_free_ctx(hash_ctx); 477 error_free_payload: 478 thread_rpc_free_payload(mobj); 479 error: 480 free(ehdr); 481 free(bs_hdr); 482 shdr_free(shdr); 483 free(handle); 484 return res; 485 } 486 487 static TEE_Result ree_fs_ta_get_size(const struct ts_store_handle *h, 488 size_t *size) 489 { 490 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 491 492 *size = handle->shdr->img_size; 493 return TEE_SUCCESS; 494 } 495 496 static TEE_Result ree_fs_ta_get_tag(const struct ts_store_handle *h, 497 uint8_t *tag, unsigned int *tag_len) 498 { 499 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 500 501 if (!tag || *tag_len < handle->shdr->hash_size) { 502 *tag_len = handle->shdr->hash_size; 503 return TEE_ERROR_SHORT_BUFFER; 504 } 505 *tag_len = handle->shdr->hash_size; 506 507 memcpy(tag, SHDR_GET_HASH(handle->shdr), handle->shdr->hash_size); 508 509 return TEE_SUCCESS; 510 } 511 512 static TEE_Result check_digest(struct ree_fs_ta_handle *h) 513 { 514 void *digest = NULL; 515 TEE_Result res; 516 517 digest = malloc(h->shdr->hash_size); 518 if (!digest) 519 return TEE_ERROR_OUT_OF_MEMORY; 520 res = crypto_hash_final(h->hash_ctx, digest, h->shdr->hash_size); 521 if (res != TEE_SUCCESS) { 522 res = TEE_ERROR_SECURITY; 523 goto out; 524 } 525 if (FTMN_CALLEE_DONE_MEMCMP(memcmp, digest, SHDR_GET_HASH(h->shdr), 526 h->shdr->hash_size)) 527 res = TEE_ERROR_SECURITY; 528 out: 529 free(digest); 530 return res; 531 } 532 533 static TEE_Result ree_fs_ta_read(struct ts_store_handle *h, void *data, 534 size_t len) 535 { 536 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 537 538 uint8_t *src = (uint8_t *)handle->nw_ta + handle->offs; 539 size_t next_offs = 0; 540 uint8_t *dst = src; 541 TEE_Result res = TEE_SUCCESS; 542 543 if (ADD_OVERFLOW(handle->offs, len, &next_offs) || 544 next_offs > handle->nw_ta_size) 545 return TEE_ERROR_BAD_PARAMETERS; 546 547 if (handle->shdr->img_type == SHDR_ENCRYPTED_TA) { 548 if (data) { 549 dst = data; /* Hash secure buffer */ 550 res = tee_ta_decrypt_update(handle->enc_ctx, dst, src, 551 len); 552 if (res != TEE_SUCCESS) 553 return TEE_ERROR_SECURITY; 554 } else { 555 size_t num_bytes = 0; 556 size_t b_size = MIN(1024U, len); 557 uint8_t *b = malloc(b_size); 558 559 if (!b) 560 return TEE_ERROR_OUT_OF_MEMORY; 561 562 dst = NULL; 563 while (num_bytes < len) { 564 size_t n = MIN(b_size, len - num_bytes); 565 566 res = tee_ta_decrypt_update(handle->enc_ctx, b, 567 src + num_bytes, n); 568 if (res) 569 break; 570 num_bytes += n; 571 572 res = crypto_hash_update(handle->hash_ctx, b, 573 n); 574 if (res) 575 break; 576 } 577 578 free(b); 579 if (res != TEE_SUCCESS) 580 return TEE_ERROR_SECURITY; 581 } 582 } else if (data) { 583 dst = data; /* Hash secure buffer (shm might be modified) */ 584 memcpy(dst, src, len); 585 } 586 587 if (dst) { 588 res = crypto_hash_update(handle->hash_ctx, dst, len); 589 if (res != TEE_SUCCESS) 590 return TEE_ERROR_SECURITY; 591 } 592 593 handle->offs = next_offs; 594 if (handle->offs == handle->nw_ta_size) { 595 if (handle->shdr->img_type == SHDR_ENCRYPTED_TA) { 596 /* 597 * Last read: time to finalize authenticated 598 * decryption. 599 */ 600 res = tee_ta_decrypt_final(handle->enc_ctx, 601 handle->ehdr, NULL, NULL, 0); 602 if (res != TEE_SUCCESS) 603 return TEE_ERROR_SECURITY; 604 } 605 /* 606 * Last read: time to check if our digest matches the expected 607 * one (from the signed header) 608 */ 609 res = check_digest(handle); 610 if (res != TEE_SUCCESS) 611 return res; 612 613 if (handle->bs_hdr) 614 res = check_update_version(ta_ver_db, 615 handle->bs_hdr->uuid, 616 handle->bs_hdr->ta_version); 617 } 618 return res; 619 } 620 621 static void ree_fs_ta_close(struct ts_store_handle *h) 622 { 623 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 624 625 if (!handle) 626 return; 627 thread_rpc_free_payload(handle->mobj); 628 crypto_hash_free_ctx(handle->hash_ctx); 629 free(handle->shdr); 630 free(handle->ehdr); 631 free(handle->bs_hdr); 632 free(handle); 633 } 634 635 #ifndef CFG_REE_FS_TA_BUFFERED 636 REGISTER_TA_STORE(9) = { 637 .description = "REE", 638 .open = ree_fs_ta_open, 639 .get_size = ree_fs_ta_get_size, 640 .get_tag = ree_fs_ta_get_tag, 641 .read = ree_fs_ta_read, 642 .close = ree_fs_ta_close, 643 }; 644 #endif 645 646 #ifdef CFG_REE_FS_TA_BUFFERED 647 648 /* 649 * This is a wrapper around the "REE FS" TA store. 650 * The whole TA/library is read into a temporary buffer during .open(). This 651 * allows the binary to be authenticated before any data is read and processed 652 * by the upper layer (ELF loader). 653 */ 654 655 struct buf_ree_fs_ta_handle { 656 struct ts_store_handle *h; /* Note: a REE FS TA store handle */ 657 size_t ta_size; 658 tee_mm_entry_t *mm; 659 uint8_t *buf; 660 size_t offs; 661 uint8_t *tag; 662 unsigned int tag_len; 663 }; 664 665 static TEE_Result buf_ta_open(const TEE_UUID *uuid, 666 struct ts_store_handle **h) 667 { 668 struct buf_ree_fs_ta_handle *handle = NULL; 669 struct ftmn ftmn = { }; 670 TEE_Result res = TEE_SUCCESS; 671 672 handle = calloc(1, sizeof(*handle)); 673 if (!handle) 674 return TEE_ERROR_OUT_OF_MEMORY; 675 FTMN_PUSH_LINKED_CALL(&ftmn, FTMN_FUNC_HASH("shdr_verify_signature")); 676 res = ree_fs_ta_open(uuid, &handle->h); 677 if (!res) 678 FTMN_SET_CHECK_RES_FROM_CALL(&ftmn, FTMN_INCR0, res); 679 FTMN_POP_LINKED_CALL(&ftmn); 680 if (res) 681 goto err_free_handle; 682 ftmn_checkpoint(&ftmn, FTMN_INCR1); 683 684 res = ree_fs_ta_get_size(handle->h, &handle->ta_size); 685 if (res) 686 goto err; 687 688 res = ree_fs_ta_get_tag(handle->h, NULL, &handle->tag_len); 689 if (res != TEE_ERROR_SHORT_BUFFER) { 690 res = TEE_ERROR_GENERIC; 691 goto err; 692 } 693 handle->tag = malloc(handle->tag_len); 694 if (!handle->tag) { 695 res = TEE_ERROR_OUT_OF_MEMORY; 696 goto err; 697 } 698 res = ree_fs_ta_get_tag(handle->h, handle->tag, &handle->tag_len); 699 if (res) 700 goto err; 701 702 handle->mm = tee_mm_alloc(&tee_mm_sec_ddr, handle->ta_size); 703 if (!handle->mm) { 704 res = TEE_ERROR_OUT_OF_MEMORY; 705 goto err; 706 } 707 handle->buf = phys_to_virt(tee_mm_get_smem(handle->mm), 708 MEM_AREA_TA_RAM, handle->ta_size); 709 if (!handle->buf) { 710 res = TEE_ERROR_OUT_OF_MEMORY; 711 goto err; 712 } 713 714 FTMN_PUSH_LINKED_CALL(&ftmn, FTMN_FUNC_HASH("check_digest")); 715 res = ree_fs_ta_read(handle->h, handle->buf, handle->ta_size); 716 if (!res) 717 FTMN_SET_CHECK_RES_FROM_CALL(&ftmn, FTMN_INCR0, res); 718 FTMN_POP_LINKED_CALL(&ftmn); 719 if (res) 720 goto err; 721 ftmn_checkpoint(&ftmn, FTMN_INCR1); 722 723 *h = (struct ts_store_handle *)handle; 724 ree_fs_ta_close(handle->h); 725 return ftmn_return_res(&ftmn, FTMN_STEP_COUNT(2, 2), TEE_SUCCESS); 726 727 err: 728 ree_fs_ta_close(handle->h); 729 tee_mm_free(handle->mm); 730 free(handle->tag); 731 err_free_handle: 732 free(handle); 733 return res; 734 } 735 736 static TEE_Result buf_ta_get_size(const struct ts_store_handle *h, 737 size_t *size) 738 { 739 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 740 741 *size = handle->ta_size; 742 return TEE_SUCCESS; 743 } 744 745 static TEE_Result buf_ta_read(struct ts_store_handle *h, void *data, 746 size_t len) 747 { 748 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 749 uint8_t *src = handle->buf + handle->offs; 750 size_t next_offs = 0; 751 752 if (ADD_OVERFLOW(handle->offs, len, &next_offs) || 753 next_offs > handle->ta_size) 754 return TEE_ERROR_BAD_PARAMETERS; 755 756 if (data) 757 memcpy(data, src, len); 758 handle->offs = next_offs; 759 return TEE_SUCCESS; 760 } 761 762 static TEE_Result buf_ta_get_tag(const struct ts_store_handle *h, 763 uint8_t *tag, unsigned int *tag_len) 764 { 765 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 766 767 *tag_len = handle->tag_len; 768 if (!tag || *tag_len < handle->tag_len) 769 return TEE_ERROR_SHORT_BUFFER; 770 771 memcpy(tag, handle->tag, handle->tag_len); 772 773 return TEE_SUCCESS; 774 } 775 776 static void buf_ta_close(struct ts_store_handle *h) 777 { 778 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 779 780 if (!handle) 781 return; 782 tee_mm_free(handle->mm); 783 free(handle->tag); 784 free(handle); 785 } 786 787 REGISTER_TA_STORE(9) = { 788 .description = "REE [buffered]", 789 .open = buf_ta_open, 790 .get_size = buf_ta_get_size, 791 .get_tag = buf_ta_get_tag, 792 .read = buf_ta_read, 793 .close = buf_ta_close, 794 }; 795 796 #endif /* CFG_REE_FS_TA_BUFFERED */ 797