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 <initcall.h> 41 #include <kernel/thread.h> 42 #include <kernel/ts_store.h> 43 #include <mm/core_memprot.h> 44 #include <mm/tee_mm.h> 45 #include <mm/mobj.h> 46 #include <optee_rpc_cmd.h> 47 #include <signed_hdr.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <tee_api_defines_extensions.h> 51 #include <tee_api_types.h> 52 #include <tee/tee_pobj.h> 53 #include <tee/tee_svc_storage.h> 54 #include <tee/tee_ta_enc_manager.h> 55 #include <tee/uuid.h> 56 #include <utee_defines.h> 57 58 struct ree_fs_ta_handle { 59 struct shdr *nw_ta; /* Non-secure (shared memory) */ 60 size_t nw_ta_size; 61 struct mobj *mobj; 62 size_t offs; 63 struct shdr *shdr; /* Verified secure copy of @nw_ta's signed header */ 64 void *hash_ctx; 65 void *enc_ctx; 66 struct shdr_bootstrap_ta *bs_hdr; 67 struct shdr_encrypted_ta *ehdr; 68 }; 69 70 struct ta_ver_db_hdr { 71 uint32_t db_version; 72 uint32_t nb_entries; 73 }; 74 75 static const char ta_ver_db_obj_id[] = "ta_ver.db"; 76 static struct mutex ta_ver_db_mutex = MUTEX_INITIALIZER; 77 78 /* 79 * Load a TA via RPC with UUID defined by input param @uuid. The virtual 80 * address of the raw TA binary is received in out parameter @ta. 81 */ 82 static TEE_Result rpc_load(const TEE_UUID *uuid, struct shdr **ta, 83 size_t *ta_size, struct mobj **mobj) 84 { 85 TEE_Result res; 86 struct thread_param params[2]; 87 88 if (!uuid || !ta || !mobj || !ta_size) 89 return TEE_ERROR_BAD_PARAMETERS; 90 91 memset(params, 0, sizeof(params)); 92 params[0].attr = THREAD_PARAM_ATTR_VALUE_IN; 93 tee_uuid_to_octets((void *)¶ms[0].u.value, uuid); 94 params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT; 95 96 res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params); 97 if (res != TEE_SUCCESS) 98 return res; 99 100 *mobj = thread_rpc_alloc_payload(params[1].u.memref.size); 101 if (!*mobj) 102 return TEE_ERROR_OUT_OF_MEMORY; 103 104 if ((*mobj)->size < params[1].u.memref.size) { 105 res = TEE_ERROR_SHORT_BUFFER; 106 goto exit; 107 } 108 109 *ta = mobj_get_va(*mobj, 0); 110 /* We don't expect NULL as thread_rpc_alloc_payload() was successful */ 111 assert(*ta); 112 *ta_size = params[1].u.memref.size; 113 114 params[0].attr = THREAD_PARAM_ATTR_VALUE_IN; 115 tee_uuid_to_octets((void *)¶ms[0].u.value, uuid); 116 params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT; 117 params[1].u.memref.offs = 0; 118 params[1].u.memref.mobj = *mobj; 119 120 res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params); 121 exit: 122 if (res != TEE_SUCCESS) 123 thread_rpc_free_payload(*mobj); 124 125 return res; 126 } 127 128 static TEE_Result ree_fs_ta_open(const TEE_UUID *uuid, 129 struct ts_store_handle **h) 130 { 131 struct ree_fs_ta_handle *handle; 132 struct shdr *shdr = NULL; 133 struct mobj *mobj = NULL; 134 void *hash_ctx = NULL; 135 struct shdr *ta = NULL; 136 size_t ta_size = 0; 137 TEE_Result res; 138 size_t offs; 139 struct shdr_bootstrap_ta *bs_hdr = NULL; 140 struct shdr_encrypted_ta *ehdr = NULL; 141 142 handle = calloc(1, sizeof(*handle)); 143 if (!handle) 144 return TEE_ERROR_OUT_OF_MEMORY; 145 146 /* Request TA from tee-supplicant */ 147 res = rpc_load(uuid, &ta, &ta_size, &mobj); 148 if (res != TEE_SUCCESS) 149 goto error; 150 151 /* Make secure copy of signed header */ 152 shdr = shdr_alloc_and_copy(ta, ta_size); 153 if (!shdr) { 154 res = TEE_ERROR_SECURITY; 155 goto error_free_payload; 156 } 157 158 /* Validate header signature */ 159 res = shdr_verify_signature(shdr); 160 if (res != TEE_SUCCESS) 161 goto error_free_payload; 162 if (shdr->img_type != SHDR_TA && shdr->img_type != SHDR_BOOTSTRAP_TA && 163 shdr->img_type != SHDR_ENCRYPTED_TA) { 164 res = TEE_ERROR_SECURITY; 165 goto error_free_payload; 166 } 167 168 /* 169 * Initialize a hash context and run the algorithm over the signed 170 * header (less the final file hash and its signature of course) 171 */ 172 res = crypto_hash_alloc_ctx(&hash_ctx, 173 TEE_DIGEST_HASH_TO_ALGO(shdr->algo)); 174 if (res != TEE_SUCCESS) 175 goto error_free_payload; 176 res = crypto_hash_init(hash_ctx); 177 if (res != TEE_SUCCESS) 178 goto error_free_hash; 179 res = crypto_hash_update(hash_ctx, (uint8_t *)shdr, sizeof(*shdr)); 180 if (res != TEE_SUCCESS) 181 goto error_free_hash; 182 offs = SHDR_GET_SIZE(shdr); 183 184 if (shdr->img_type == SHDR_BOOTSTRAP_TA || 185 shdr->img_type == SHDR_ENCRYPTED_TA) { 186 TEE_UUID bs_uuid; 187 188 if (ta_size < SHDR_GET_SIZE(shdr) + sizeof(*bs_hdr)) { 189 res = TEE_ERROR_SECURITY; 190 goto error_free_hash; 191 } 192 193 bs_hdr = malloc(sizeof(*bs_hdr)); 194 if (!bs_hdr) { 195 res = TEE_ERROR_OUT_OF_MEMORY; 196 goto error_free_hash; 197 } 198 199 memcpy(bs_hdr, (uint8_t *)ta + offs, sizeof(*bs_hdr)); 200 201 /* 202 * There's a check later that the UUID embedded inside the 203 * ELF is matching, but since we now have easy access to 204 * the expected uuid of the TA we check it a bit earlier 205 * here. 206 */ 207 tee_uuid_from_octets(&bs_uuid, bs_hdr->uuid); 208 if (memcmp(&bs_uuid, uuid, sizeof(TEE_UUID))) { 209 res = TEE_ERROR_SECURITY; 210 goto error_free_hash; 211 } 212 213 res = crypto_hash_update(hash_ctx, (uint8_t *)bs_hdr, 214 sizeof(*bs_hdr)); 215 if (res != TEE_SUCCESS) 216 goto error_free_hash; 217 offs += sizeof(*bs_hdr); 218 handle->bs_hdr = bs_hdr; 219 } 220 221 if (shdr->img_type == SHDR_ENCRYPTED_TA) { 222 struct shdr_encrypted_ta img_ehdr; 223 224 if (ta_size < SHDR_GET_SIZE(shdr) + 225 sizeof(struct shdr_bootstrap_ta) + sizeof(img_ehdr)) { 226 res = TEE_ERROR_SECURITY; 227 goto error_free_hash; 228 } 229 230 memcpy(&img_ehdr, ((uint8_t *)ta + offs), sizeof(img_ehdr)); 231 232 ehdr = malloc(SHDR_ENC_GET_SIZE(&img_ehdr)); 233 if (!ehdr) { 234 res = TEE_ERROR_OUT_OF_MEMORY; 235 goto error_free_hash; 236 } 237 238 memcpy(ehdr, ((uint8_t *)ta + offs), 239 SHDR_ENC_GET_SIZE(&img_ehdr)); 240 241 res = crypto_hash_update(hash_ctx, (uint8_t *)ehdr, 242 SHDR_ENC_GET_SIZE(ehdr)); 243 if (res != TEE_SUCCESS) 244 goto error_free_hash; 245 246 res = tee_ta_decrypt_init(&handle->enc_ctx, ehdr, 247 shdr->img_size); 248 if (res != TEE_SUCCESS) 249 goto error_free_hash; 250 251 offs += SHDR_ENC_GET_SIZE(ehdr); 252 handle->ehdr = ehdr; 253 } 254 255 if (ta_size != offs + shdr->img_size) { 256 res = TEE_ERROR_SECURITY; 257 goto error_free_hash; 258 } 259 260 handle->nw_ta = ta; 261 handle->nw_ta_size = ta_size; 262 handle->offs = offs; 263 handle->hash_ctx = hash_ctx; 264 handle->shdr = shdr; 265 handle->mobj = mobj; 266 *h = (struct ts_store_handle *)handle; 267 return TEE_SUCCESS; 268 269 error_free_hash: 270 crypto_hash_free_ctx(hash_ctx); 271 error_free_payload: 272 thread_rpc_free_payload(mobj); 273 error: 274 free(ehdr); 275 free(bs_hdr); 276 shdr_free(shdr); 277 free(handle); 278 return res; 279 } 280 281 static TEE_Result ree_fs_ta_get_size(const struct ts_store_handle *h, 282 size_t *size) 283 { 284 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 285 286 *size = handle->shdr->img_size; 287 return TEE_SUCCESS; 288 } 289 290 static TEE_Result ree_fs_ta_get_tag(const struct ts_store_handle *h, 291 uint8_t *tag, unsigned int *tag_len) 292 { 293 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 294 295 if (!tag || *tag_len < handle->shdr->hash_size) { 296 *tag_len = handle->shdr->hash_size; 297 return TEE_ERROR_SHORT_BUFFER; 298 } 299 *tag_len = handle->shdr->hash_size; 300 301 memcpy(tag, SHDR_GET_HASH(handle->shdr), handle->shdr->hash_size); 302 303 return TEE_SUCCESS; 304 } 305 306 static TEE_Result check_digest(struct ree_fs_ta_handle *h) 307 { 308 void *digest = NULL; 309 TEE_Result res; 310 311 digest = malloc(h->shdr->hash_size); 312 if (!digest) 313 return TEE_ERROR_OUT_OF_MEMORY; 314 res = crypto_hash_final(h->hash_ctx, digest, h->shdr->hash_size); 315 if (res != TEE_SUCCESS) { 316 res = TEE_ERROR_SECURITY; 317 goto out; 318 } 319 if (memcmp(digest, SHDR_GET_HASH(h->shdr), h->shdr->hash_size)) 320 res = TEE_ERROR_SECURITY; 321 out: 322 free(digest); 323 return res; 324 } 325 326 static TEE_Result check_update_version(struct shdr_bootstrap_ta *hdr) 327 { 328 struct shdr_bootstrap_ta hdr_entry = { }; 329 const struct tee_file_operations *ops = NULL; 330 struct tee_file_handle *fh = NULL; 331 TEE_Result res = TEE_SUCCESS; 332 bool entry_found = false; 333 size_t len = 0; 334 unsigned int i = 0; 335 struct ta_ver_db_hdr db_hdr = { }; 336 struct tee_pobj pobj = { 337 .obj_id = (void *)ta_ver_db_obj_id, 338 .obj_id_len = sizeof(ta_ver_db_obj_id) 339 }; 340 341 mutex_lock(&ta_ver_db_mutex); 342 ops = tee_svc_storage_file_ops(TEE_STORAGE_PRIVATE); 343 344 res = ops->open(&pobj, NULL, &fh); 345 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND) 346 goto out; 347 348 if (res == TEE_ERROR_ITEM_NOT_FOUND) { 349 res = ops->create(&pobj, false, NULL, 0, NULL, 0, NULL, 0, &fh); 350 if (res != TEE_SUCCESS) 351 goto out; 352 353 res = ops->write(fh, 0, &db_hdr, sizeof(db_hdr)); 354 if (res != TEE_SUCCESS) 355 goto out; 356 } else { 357 len = sizeof(db_hdr); 358 359 res = ops->read(fh, 0, &db_hdr, &len); 360 if (res != TEE_SUCCESS) { 361 goto out; 362 } else if (len != sizeof(db_hdr)) { 363 res = TEE_ERROR_BAD_STATE; 364 goto out; 365 } 366 } 367 368 for (i = 0; i < db_hdr.nb_entries; i++) { 369 len = sizeof(hdr_entry); 370 371 res = ops->read(fh, sizeof(db_hdr) + (i * len), &hdr_entry, 372 &len); 373 if (res != TEE_SUCCESS) { 374 goto out; 375 } else if (len != sizeof(hdr_entry)) { 376 res = TEE_ERROR_BAD_STATE; 377 goto out; 378 } 379 380 if (!memcmp(hdr->uuid, hdr_entry.uuid, sizeof(TEE_UUID))) { 381 entry_found = true; 382 break; 383 } 384 } 385 386 if (entry_found) { 387 if (hdr_entry.ta_version > hdr->ta_version) { 388 res = TEE_ERROR_ACCESS_CONFLICT; 389 goto out; 390 } else if (hdr_entry.ta_version < hdr->ta_version) { 391 len = sizeof(*hdr); 392 res = ops->write(fh, sizeof(db_hdr) + (i * len), hdr, 393 len); 394 if (res != TEE_SUCCESS) 395 goto out; 396 } 397 } else { 398 len = sizeof(*hdr); 399 res = ops->write(fh, sizeof(db_hdr) + (db_hdr.nb_entries * len), 400 hdr, len); 401 if (res != TEE_SUCCESS) 402 goto out; 403 404 db_hdr.nb_entries++; 405 res = ops->write(fh, 0, &db_hdr, sizeof(db_hdr)); 406 if (res != TEE_SUCCESS) 407 goto out; 408 } 409 410 out: 411 ops->close(&fh); 412 mutex_unlock(&ta_ver_db_mutex); 413 return res; 414 } 415 416 static TEE_Result ree_fs_ta_read(struct ts_store_handle *h, void *data, 417 size_t len) 418 { 419 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 420 421 uint8_t *src = (uint8_t *)handle->nw_ta + handle->offs; 422 size_t next_offs = 0; 423 uint8_t *dst = src; 424 TEE_Result res = TEE_SUCCESS; 425 426 if (ADD_OVERFLOW(handle->offs, len, &next_offs) || 427 next_offs > handle->nw_ta_size) 428 return TEE_ERROR_BAD_PARAMETERS; 429 430 if (handle->shdr->img_type == SHDR_ENCRYPTED_TA) { 431 if (data) { 432 dst = data; /* Hash secure buffer */ 433 res = tee_ta_decrypt_update(handle->enc_ctx, dst, src, 434 len); 435 if (res != TEE_SUCCESS) 436 return TEE_ERROR_SECURITY; 437 } else { 438 size_t num_bytes = 0; 439 size_t b_size = MIN(1024U, len); 440 uint8_t *b = malloc(b_size); 441 442 if (!b) 443 return TEE_ERROR_OUT_OF_MEMORY; 444 445 dst = NULL; 446 while (num_bytes < len) { 447 size_t n = MIN(b_size, len - num_bytes); 448 449 res = tee_ta_decrypt_update(handle->enc_ctx, b, 450 src + num_bytes, n); 451 if (res) 452 break; 453 num_bytes += n; 454 455 res = crypto_hash_update(handle->hash_ctx, b, 456 n); 457 if (res) 458 break; 459 } 460 461 free(b); 462 if (res != TEE_SUCCESS) 463 return TEE_ERROR_SECURITY; 464 } 465 } else if (data) { 466 dst = data; /* Hash secure buffer (shm might be modified) */ 467 memcpy(dst, src, len); 468 } 469 470 if (dst) { 471 res = crypto_hash_update(handle->hash_ctx, dst, len); 472 if (res != TEE_SUCCESS) 473 return TEE_ERROR_SECURITY; 474 } 475 476 handle->offs = next_offs; 477 if (handle->offs == handle->nw_ta_size) { 478 if (handle->shdr->img_type == SHDR_ENCRYPTED_TA) { 479 /* 480 * Last read: time to finalize authenticated 481 * decryption. 482 */ 483 res = tee_ta_decrypt_final(handle->enc_ctx, 484 handle->ehdr, NULL, NULL, 0); 485 if (res != TEE_SUCCESS) 486 return TEE_ERROR_SECURITY; 487 } 488 /* 489 * Last read: time to check if our digest matches the expected 490 * one (from the signed header) 491 */ 492 res = check_digest(handle); 493 if (res != TEE_SUCCESS) 494 return res; 495 496 if (handle->bs_hdr) 497 res = check_update_version(handle->bs_hdr); 498 } 499 return res; 500 } 501 502 static void ree_fs_ta_close(struct ts_store_handle *h) 503 { 504 struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h; 505 506 if (!handle) 507 return; 508 thread_rpc_free_payload(handle->mobj); 509 crypto_hash_free_ctx(handle->hash_ctx); 510 free(handle->shdr); 511 free(handle->ehdr); 512 free(handle->bs_hdr); 513 free(handle); 514 } 515 516 #ifndef CFG_REE_FS_TA_BUFFERED 517 REGISTER_TA_STORE(9) = { 518 .description = "REE", 519 .open = ree_fs_ta_open, 520 .get_size = ree_fs_ta_get_size, 521 .get_tag = ree_fs_ta_get_tag, 522 .read = ree_fs_ta_read, 523 .close = ree_fs_ta_close, 524 }; 525 #endif 526 527 #ifdef CFG_REE_FS_TA_BUFFERED 528 529 /* 530 * This is a wrapper around the "REE FS" TA store. 531 * The whole TA/library is read into a temporary buffer during .open(). This 532 * allows the binary to be authenticated before any data is read and processed 533 * by the upper layer (ELF loader). 534 */ 535 536 struct buf_ree_fs_ta_handle { 537 struct ts_store_handle *h; /* Note: a REE FS TA store handle */ 538 size_t ta_size; 539 tee_mm_entry_t *mm; 540 uint8_t *buf; 541 size_t offs; 542 uint8_t *tag; 543 unsigned int tag_len; 544 }; 545 546 static TEE_Result buf_ta_open(const TEE_UUID *uuid, 547 struct ts_store_handle **h) 548 { 549 struct buf_ree_fs_ta_handle *handle = NULL; 550 TEE_Result res = TEE_SUCCESS; 551 552 handle = calloc(1, sizeof(*handle)); 553 if (!handle) 554 return TEE_ERROR_OUT_OF_MEMORY; 555 res = ree_fs_ta_open(uuid, &handle->h); 556 if (res) 557 goto err2; 558 res = ree_fs_ta_get_size(handle->h, &handle->ta_size); 559 if (res) 560 goto err; 561 562 res = ree_fs_ta_get_tag(handle->h, NULL, &handle->tag_len); 563 if (res != TEE_ERROR_SHORT_BUFFER) { 564 res = TEE_ERROR_GENERIC; 565 goto err; 566 } 567 handle->tag = malloc(handle->tag_len); 568 if (!handle->tag) { 569 res = TEE_ERROR_OUT_OF_MEMORY; 570 goto err; 571 } 572 res = ree_fs_ta_get_tag(handle->h, handle->tag, &handle->tag_len); 573 if (res) 574 goto err; 575 576 handle->mm = tee_mm_alloc(&tee_mm_sec_ddr, handle->ta_size); 577 if (!handle->mm) { 578 res = TEE_ERROR_OUT_OF_MEMORY; 579 goto err; 580 } 581 handle->buf = phys_to_virt(tee_mm_get_smem(handle->mm), 582 MEM_AREA_TA_RAM); 583 if (!handle->buf) { 584 res = TEE_ERROR_OUT_OF_MEMORY; 585 goto err; 586 } 587 res = ree_fs_ta_read(handle->h, handle->buf, handle->ta_size); 588 if (res) 589 goto err; 590 *h = (struct ts_store_handle *)handle; 591 err: 592 ree_fs_ta_close(handle->h); 593 err2: 594 if (res) { 595 tee_mm_free(handle->mm); 596 free(handle->tag); 597 free(handle); 598 } 599 return res; 600 } 601 602 static TEE_Result buf_ta_get_size(const struct ts_store_handle *h, 603 size_t *size) 604 { 605 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 606 607 *size = handle->ta_size; 608 return TEE_SUCCESS; 609 } 610 611 static TEE_Result buf_ta_read(struct ts_store_handle *h, void *data, 612 size_t len) 613 { 614 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 615 uint8_t *src = handle->buf + handle->offs; 616 size_t next_offs = 0; 617 618 if (ADD_OVERFLOW(handle->offs, len, &next_offs) || 619 next_offs > handle->ta_size) 620 return TEE_ERROR_BAD_PARAMETERS; 621 622 if (data) 623 memcpy(data, src, len); 624 handle->offs = next_offs; 625 return TEE_SUCCESS; 626 } 627 628 static TEE_Result buf_ta_get_tag(const struct ts_store_handle *h, 629 uint8_t *tag, unsigned int *tag_len) 630 { 631 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 632 633 *tag_len = handle->tag_len; 634 if (!tag || *tag_len < handle->tag_len) 635 return TEE_ERROR_SHORT_BUFFER; 636 637 memcpy(tag, handle->tag, handle->tag_len); 638 639 return TEE_SUCCESS; 640 } 641 642 static void buf_ta_close(struct ts_store_handle *h) 643 { 644 struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h; 645 646 if (!handle) 647 return; 648 tee_mm_free(handle->mm); 649 free(handle->tag); 650 free(handle); 651 } 652 653 REGISTER_TA_STORE(9) = { 654 .description = "REE [buffered]", 655 .open = buf_ta_open, 656 .get_size = buf_ta_get_size, 657 .get_tag = buf_ta_get_tag, 658 .read = buf_ta_read, 659 .close = buf_ta_close, 660 }; 661 662 #endif /* CFG_REE_FS_TA_BUFFERED */ 663